Search code examples
pythondatetimeutcpytz

Pytz Python Timezone Conversion Not Working


I'm trying to convert "Europe/London" pytz timezone to UTC without success:

>>>tz=pytz.timezone("Europe/London")
>>>date=datetime.datetime(2015,1,1,4,4)
>>>tz.normalize(tz.localize(date)).astimezone(pytz.utc)
datetime.datetime(2015, 1, 1, 4, 4, tzinfo=<UTC>)
>>>tz.localize(date)
datetime.datetime(2015, 1, 1, 4, 4, tzinfo=<DstTzInfo 'Europe/London'GMT0:00:00 STD>)

This is just flat out wrong, why is the line directly above at GMT-0 when it should be GMT+1. London time is currently one hour ahead of UTC because of daylights savings but the code isn't producing this.

>>>tz.normalize(tz.localize(date)).astimezone(pytz.utc) #should produce:
datetime.datetime(2015, 1, 1, 3, 4, tzinfo=<UTC>)

Solution

  • You shouldn't expect the summer time in January in the Northern Hemisphere in London.

    pytz-2015.4 version produces the same (correct) result:

    >>> from datetime import datetime
    >>> import pytz
    >>> d = datetime(2015, 1, 1, 4, 4)
    >>> tz = pytz.timezone('Europe/London')
    >>> tz.localize(d, is_dst=None).astimezone(pytz.utc)
    datetime.datetime(2015, 1, 1, 4, 4, tzinfo=<UTC>)
    >>> tz.localize(d, is_dst=None)
    datetime.datetime(2015, 1, 1, 4, 4, tzinfo=<DstTzInfo 'Europe/London' GMT0:00:00 STD>)
    

    zdump on my system agrees with it:

    $ zdump -v Europe/London | grep 2015
    Europe/London  Sun Mar 29 00:59:59 2015 UT = Sun Mar 29 00:59:59 2015 GMT isdst=0 gmtoff=0
    Europe/London  Sun Mar 29 01:00:00 2015 UT = Sun Mar 29 02:00:00 2015 BST isdst=1 gmtoff=3600
    Europe/London  Sun Oct 25 00:59:59 2015 UT = Sun Oct 25 01:59:59 2015 BST isdst=1 gmtoff=3600
    Europe/London  Sun Oct 25 01:00:00 2015 UT = Sun Oct 25 01:00:00 2015 GMT isdst=0 gmtoff=0
    

    i.e., until March 29, 2015 the utc offset is zero in London.

    The tz database itself agrees: Europe/London uses EU rules for DST transitions since 1996: the summer time doesn't start until the last Sunday in March.