Time-Related Things I Never Want to See In A Perl Script Again

I got stuck debugging someone else’s Perl code today, and it was chock-full of the sorts of things that annoy the piss out of those of us who know better.

$date = `date +%Y-%m-%d`;

Perl isn’t the Bourne shell, you know. It’s a pretty complete programming language. It can tell time. Look up localtime, which returns the time either as a human-readable string, or as a conveniently parsed array with year, month, day, hour, minute, second, and everythng, depending on whether you call it as

$date = localtime;

or

@time_elements = localtime;

Or try gmtime if you want universal time.

If you want the time and/or date in a particular format, e.g., if you want a file with a date in the filename, like “logfile-2006-03-15”, there’s the POSIX module:

use POSIX;

$log_file_name = strftime("logfile-%Y-%m-%d", localtime);

(Notice how conveniently strftime takes the same arguments that localtime returns.)

Okay, but what if you had just collected statistics about yesterday’s events (e.g., web server statistics), and wanted to put them in a log file with yesterday’s date? You might think the easiest thing to do is to call localtime and subtract one from the day number.

And subtract one from the month number if today is the first of the month. And subtract one from the year number if today is January 1st. And figure out how many days were in the last month, and whether it was February on a leap year.

There’s a simpler way: time returns the number of seconds since the Unix Epoch, Jan. 1, 1970 at midnight. There are 60 * 60 * 24 = 86400 seconds in a day. So 86400 seconds ago was yesterday. The time-related functions in the POSIX module were written by clever people who took the time to figure out the best way to convert a Unix time to year, month, day, etc. So you can just create your filename with:

use POSIX;
$log_file_name = strftime("logfile-%Y-%m-%d", localtime(time - 86400));
This entry was posted in Perl. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s