I'm working on a Perl program at work and stuck on (what I think is) a trivial problem. I simply need to build a string in the format '06/13/2012' (always 10 characters, so 0's for numbers less than 10).
Here's what I have so far:
use Time::localtime;
$tm=localtime;
my ($day,$month,$year)=($tm->mday,$tm->month,$tm->year);
You can do it fast, only using one POSIX function. If you have bunch of tasks with dates, see the module DateTime.
use POSIX qw(strftime);
my $date = strftime "%m/%d/%Y", localtime;
print $date;
You can use Time::Piece, which shouldn't need installing as it is a core module and has been distributed with Perl 5 since version 10.
use Time::Piece;
my $date = localtime->strftime('%m/%d/%Y');
print $date;
output
06/13/2012
Update
You may prefer to use the dmy method, which takes a single parameter which is the separator to be used between the fields of the result, and avoids having to specify a full date/time format
my $date = localtime->dmy('/');
This produces an identical result to that of my original solution
use DateTime qw();
DateTime->now->strftime('%m/%d/%Y')
expression returns 06/13/2012
If you like doing things the hard way:
my (undef,undef,undef,$mday,$mon,$year) = localtime;
$year = $year+1900;
$mon += 1;
if (length($mon) == 1) {$mon = "0$mon";}
if (length($mday) == 1) {$mday = "0$mday";}
my $today = "$mon/$mday/$year";
use Time::Piece;
...
my $t = localtime;
print $t->mdy("/");# 02/29/2000
Perl Code for Unix systems:
# Capture date from shell
my $current_date = `date +"%m/%d/%Y"`;
# Remove newline character
$current_date = substr($current_date,0,-1);
print $current_date, "\n";
Formating numbers with leading zero is done easily with "sprintf", a built-in function in perl (documentation with: perldoc perlfunc)
use strict;
use warnings;
use Date::Calc qw();
my ($y, $m, $d) = Date::Calc::Today();
my $ddmmyyyy = sprintf '%02d.%02d.%d', $d, $m, $y;
print $ddmmyyyy . "\n";
This gives you:
14.05.2014
Related
I want to compare both date and time check if the timestamp from the file I'm going to open will have equal or greater date and time as if the my timestamp which looks like this:
$Date = "20170608";
$Time = "105006";
My main problem is how to do it efficiently possibly without adding perl libraries and how to check it when there's going to be situation of date switching and the hour will be for example 23:59:44
Time::Piece is core in perl, and supports 'strptime'.
#!/usr/bin/env perl
use strict;
use warnings;
use Time::Piece;
my $Date = "20170608";
my $Time = "10506";
my $ts = Time::Piece->strptime( "$Date $Time", "%Y%m%d %H%M%S" );
print $ts, "\n";
print "Delta:", $ts->epoch - time(), "\n";
Was unclear on what time that $Time represented - strptime converts it to 10:50:06, but I'm guessing it might be intended to be 01:05:06?
If so, then zero pad.
$Time = sprintf ( "%06d", $Time );
To read the timestamp from the file metadata, then you need stat:
my $mtime = (stat $filename)[9];
I have an ISO 8601 time stored in a variable and I have some number of hours stored in another variable like this:
my $current_time = shift; #looks like: 2015-07-01T15:38:08Z
my $hours = shift; # looks like: 12
My goal is to add the hours to the current time, but there doesn't seem to be any built in Perl function to do it. In Powershell, you can do something like this:
$currentTime = $currentTime .AddHours($hours)
Is there an easy way to do this in Perl?
That specific ISO 8601 profile is also known as RFC3339.
use DateTime::Format::RFC3339;
my $dt = DateTime::Format::RFC3339->parse_datetime('2015-07-01T15:38:08Z');
$dt->add( hours => 1 );
print "$dt\n"; # 2015-07-01T16:38:08Z
If you want to accept arbitrary ISO 8601 profiles, you can use DateTime::Format::ISO8601.
use DateTime::Format::ISO8601;
my $dt = DateTime::Format::ISO8601->parse_datetime('2015-07-01T15:38:08Z');
$dt->set_time_zone('UTC'); # Convert to UTC ("Z") if it's not already.
$dt->add( hours => 1 );
print $dt->iso8601().'Z', "\n"; # 2015-07-01T16:38:08Z
I posted these alternatives because these modules are far less error-prone to use than Time::Piece.
You can also use Time::Moment. In the interest of full disclosure, I am the author of Time::Moment.
say Time::Moment->from_string('2015-07-01T15:38:08Z')
->plus_hours(1);
Output:
2015-07-01T16:38:08Z
Rather easy with Time::Piece:
#! /usr/bin/perl
use warnings;
use strict;
use Time::Piece;
use Time::Seconds;
my $current_time = '2015-07-01T15:38:08Z';
my $hours = 12;
my $format = '%Y-%m-%dT%H:%M:%SZ';
my $time = 'Time::Piece'->strptime($current_time, $format);
$time += $hours * ONE_HOUR;
print $time->strftime($format), "\n";
I would like to calculate the the current time and add 2 minutes to it and print the output in the following format. HH:MM . I searched online and came to know that there are lot of CPAN modules that can be used to implement this. But I'd like to do it without cpan modules.
$current_time = time();
$new_time = $current_time + (2*60); // adding two minutes
print( ' the time is ' . $ new_time ) ;
Output : the time is 1424906904
I searched online and came to know that we need to use POSIX perl interface to print the time in the appropriate format. However i'd like to know if there is a way to do this without using any cpan modules.
You can use localtime:
print scalar localtime($current_time);
Or you can run localtime's return values through POSIX::strftime (which is distributed with Perl as a core module):
use POSIX qw(strftime);
print strftime('%Y-%m-%d %H:%M:%S', localtime $current_time);
That's easy to do with localtime. Hours, minutes, and seconds are the 2nd, 1st, and 0th values returned. For example:
my ($sec, $min, $hours) = localtime(time()+120); # add 120 seconds
printf "%02d:%02d:%02d\n", $hours, $min, $sec;
Time::Piece and Time::Seconds have been included with all Perl installations since 2007.
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
use Time::Piece;
use Time::Seconds;
my $time = localtime;
$time += 2 * ONE_MINUTE;
say $time->strftime('%H:%M');
The code below only expresses the difference in months and days like so:
0:2:0:5:0:0:0
So it works, but I want to know the total number of days given that $ADDate can vary quite a bit. Hopefully this is simple, and I just completely missed how to do it.
#!/usr/bin/perl
use Date::Manip 6.42;
my $ADDate = "20131211000820.0Z";
my $var;
my #val;
my $diff;
calc_period($ADDate = "20131211000820.0Z");
sub calc_period
{
$ADDate =~ s/^([\d][\d][\d][\d])([\d][\d])([\d][\d])/$1-$2-$3/gs;
$ADDate =~ s/.........$//gs;
$today = ParseDate("today");
$beginning = ParseDate($ADDate);
$end = ParseDate($today);
$delta = DateCalc($beginning,$end,\$err,1);
#$delta =~ s/([\d+][:][\d+]):.*$/$1/gs;
print "$delta\n";
print "$ADDate\n";
}
I'm not familiar with Date::Manip, but I think another way to do this is to use Time::Piece to parse your string and do whatever you like with that since taking the difference of two Time::Piece object returns a Time::Seconds object.
The following example will show the difference of the current time and the hardcoded time and show it in days.
#!/usr/bin/perl
use strict;
use warnings;
use Time::Piece;
use Time::Seconds;
my $d = "20131211000820.0Z";
my $t = Time::Piece->strptime($d, "%Y%m%d%H%M%S.0Z");
my $now = Time::Piece->localtime();
my $diff = Time::Seconds->new($now - $t);
print $diff->days, "\n";
NigoroJr has already given you an answer. However, just as an FYI, the following is how I would clean up the code you originally provided:
#!/usr/bin/perl
use Date::Manip 6.42;
use strict;
use warnings;
calc_period("20131211000820.0Z");
sub calc_period {
my $date = shift;
$date =~ s/^(\d{4})(\d{2})(\d{2}).*/$1-$2-$3/;
my $beginning = ParseDate($date);
my $end = ParseDate("today");
my $delta = DateCalc($beginning, $end, \my $err, 1);
#$delta =~ s/([\d+][:][\d+]):.*$/$1/gs;
print "$delta\n";
print "$date\n";
}
Biggest differences being the proper use of a function and scoped variables, and a simplification of your regex.
I was unable to find a clean way to get Date::Manip to output a strict delta in days though, so the other module is the way to go.
I have a variable which contain value "20140720". I need to change it to the format "20/07".
My code is shown below.
#!/usr/bin/perl
use strict;
use warnings;
use Time::Piece;
my $date = '20140720';
my $date_format = Time::Piece->strptime($date, '%d/%m');
my $new_date = $date_format->strftime('%d/%m');
print $new_date;
I get following error during execution.
Error parsing time at /usr/lib/perl5/5.10.0/x86_64-linux-thread-multi/Time/Piece.pm line 470.
In this line — Time::Piece->strptime($date, '%d/%m'); — you specified the format that $date is currently in incorrectly. The second argument describes how the string should be parsed, not the format you want it to be in (which is what the following line is for).
Use '%Y%m%d' instead.
With a fixed string, you should use the pack/unpack function:
use strict;
use warnings;
my $date = '20140720';
my (undef, $m, $d) = unpack 'A4A2A2', $date;
print "$d/$m";
If you don't need further date processing, using a simple regular expression may be simpler:
use strict;
use warnings;
my $date = '20140720';
my $new_date = $date;
$new_date =~ s!\d{4}(\d{2})(\d{2})$!$2/$1!;
print $new_date, "\n";