Perlish – Dates and Time
Introduction
Anyone who frequently writes utility scripts will eventually run into having to deal with Dates and Time. The type of tasks, though, can vary: sometimes you have to format a date, convert a date, add or subtract time to a date, or find a date. This article covers various ways of having to deal with Dates and Time in Perl.
Table of Contents
Core Date Tools
To start off with, here are some basic ways to deal with dates and time in Perl without the need for external modules. Here’s a basic script:
#!/usr/bin/env perl use strict; use warnings; use 5.010; # print formatted time say scalar localtime;
Running the above script will simply print:
$ perl time.pl Thu Mar 31 16:38:03 2011
How about dissecting the current date/time:
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $dst) = localtime();
It’s important to note that $mon (for month) is zero-based and $year needs 1900 added to it. So if you want to print 3/31/2011, you need to do:
$mon += 1; $year += 1900; say "$mon/$mday/$year";
Dealing with epoch-based time is a frequent occurrence on *nix-based systems:
# get epoch time my $time = time; # get yesterday $time -= 86400; # get different parts of specified time ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $dst) = localtime($time);
The above code gets the current time in epoch-based seconds, subtracts 1 day from it (60 seconds * 60 minutes * 24 hours) and then retrieves the different parts using the localtime function.
You can easily format a date however you want with the POSIX module and the strftime function:
use POSIX qw/ strftime /;
say "Yesterday was ", strftime("%A, %B %dth, %Y", localtime($time));
This prints:
$ perl time.pl Yesterday was Wednesday, March 30th, 2011
Date::Manip
Sometimes you need to do more advanced date calculations. I like Date::Manip for these tasks.
For example, here’s how to parse a date:
use Date::Manip::Date;
my $date = new Date::Manip::Date;
$date->parse('2011-03-31 12:47:33');
say $date->printf("%F");
The above prints:
$ perl time.pl Thursday, March 31, 2011
Date::Manip supports a huge array of formats, the above is just a simple example.
If you wanted to find how many days are between two dates, Date::Manip can do that:
my $d1 = new Date::Manip::Date;
my $d2 = new Date::Manip::Date;
$d1->parse('2001-01-01');
$d2->parse('epoch ' . time); # Use keyword 'epoch' for epoch-based time
$delta = $d1->calc($d2, 'approx');
printf("[%s] minus [%s] is [%s] days\n", $d1->printf("%F"), $d2->printf("%F"), $delta->printf("%dyd"));
This prints:
$ perl time.pl [Monday, January 01, 2001] minus [Thursday, March 31, 2011] is [3743.29875] days
DateTime
As Perl has a huge collection of Date and Time modules, DateTime was created to standardize on a set of functions and way to use them. One thing I do like about Date::Manip is that I only have to install the one module to have access to a wide array of Date and Time utilities. DateTime is a little different, and I can understand the need for that, too.
In order to run the following examples, three separate modules needed installed:
DateTimeDateTime::Format::StrptimeDateTime::Format::HTTP
This example parses and reformats a simple date:
use DateTime;
use DateTime::Format::Strptime;
my $parser = DateTime::Format::Strptime->new( pattern => '%Y-%m-%d' );
my $dt1 = $parser->parse_datetime('2001-01-02');
say $dt1->mdy('/');
This prints:
$ perl time.pl 01/02/2001
If you don’t want to supply your own date format to be parsed, DateParse::Format::HTTP should be able to parse it for you:
use DateTime;
use DateTime::Format::HTTP;
my $dt2 = DateTime::Format::HTTP->parse_datetime('2001-01-02');
say $dt2->mdy('/');
This prints the same result.
This example gets the current time as it is in Helsinki and then adds 17 days to it:
my $dt3 = DateTime->now(time_zone => 'Europe/Helsinki'); say $dt3->datetime; $dt3->add( days => 17 ); say $dt3->datetime;
The output is:
$ perl time.pl 2011-04-01T01:38:03 2011-04-18T01:38:03
This final example subtracts 5 months from the current epoch time and then prints the resulting year:
my $dt4 = DateTime->from_epoch( epoch => time ); $dt4->subtract( months => 5 ); say $dt4->year;
The output is:
$ perl time.pl 2010
Conclusion
This article covered only a few of the different types of Date and Time manipulations a systems administrator is likely to run into. As you run into different tasks, keep these modules in mind — they’re able to do a lot more than what is described above.

Add A Comment