Perl Date Geekery

Last August, Pun Salad moved from its UNH host (specifically, the workstation under my desk) to Arias Web Hosting. They've been great, and if you're looking for a provider that allows you a decent amount of control over your site, I can recommend them.

However, the server is (apparently) located out there in the great US/Central time zone. (At least that's what the shell command date +%Z claims.) And so the timestamps at the bottom of each post dutifully reported US/Central time.

But Pun Salad's heart and soul (and, arguably, brain) is almost always zoned on US/Eastern time. So the discrepancy has been something I've been meaning to fix.

The first whack was pretty easy. The script that generates Pun Salad is written in Perl, and Pun Salad's host is running Linux. And (it turns out) in that environment, you can tell Perl to imagine it's in a different time zone by setting the TZ environment variable at the top of your script:

    $ENV{'TZ'} = ':/usr/share/zoneinfo/US/Eastern';
Hey, that worked great!

But, there was still a minor problem, one which Pun Salad has had since its inception: the timestamps would show up as EST or EDT (or CST/CDT) depending on when you looked at them. (Specifically: when the script generating the page was run.)

Irritating! If I posted an article at 6pm EDT on July 15, it should always show up as being posted at 6pm EDT, even when viewed in EST-February.

This turned out to be surprisingly difficult using my Perl date manipulation package of choice, Date::Manip. Ordinarily, this package is awesome. And (to the author's great credit), the problem shows up prominently in the documentation, under "Known Bugs": "Date::Manip does not handle daylight saving time." Rats!

Fortunately, this is fixable using the standard Perl localtime and POSIX::strftime routines. Roughly, I replaced Date::Manip code that looked like:

    use Date::Manip;
    ...
    # given Linux timestamp $ts, generate human-readable date/time
    $date = UnixDate(ParseDate("epoch $ts"), "%Y-%m-%d %i:%M %p %Z");
with something like this:
    use POSIX qw/strftime/;
    ...
    # given Linux timestamp $ts, generate human-readable date/time
    $date = strftime("%Y-%m-%d %-I:%M %p %Z", localtime($ts));
Ahhhh, that's better. If you want to check out what I said last June on the hysteria about "speculators", you'll note that it was posted and modified on Eastern Daylight Time, which it was.

Now if only I could get decent Google ads. As I type, due to my stimulus-bashing over the past few weeks, they are titled "Obama Is Giving You Money", "$37,383 Stimulus Checks", "Your Stimulus Check", and "Free Stimulus Grants Kit". Google not only hates America, they also think you're pretty stupid. (But feel free to click away, if you'd like to be amused or disgusted, at the same time sending a few pennies this way.)


Last Modified 2012-10-08 7:55 PM EDT