[nylug-talk] Python time zones

Chris Knadle Chris.Knadle at coredump.us
Tue Mar 11 16:31:22 EDT 2008


   As previously discussed, I had a chance to talk to my friend dealing with 
the Python timezone issues.

On Wednesday 05 March 2008, Peter C. Norton wrote:
> On Wed, Mar 05, 2008 at 11:54:15AM -0500, Chris Knadle wrote:
> >    Just something I wanted to mention concerning Python time zones since
> > the subject was brought up.  A friend has run into some interesting
> > difficulties dealing with timezones in Python relating to DST: the
> > standard way Python subtracts time is to check if the timezones match,
> > and if they don't time is converted to UTC first then subtracted, but if
> > the timezones do match then the subtraction is done directly.  [Seemingly
> > makes sense at first.]  This has an interesting consequence, though,
> > because it means a change to DST isn't taken into account -- because a
> > switch to DST is only taken into account during a conversion to UTC.
>
> The tz object in a datetime object has the offset from UTC encoded in
> it, so if the objects were created timezone-aware, they shouldn't
> compare as being equal. I think there's a subtlety to this
> that hasn't come out in the story.

   It sounds like there are a couple of subtleties.  Disclaimer: I'm not much 
of a Python programmer myself thusfar, so I'm relaying info here.

   First, Python itself only implements a general TZinfo class, so the actual 
code to implement this class is implemented in an external library.  Two 
current implementations are in the 'dateutils' and 'pytz' libraries.

   Second, whether a timezone is in or out of DST has to do with information 
within a TZinfo object.  Thus, changing to DST or out of DST does not change 
which TZinfo object a DateTime object references.

   When two DateTime objects are to be subtracted, if they have the same 
TZinfo object (I.E. they're in the same geographical region), then they are 
not first converted to UTC before the subtraction.  This means that DST
*IS NOT* taken into account when subtracting two DateTime objects if they have 
the same TZinfo object.


   The following program illustrates this issue.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

#!/usr/bin/env python
# encoding: utf-8

from dateutil.tz import gettz
from datetime import datetime, timedelta, tzinfo
from pytz import timezone
import copy

NYC = gettz('America/New_York')
UTC = gettz('UTC')

a = datetime(2008, 3, 9, 0, 0, 0, tzinfo=NYC)
b = datetime(2008, 3, 9, 3, 0, 0, tzinfo=NYC)

print 'Time a is %s' % a.isoformat()
print 'Time b is %s' % b.isoformat()
print
print 'Time a as UTC is %s' % a.astimezone(UTC).isoformat()
print 'Time b as UTC is %s' % b.astimezone(UTC).isoformat()
print
print 'Therefore, the time delta when subtracting a from b should be %s' % \
         (b.astimezone(UTC) - a.astimezone(UTC))
print
print 'But b - a is %s, which is incorrect.' % (b-a)
print
print 'However, if a different tzinfo object is used, the subtraction is done correctly.'

# This makes a functionally identical, but distinct tzinfo object
alt_NYC = copy.deepcopy(NYC)

c = datetime(2008, 3, 9, 3, 0, 0, tzinfo=alt_NYC)

print 'Time c is %s, which is the same as b above.' % c.isoformat()
print
print 'Yet, c - a is %s, which is correct, and different from b - a!' % (c-a)

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

   -- Chris

-- 

Chris Knadle
Chris.Knadle at coredump.us



More information about the nylug-talk mailing list