strftime in Python

Time has never been easy to work with, and while it is best to use UTC to store time, it is necessary to use local time zones when displaying time to the user.

With regards to displaying local timezones using strftime and the format specifications %Z for timezone name and %z for the RFC-2822 conformant [+-]hhmm displays, Perl and PHP work fine, at least on Fedora FC5. Python 2.4 does not yet have support for %z, and the best support in Python for timezone is using the basic time module; the enhanced datetime module has no built-in support for time zones.

That takes care of strftime, what about strptime? Unfortunately, that is a topic that is even more convoluted, so try all variations out before you use it on any system.

Here's a strftime support summary for Python date/time users:

  • Use the datetime module if you don't need any timezone handling. The standard library comes with no support for any timezones, not even local timezones, so datetime module is useless for those who need to use time zone information. This can be done of course, but requires coding up your own timezone routines.
  • Use the time module if you can live with just %Z and don't need %z. Python 2.4 time module always prints wrong value +0000 for %z, even while it gets %Z correct.
  • Need %z, the RFC-2822 conformant time display? This requires writing your own code, Python does not support this. Using the basic time module, here's example code on how to get these values:
    lt = localtime(t)
    if lt.tm_isdst > 0 and time.daylight:
        tz = time.tzname[1]
        utc_offset_minutes = - int(time.altzone/60)
    else:
        tz = time.tzname[0]
        utc_offset_minutes = - int(time.timezone/60)
    utc_offset_str = "%+03d%02d" % (utc_offset_minutes/60.0, utc_offset_minutes % 60)

    Note: in the utc_offset_str computation, the use of 60.0 float in the / operation is necessary to get a value rounded to 0 instead of negative infinity, for example, -90 minutes offset should be -0130 and not -0230.

Here's the sample code and the output from Perl, Php, and Python, for two example strftime calls:

Perl 5.8.8:
$t = 1172342943; # /* EST-0500 */
print "strftime %Z%z for localtime($t) :"  . strftime("Zone: %Z%z\n", localtime($t));

$t = 1177342943; # /* EDT-0400 */
print "strftime %Z%z for localtime($t) :"  . strftime("Zone: %Z%z\n", localtime($t));

# outputs
# strftime %Z%z for localtime(1172342943) :Zone: EST-0500
# strftime %Z%z for localtime(1177342943) :Zone: EDT-0400

----------------

PHP 5.1.6:
$t = 1172342943; # /* EST-0500 */
print "strftime %Z%z for localtime($t) :"  . strftime("Zone: %Z%z\n", $t);

$t = 1177342943; # /* EDT-0400 */
print "strftime %Z%z for localtime($t) :"  . strftime("Zone: %Z%z\n", $t);

/*
outputs:
strftime %Z%z for localtime(1172342943) :Zone: EST-0500
strftime %Z%z for localtime(1177342943) :Zone: EDT-0400
*/

---------------

Python:
from time import strftime, localtime

t = 1172342943; # /* EST-0500 */
print "strftime %Z%z for localtime(", t, ") :", strftime("Zone: %Z%z\n", localtime(t)),

t = 1177342943; # /* EDT-0400 */
print "strftime %Z%z for localtime(", t, ") :", strftime("Zone: %Z%z\n", localtime(t)),

# outputs:
# strftime %Z%z for localtime( 1172342943 ) : Zone: EST+0000
# strftime %Z%z for localtime( 1177342943 ) : Zone: EDT+0000
(above EST/EDT printout is correct, but associated +0000 values are wrong, 
see correct values in Perl or PHP section)

Comments

thanks for the analysis, i

thanks for the analysis, i thought there may have been a bug in my code but in fact it's python lameness ;-)