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.
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 have an issue and this is rather my last resort before I give up, Im rather a noob with Perl and I've about reached the end of the internet searching for a solution.
***I do not have permission to install anything so it must be native to Perl5
I have a script and I need to calculate the total runtime of the script, and output the result in 00.00 "minutes.seconds" stored in a variable.
Here's a failed attempt:
#!/usr/bin/perl
use Time::Piece;
use POSIX qw(strftime);
my $start = localtime->strftime($unixtime);
sleep(10);
my $end = localtime->strftime($unixtime);
my $diff = $end - $start;
my $runtime = printf("%M.%S", $diff);
print $runtime;
I definitely have played with this a bit and was able to get "10" seconds as a result, however that is not the proper format. If the script ran for say 10 seconds, the output should be "00.10".
If the script ran for say 1 minute and 55 seconds the output should be "01.55".
Is there any way this can be done?
I searched on this and found 1 article however not even close... REF: perl different time format output
No need for Time::Piece!
my $start = time;
sleep(10);
my $end = time;
my $diff = $end - $start;
my $runtime = sprintf '%d:%02d', int($diff / 60), $diff % 60;
print "$runtime\n";
This should do the trick:
#!/usr/bin/perl
use Time::Piece;
my $start = localtime;
sleep(10);
my $end = localtime;
my $diff = $end - $start;
my $minutes = int $diff->minutes;
my $seconds = $diff->seconds % 60;
my $output = sprintf '%02d.%02d', $minutes, $seconds;
print "$output\n";
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";
I am attempting to write a Perl script that parses a log where on each line the second value is the date. The script takes in three arguments: the input log file, the start time, and the end time. The start and end time are used to parse out a certain value on each line that that falls between those two times. But to properly run this I am converting the start and end time to epoch time. The problem I am having is that to convert the loops 'i' value back to normal time to compare against the log file. After running localtime($i) I print the value and only see a reference printed not the actual value.
Here is the script I have so far (it is a work in progress):
#!/usr/bin/perl
use strict;
use warnings;
use Time::Local;
use Time::localtime;
use File::stat;
my $sec = 0;
my $min = 0;
my $hour = 0;
my $mday = 0;
my $mon = 0;
my $year = 0;
my $wday = 0;
my $yday = 0;
my $isdst = 0;
##########################
# Get the engine log date
##########################
my $date = `grep -m 1 'Metric' "$ARGV[0]" | awk '{print \$2}'`;
($year,$mon,$mday) = split('-', $date);
$mon--;
#########################################
# Calculate the start and end epoch time
#########################################
($hour,$min,$sec) = split(':', $ARGV[1]);
my $startTime = timelocal($sec,$min,$hour,$mday,$mon,$year);
($hour,$min,$sec) = split(':', $ARGV[2]);
my $endTime = timelocal($sec,$min,$hour,$mday,$mon,$year);
my $theTime = 0;
for (my $i = $startTime; $i <= $endTime + 29; $i++) {
#print "$startTime $i \n";
$theTime = localtime($i);
#my $DBInstance0 = `grep "$hour:$min:$sec" "$ARGV[0]"`;# | grep 'DBInstance-0' | awk '{print \$9}'`;
#print "$DBInstance0\n";
print "$theTime\n";
}
print "$startTime $endTime \n";
The output looks like:
Time::tm=ARRAY(0x8cbbd40)
Time::tm=ARRAY(0x8cbc1a0)
Time::tm=ARRAY(0x8cbbe80)
Time::tm=ARRAY(0x8cbc190)
Time::tm=ARRAY(0x8bbb170)
Time::tm=ARRAY(0x8cbc180)
Time::tm=ARRAY(0x8cbbf30)
Time::tm=ARRAY(0x8cbc170)
Time::tm=ARRAY(0x8cbc210)
Time::tm=ARRAY(0x8cbc160)
1275760356 1275760773
I only have access to the core Perl modules and am unable to install any others.
You can use ctime, depending on your definition of "Normal time":
Example code:
use Time::Local;
use Time::localtime;
my $time=timelocal(1,2,3,24,6,2010);
print "$time\n";
$theTime = ctime($time);
print "$theTime\n";
Result:
1279954921
Sat Jul 24 03:02:01 2010
Also, you don't need to use Time::Localtime (which is why you get Time::tm instead of a standard array/string from Perl's internal localtime):
use Time::Local;
my $time=timelocal(1,2,3,24,6,2010);
print "$time\n";
$theTime = localtime($time);
print "$theTime\n";
1279954921
Sat Jul 24 03:02:01 2010
Don't forget to subtract 1900 from the year!
Remember that in scalar context, localtime and gmtime returns a ctime-formatted string, so you could use it as in the following. If that's unsuitable, you might want to use strftime from the POSIX module.
#! /usr/bin/perl
use warnings;
use strict;
use Time::Local;
my $start = "01:02:03";
my $end = "01:02:05";
my $date = "2010-02-10";
my($year,$mon,$mday) = split /-/, $date;
$mon--;
$year -= 1900;
my($startTime,$endTime) =
map { my($hour,$min,$sec) = split /:/;
timelocal $sec,$min,$hour,$mday,$mon,$year }
$start, $end;
for (my $i = $startTime; $i <= $endTime + 29; $i++) {
print scalar localtime($i), "\n";
}
print "$startTime $endTime \n";
Tail of the output:
Wed Feb 10 01:02:26 2010
Wed Feb 10 01:02:27 2010
Wed Feb 10 01:02:28 2010
Wed Feb 10 01:02:29 2010
Wed Feb 10 01:02:30 2010
Wed Feb 10 01:02:31 2010
Wed Feb 10 01:02:32 2010
Wed Feb 10 01:02:33 2010
Wed Feb 10 01:02:34 2010
1265785323 1265785325