Search code examples
pythondatetimepytz

Normalize datetime object


I'm doing some datetime magic and trying to figure out why the hours are slightly off.

3pm Central on June 3rd 2014 as UTC:

>>> chicago = pytz.timezone('US/Central')
>>> chicago.localize(datetime(2014,6,3,15,0,0)).astimezone(pytz.utc)
datetime.datetime(2014, 6, 3, 20, 0, tzinfo=<UTC>)

3pm Central on December 2nd 2014 as UTC:

>>> chicago.localize(datetime(2014,12,2,15,0,0)).astimezone(pytz.utc)
datetime.datetime(2014, 12, 2, 21, 0, tzinfo=<UTC>)

The hour in the second example is 21 as opposed to 20 in the first example. I thought maybe the date isn't normalized, so I tried this:

>>> chicago.normalize(chicago.localize(datetime(2014,12,2,15,0,0))).astimezone(pytz.utc)
datetime.datetime(2014, 12, 2, 21, 0, tzinfo=<UTC>)

It's still 21. What's going on here?


Solution

  • Daylight Savings Time.

    In the first case (Jun 3), Chicago is under Central Daylight Savings Time. The offset to UTC is five hours.

    >>> fmt = '%Y-%m-%d %H:%M:%S %Z%z'
    >>> clt=chicago.localize(datetime(2014,6,3,15,0,0))
    >>> clt.strftime(fmt)
    '2014-06-03 15:00:00 CDT-0500'
                         ^^^^^^^^
    

    In the second case (Dec 2), Chicago is under Central Standard Time. The offset to UTC is six hours.

    >>> clt=chicago.localize(datetime(2014,12,2,15,0,0))
    >>> clt.strftime(fmt)
    '2014-12-02 15:00:00 CST-0600'
                         ^^^^^^^^
    

    Your call to normalize() doesn't help here, because you're not doing date or time arithmetic on local times that cross DST boundaries.