Main Content

Time conversions in Perl

Archive - Originally posted on "The Horse's Mouth" - 2005-10-02 13:28:28 - Graham Ellis

Time isn't the easiest unit on which to do arithmetic, and dates expressed as a human-readable string are quite tricky to sort. Just imagine trying to write a program to work out whether 9 p.m. Pacific time on 28th Feb was before or after 3 a.m. in the UK on 1st March. And did you realise that, sorted alphabetically, the week starts on Friday and ends on Wednesday in England ... and it starts on Sunday and ends on Friday in France.

In Perl, all is neatly and elegantly solved for you ... you simply work in seconds from 1st January 1970, and use
localtime to convert from seconds into hour, minute, second, day, month, year
timelocal to convert the other way (from 6 values into a single number of seconds)

In order to use localtime, you need to use the Time::Local module which is supplied as standard with Perl anyway, although localtime is always available without pulling any extra module in.

gmtime and timegm provide Greenwich Mean Time convertors rather than convertors for your local time zone, and localtime and gmtime in a scalar context will give you a string rather than a list of numbers - so that makes output formatting very easy.

A final piece in the puzzle ... if you stat a file, the list you get back includes the times that the file was accessed, modified and changed each in seconds from 1.1.1970 - giving use an easy way to compare file stamps, or file ages versus some other timed happening.

Like to see an example?


use Time::Local;

# get the current time (seconds from 1.1.1970)

$now = time();

# in LIST context, localtime returns a list of each part of the time
# second, minute, hour, day, month, year, weekday, yearday, dst

# in SCALAR context, localtime returns string

@lpart = localtime($now);
$spart = localtime($now);
print "$spart ... @lpart ...\n";

# Work out the timestamp for a year ago ...

$lpart[5]--;
$past = timelocal(@lpart);

# and see if a file is over a year old ...

($finfo) = (stat("/etc/hosts"))[9];
($finfo < $past) ?
print "File is over a year old\n":
print "File is recent\n";