How to process and manipulate dates and times in Perl.

Intr

Perl represents points in time as intervals, measuring seconds past a point in time called the Epoch. On linux and many other systems, the Epoch was 00:00 Jan 1, 1970 Greenwich Mean Time(GMT).

When we talk about dates and times, we often interchange two different concepts: points in time(date and time) and intervals between points in time(weeks, months, days, etc.) Epoch seconds represent intervals and points in the same units, so you can do basic arithmetic on them.

GMT and local time

Epoch seconds are always calculated in GMT, so when converting to or from distinct values, we must always consider whether the time represented is GMT or local.

Perl time function returns the number of seconds that have pasted since the Epoch.

Current Date & Time

To convert Epoch seconds into distinct values for days, months, years, hours, minutes, and seconds, use localtime and gmtime functions. 

$cat time.pl
#!/usr/bin/perl -T
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
my @t_time = localtime();
$datestring = localtime();
print "$sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst\n";
print "@t_time\n";
print "Local date and time $datestring\n";

$./time.pl
46,36,0,16,1,115,1,46,0
46 36 0 16 1 115 1 46 0
Local date and time Mon Feb 16 00:36:46 2015

In the example above, following is the 9-element list returned by localtime function while using in list context:

sec,     # seconds of minutes from 0 to 61
min,     # minutes of hour from 0 to 59
hour,    # hours of day from 0 to 24
mday,    # day of month from 1 to 31
mon,     # month of year from 0 to 11
year,    # year since 1900
wday,    # days since sunday
yday,    # days since January 1st
isdst    # hours of daylight savings time

Note: Perhaps you have noticed the format in $datestring is different with other two. The reason is that In scalar context, localtime and gmtiem return the date and time formatted as an ASCII string.

Finding todays' Date

Here are some different ways using loclatime function to get today's date

Use Standard Time::tm module

($day,$month,$year)=(localtime)[3,4,5];

Use Time::localtime module

use Time::localtime;
$t=localtime;
($day,$month,$year)=(localtime)[3,4,5];

Similarily, we can get current date as "YYYY-MM-DD"

($day,$month,$year)=(localtime)[3..5];  # note: there is a bit different in localtime
printf("The current date is %04d-%02d-%02d\n", $year,$month,$day);

Output:

The current date is 2015-02-16

Converting DMYHMS to Epoch Seconds

localtime converts an Epoch seconds value to distinct DMYHMS values; the timelocal subroutine from the standard Time:Local module converts distinct DMYHMS values to an Epoch seconds value.

Here is an example:

use Time::Local;
$time= timelocal($seconds,$mnutes,$hours,(localtime)[3,4,5]);

Adding to or Subtracting from a date

 As mentioned in Intr, Epoch seconds represent intervals and points in the same units, so you can do basic arithmetic on them:

$day  = $now + $interval;
$then = $now - $interval;

Example:

$tm=time();
sleep 10;
$tm_e=time();
$interval=$tm_e-$tm;
print "the interval: $interval sec\n";

Output:

the interval: 10 sec

You can do the difference of two dates easily in similary way.

Day in a week/month/year or week number

For day of the month, day of the week, and day of the year, they are easy to get from localtime() function.

($dayofmonth)=(localtime)[3];
($dayofweek)=(localtime)[6];
($dayofyear)=(localtime)[7];

Parsing DAtes and Times from Strings

If the date is alrady numeric, or in a easily parsed format, use a regular expression to extract individual day, month,and year values, and then use the standard time::Local module's timelocal and timegm functions to turn that into an Epoch seconds.

But, there is no date validation in that way. CPAN provides a functio ParseDate

Here is an example:

use Date;:Manip qw(ParseDate UnixDate);
$date = ParseDate($STRING);
if (!$date) {
#bad or invalid date
} else {
@values=Unixdae($date,@formats);
}