UPDATE 2023-03-27: This page is obsolete, as it refers to a prior version of this blog. However, it may be of historical interest.

I recently experienced a strange problem with the Atom feed on my weblog. My weblog server is running on US Eastern time as the basic time zone, but the story dates in the Atom feed should be expressed in UTC/GMT; the atomfeed plugin has code that supposedly should do any necessary conversions. On my local test blog (running under OS X 10.3 using Perl 5.8.1) this worked fine, but on my real blog (running on Red Hat Enterprise Linux 3 using Perl 5.8.0) the dates in the Atom feed were incorrect; they were five hours earlier than what they should be, suggesting that they didn’t get converted to UTC/GMT. After some investigation this turned out to be due to non-portable code in the atomfeed plugin.

More specifically, the atomfeed plugin attempts to convert the modification time of each entry file (expressed as a Unix time, i.e., in seconds since the epoch) into a UTC date by calling the subroutine blosxom::nice_date, which in turn uses the ctime function defined by Time::localtime. Since ctime normally converts Unix time into a local time (i.e., using the time zone currently in effect), the original atomfeed plugin attempts to coerce ctime into returning a UTC/GMT time by setting the TZ environment variable to the value ’GMT’ prior to calling nice_date, and then restoring TZ to its original value afterwards.

Unfortunately, as noted in “Writing Portable Perl,” this won’t necessarily work on all systems:

The system’s notion of time of day and calendar date is controlled in widely different ways. Don’t assume the timezone is stored in $ENV{TZ}, and even if it is, don’t assume that you can control the timezone through that variable.

I appear to have hit one of the cases where this doesn’t work.

In any case the solution was simple: I just changed the atomfeed plugin to convert the entry’s modification time using the built-in Perl function gmtime, which converts a Unix time into a time expressed as UTC/GMT. Like the nice_date subroutine the gmtime function returns an array; the returned values require a bit more reformatting than those from nice_date, but nothing that complicated.

For the exact code changes see the atomfeed UTC patch itself.