parse timestamp with millisecond in Perl - perl

Assuming I have a bunch of timestamps like "11/05/2010 16:27:26.003", how do parse them with millisecond in Perl.
Essentially, I would like to compare the timestamp to see if they are before or after a specific time.
I tried using Time::Local, but it seems that Time::Local is only capable to parse up second. And Time::HiRes, on the other hand, isn't really made for parsing text.
Thanks,
Derek

use DateTime::Format::Strptime;
my $Strp = new DateTime::Format::Strptime(
pattern => '%m/%d/%Y %H:%M:%S.%3N',
time_zone => '-0800',
);
my $now = DateTime->now;
my $dt = $Strp->parse_datetime('11/05/2010 23:16:42.003');
my $delta = $now - $dt;
print DateTime->compare( $now, $dt );
print $delta->millisecond;

You can use Time::Local and just add the .003 to it:
#!/usr/bin/perl
use strict;
use warnings;
use Time::Local;
my $timestring = "11/05/2010 16:27:26.003";
my ($mon, $d, $y, $h, $min, $s, $fraction) =
$timestring =~ m{(..)/(..)/(....) (..):(..):(..)([.]...)};
$y -= 1900;
$mon--;
my $seconds = timelocal($s, $min, $h, $d, $mon, $y) + $fraction;
print "seconds: $seconds\n";
print "milliseconds: ", $seconds * 1_000, "\n";

Related

Perl Date Comparison Query

