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";
}
Related
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
I was just having a go at perl. I was trying to extract the date and time from a line in a text file that begins with
Date: 05/Feb/2017 21:30:00 PST - 06/Feb/2017 06:00:00 PST
I have managed to scavenge a script but Im trying to modify it so it extracts the above to
start date - 2017-02-05 21:30:00
end date - 2017-02-06 06:00:00
any help would be appreciated
#Is it a reg date
} elsif (!$start && $line[$i] =~ /^Date: (.+?) - (.+)$/i) {
$regstartdate = $1;
$regenddate = $2;
} elsif (!$start && $line[$i] =~ /^Date: (.+)$/i) {
#Monday 3rd July 2006
#Friday 30th June 2006 01:00 Hrs EST
$regstartdate = $1;
eval{
$start = &dateconv($regstartdate);
$end = $start;
1;
}
or do{
warn "Could not process start date: $regstartdate";
};
} elsif (!$start && $line[$i] =~ /^Time:\s*(\d+:\d+)[\s\-]+\s+(\d+:\d+)\s+[hH][rR][sS]\s+(\w+)$/i) {
$tz = $3;
$twestartdate = $regstartdate . " ".$1." Hrs ".$3;
$tweenddate = $regenddate . " ".$2." Hrs ".$3;
$start = &dateconv($regstartdate);
$end = &dateconv($regenddate);
} elsif (!$start && $line[$i] =~ /^Time:\s*(\d+:\d+)[\s*\-]+\s*(\d+:\d+)\s+(\w+)$/i) {
$tz = $3;
$regstartdate = $regstartdate . " ".$1." Hrs ".$3;
$regenddate = $regenddate . " ".$2." Hrs ".$3;
$start = &dateconv($regstartdate);
$end = &dateconv($regenddate);
#Is it a reg Time
} elsif (!$start && $line[$i] =~ /^Interruption Time: (\d+:\d+)[\s\-]+(\d+:\d+) (\w+)/i) {
$regstartdate = $regstartdate . " " . $1 . " Hrs " . $3;
$regenddate = $regenddate . " " . $2 . " Hrs " . $3;
$start = &dateconv($regstartdate);
$end = &dateconv($regenddate);
#Is is the start time ?
} elsif (!$start && $line[$i] =~ /^Duration:\s*START DATE (.*)/i) {
$start = &dateconv($1);
#Is it the end time ?
} elsif (!$end && $line[$i] =~ /^END DATE (.*)/i) {
my $endtime = $1;
$end = &dateconv($endtime);
$endtime =~ m/(\w{1,2}ST)/g;
$tz = $1;
Offering a solution using Time::Piece which I prefer - both because I like the interface, but also because it's core as of perl 5.9.5
#!/usr/bin/env perl
use strict;
use warnings;
use Time::Piece;
my $input_format = '%d/%b/%Y %H:%M:%S';
my $output_format = '%Y-%m-%d %H:%M:%S';
while (<DATA>) {
if ( my ( $start_str, $end_str ) = m/Date: (.*) PST - (.*) PST/ ) {
my $start = Time::Piece->strptime( $start_str, $input_format );
my $end = Time::Piece->strptime( $end_str, $input_format );
print "Start:\t", $start->strftime($output_format), "\n";
print "End: \t", $end ->strftime($output_format), "\n";
}
}
__DATA__
Date: 05/Feb/2017 21:30:00 PST - 06/Feb/2017 06:00:00 PST
The reason I like it is because the $start and $end in the above, are 'time objects' so you can do things like:
print $start -> epoch;
print "Elapsed time: ", $end - $start, "s\n";
If you use the DateTime module, parsing and formatting those date strings is trivial:
use strict;
use warnings;
use 5.010;
use DateTime;
use DateTime::Format::Strptime;
my $fmt = DateTime::Format::Strptime->new(pattern => '%d/%b/%Y %H:%M:%S');
my $line = 'Date: 05/Feb/2017 21:30:00 PST - 06/Feb/2017 06:00:00 PST';
$line =~ s/^Date: //;
my #dates = split(/\s*-\s*/, $line);
for my $date (#dates) {
my $dt = $fmt->parse_datetime($date);
say $dt->ymd . ' ' . $dt->hms;
}
Produces:
2017-02-05 21:30:00
2017-02-06 06:00:00
You can adjust the formatting as you see fit.
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);
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
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";