I'm trying to output "not ok" if the date provided within an input file is greater than one day from "today" using Perl version 5.8.8.
Initializing with "./code.sh < test.txt" works fine, when test.txt contains the following data:
07/02/2020 08/02/2020
When I rehash the code below to try an use "today's date" as a variable, and only have one date within the input file I get the following error:
Use of uninitialized value in concatenation (.) or string at code.sh line 27, <> line 1
Working code (with two dates in the input file):
#!/usr/bin/perl
use strict;
use warnings;
use Time::Piece;
#my $date = localtime->strftime('%d/%m/%Y');
#print "$date";
my $format = '%d/%m/%Y';
while (<>) {
chomp;
my ($str1, $str2) = split;
# my ($date, $str2) = split;
# my $dt1 = Time::Piece->strptime($date, $format);
my $dt1 = Time::Piece->strptime($str1, $format);
my $dt2 = Time::Piece->strptime($str2, $format);
# print "$date / $str2 ";
print "$str1 / $str2 ";
if ($dt2->julian_day - $dt1->julian_day ==1) {
print "ok\n";
} else {
print "not ok\n";
}
}
Broken code (with one date within the input file):
#!/usr/bin/perl
use strict;
use warnings;
use Time::Piece;
my $date = localtime->strftime('%d/%m/%Y');
print "$date";
my $format = '%d/%m/%Y';
while (<>) {
chomp;
# my ($str1, $str2) = split;
my ($date, $str2) = split;
my $dt1 = Time::Piece->strptime($date, $format);
# my $dt1 = Time::Piece->strptime($str1, $format);
my $dt2 = Time::Piece->strptime($str2, $format);
print "$date / $str2 ";
# print "$str1 / $str2 ";
if ($dt2->julian_day - $dt1->julian_day ==1) {
print "ok\n";
} else {
print "not ok\n";
}
}
Not quite sure what I'm doing wrong...
Any help is appreciated
Please pay more attention when you type your code, your sample had a few miss-types
#!/usr/bin/perl
#
# vim: ai:ts=4:sw=4
#
use strict;
use warnings;
use feature 'say';
use Time::Piece;
my $format = '%d/%m/%Y';
my $date = localtime->strftime($format);
say "Today is: $date\n";
my #str_dates = <DATA>;
chomp(#str_dates);
my $date1 = Time::Piece->strptime($str_dates[0], $format);
my $date2 = Time::Piece->strptime($str_dates[1], $format);
my $days_diff = $date2->julian_day - $date1->julian_day;
my $msg = ($days_diff == 1) ? "ok" :"not ok";
say "$date2 :: $date1 => $msg";
say "$date2 :: $date1 = $days_diff day(s) apart";
__DATA__
07/02/2020
08/02/2020
Output
Today is: 07/02/2020
Sat Feb 8 00:00:00 2020 :: Fri Feb 7 00:00:00 2020 => ok
Sat Feb 8 00:00:00 2020 :: Fri Feb 7 00:00:00 2020 = 1 day(s) apart
NOTE: I would recommend if you use:
Windows OS
notepad++
Linux OS vim
vim better use with options: syntax on, ai,ts=4,sw=4

Quickly getting to local time YYYY-mm-dd HH:MM:SS in Perl?

i want to get local time and formatted as YYYY-mm-dd HH:MM:SS (say 2009-11-29 14:28:29).,
How can i get date in this format YYYY-mm-dd HH:MM:SS ?
i have try
my $format = "%4u-%02u-%02u %02u:%02u:%02u";
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
printf "$format\n", $year+1900, $mon+1, $mday, $hour, $min, $sec;
the print output is that i want ,but how to designed the output to a variable ??
Use sprintf instead of printf.
my ($sec, $min, $hour, $mday, $mon, $year) = localtime;
my $formatted = sprintf "%4u-%02u-%02u %02u:%02u:%02u",
$year+1900, $mon+1, $mday, $hour, $min, $sec;
But it's much simpler to use strftime.
use POSIX qw( strftime );
my $formatted = strftime("%Y-%m-%d %H:%M:%S", localtime);

Issue with Perl File::stat output, need to show date

I am having an issue with getting File::stat to output the last modified date of the file. This is my code so far:
#!/usr/bin/perl
use Time::localtime;
use File::stat;
use warnings;
use File::Find;
my $dirloc = 'E:\tmp\testdir';
sub find_txt {
my $F = $File::Find::name;
if ( ! -d $F && $F =~ /.tar|.exe|.zip/ ) {
my #result = $F;
foreach my $result (#result){
my $timestamp;
$timestamp = (stat("$result"))->[9] or die "No $_: $!";
print "$result : $timestamp\n";
}
}
}
find({wanted => \&find_txt}, $dirloc);
It is outputing something like this:
C:/tmp/testdir/foo/bar/test.tar : 1415305933
I need it to output instead (date format doesn't have to be what is listed, i just want to see the date):
C:/tmp/testdir/foo/bar/test.tar : 11/07/2014
I know that the output it is giving me is the time since epoch but I thought stat was supposed to give the date. Am I doing something wrong? Thanks!
edit: I have tried localtime, and i get: Time::tm=ARRAY(0x245b220), not sure what is happening there
You can use the localtime (Note: not Time::localtime) function to convert the timestamp into something useful
my $date = localtime $timestamp
which will make it a human readable string like Fri Nov 7 15:33:00 2014
Or you can use it in a list context to spit it into individual fields:
my($sec, $min, $hour, $day, $month, $year, $weekday, $yearOfDay, $isDST) = localtime $timestamp

Perl script - add days to Date to get new date

I am working on a perl script to add days to a date and display the newdate:
use Time::ParseDate;
use Time::CTime;
my $date = "02/01/2003";
my $numdays = 30;
my $time = parsedate($date);
# add $numdays worth of seconds
my $newtime = $time + ($numdays * 24 * 60 * 60);
my $newdate = strftime("%m/%d/%Y",localtime($newtime));
print "$newdate\n";
The output will be:
03/03/2003
Now how do I set the input for the date field to be yyyymmdd Ex: my $date = "20030102"
Also the output will need to be : 20030303
Thanks
You use Time::Piece + Time::Seconds (in core since Perl 5.10),
use Time::Piece ();
use Time::Seconds;
my $date = '20030102';
my $numdays = 60; # 30 doesn't get us to march
my $dt = Time::Piece->strptime( $date, '%Y%m%d');
$dt += ONE_DAY * $numdays;
print $dt->strftime('%Y%m%d');
You can use DateTime + DateTime::Format::Strptime:
#!/usr/bin/perl
use strict;
use DateTime;
use DateTime::Format::Strptime;
my $strp = DateTime::Format::Strptime->new(
pattern => '%m/%d/%Y'
);
# convert date to
my $date = '02/01/2003';
my $dt = $strp->parse_datetime($date);
printf "%s -> %s\n", $date, $dt->add(days => 30)->strftime("%d/%m/%Y");
OUTPUT
02/01/2003 -> 03/03/2003
Convert $date from the input format to the old format:
$date =~ s%(....)(..)(..)%$3/$2/$1%;
If the output format should not be %m/%d/%Y, then do not set it to it. You obviously need %Y%m%d.

Date::Calc - format the day and month

All I am trying to do here is if the day or month is a single digit, to add a zero in
the front of it. Right now it prints out the date as 201188, and I am looking for
20110808.
#!/usr/bin/perl
use Date::Calc qw(Add_Delta_Days);
my (undef, undef, undef, $day, $month, $year) = localtime();
$year +=1900;
$month +=1;
($year, $month, $day ) = Add_Delta_Days($year, $month, $day, -3)
if ($month =~ /\d{1}/){
s/$month/0$month/
}
if ($day =~/\d{1}/){
s/$day/0$day/
}
print $year,$month,$day;
If you're happy to use Date::Calc, why not use DateTime ?
use DateTime;
my $date = DateTime->now;
$date->subtract(days => 3);
print $date->ymd;
In fact you can reduce that to:
print DateTime->now->subtract(days => 3)->ymd
Use printf instead:
printf "%d-%02d-%02d", $year, $month, $day;
Gives output such as:
C:\perl>perl -we "printf qq(%d-%02d-%02d), 2011,5,4"
2011-05-04
C:\perl>perl -we "printf qq(%d-%02d-%02d), 2011,5,12"
2011-05-12
C:\perl>perl -we "printf qq(%d-%02d-%02d), 2011,22,12"
2011-22-12
if ($month < 10)
{
$month="0$month";
}
if ($day < 10)
{
$day="0$day";
}