#591 TimeZoneInfo does not convert timezones correctly

closed
5
2012-05-05
2012-05-02
No

in the following example two dates are converted from Hawaii time zone to Pacific time zone. In both cases the time difference should be 3 hours.
The first is correct, the second is incorrect

>>> from win32timezone import TimeZoneInfo
>>> from datetime import datetime
>>> tzi = TimeZoneInfo('Hawaiian Standard Time')
>>> tzs = TimeZoneInfo('Pacific Standard Time')
>>> dthaw = datetime(2011, 11, 5, 15, 59, 59, 0, tzinfo=tzi)
>>> print dthaw.timetuple()
time.struct_time(tm_year=2011, tm_mon=11, tm_mday=5, tm_hour=15, tm_min=59, tm_sec=59, tm_wday=5, tm_yday=309, tm_isdst=0)
>>> dtpac = dthaw.astimezone(tzs)
>>> print dtpac.timetuple()
time.struct_time(tm_year=2011, tm_mon=11, tm_mday=5, tm_hour=18, tm_min=59, tm_sec=59, tm_wday=5, tm_yday=309, tm_isdst=1)
>>>
>>> dthaw = datetime(2011, 11, 5, 16, 0, 0, 0, tzinfo=tzi)
>>> print dthaw.timetuple()
time.struct_time(tm_year=2011, tm_mon=11, tm_mday=5, tm_hour=16, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=309, tm_isdst=0)
>>> dtpac = dthaw.astimezone(tzs)
>>> print dtpac.timetuple()
time.struct_time(tm_year=2011, tm_mon=11, tm_mday=5, tm_hour=17, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=309, tm_isdst=1)
>>>

Discussion

  • Brian Matthews

    Brian Matthews - 2012-05-02

    This was using the patched code from #3521185

     
  • Brian Matthews

    Brian Matthews - 2012-05-04

    I think the problem is that TimeZoneInof only works with Naive datetime. That is, if you pass in a datetime in UTC, the utcoffset() returns as if it were localtime.
    EG:

    from win32timezone import TimeZoneInfo
    from datetime import datetime
    import calendar
    import time
    tzi = TimeZoneInfo('Pacific Standard Time')
    tzutc = TimeZoneInfo('Coordinated Universal Time')
    tz_time = datetime(2011, 11, 6, 4, 0, 0, tzinfo=tzutc)
    tzi.utcoffset(tz_time).total_seconds()/60/60

    shows -8:00 when it should be -7:00 because the datetime is UTC, not localtime.
    We have a way around this rght now by doing a 2-pass calculation tto see if we crossed the pst/dst time.

    win32timezone needs a method of showing the utcoffset for a utc timestamp in the specified timezone

     
  • Jason R. Coombs

    Jason R. Coombs - 2012-05-05
    • status: open --> closed
     
  • Jason R. Coombs

    Jason R. Coombs - 2012-05-05

    Brian, thanks for your help and patience. The problem is fixed in 085048997feb.

    You want the utc offset for a utc timestamp in a specified timezone?

    >>> timestamp = datetime(2011, 11, 6, 4, 0, tzinfo=TimeZoneInfo.utc())
    >>> dt_pac = timestamp.astimezone(TimeZoneInfo('Pacific Standard Time'))
    >>> dt_pac.utcoffset().total_seconds() / 3600
    -7.0

    Do you think win32timezone should have a single function that takes a naive timestamp in utc and a time zone name and returns the offset? Something like offset_for_utc_timestamp_in_zone(datetime, zone_name) ?

     
  • Brian Matthews

    Brian Matthews - 2012-05-05

    Thanks again for your quick work!

    A small discrepancy. I am running my PC in Pacific time, so I have a way to check the results. The script below converts a UTC timestamp into a datetime in the Pacific time zone. The result is different for the second timestamp when doing the same thing using localtime()

    from win32timezone import TimeZoneInfo
    from datetime import datetime
    import calendar
    import time

    tzi = TimeZoneInfo('Pacific Standard Time')
    tzutc = TimeZoneInfo('Coordinated Universal Time')

    def fromtimestamp_to_timetuple(timestamp):
    tm = time.gmtime(timestamp)
    tz1 = datetime(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tzinfo=tzutc)
    tz_time = tz1.astimezone(tzi)
    return tz_time

    print fromtimestamp_to_timetuple(1320573600).timetuple()
    print fromtimestamp_to_timetuple(1320570000).timetuple()
    print fromtimestamp_to_timetuple(1320566400).timetuple()

    print time.strftime('%c', time.localtime(1320573600))
    print time.strftime('%c', time.localtime(1320570000))
    print time.strftime('%c', time.localtime(1320566400))

    To answer you question about the function for Naive datetime.
    It would be better if utcoffset() accepted a datetime that was not Naive.
    This example logically should show a utcoffset of -7, but it shows -8 as utcoffset ignores the tz in datetime

    from win32timezone import TimeZoneInfo
    from datetime import datetime
    import calendar
    import time
    tzi = TimeZoneInfo('Pacific Standard Time')
    tzutc = TimeZoneInfo('Coordinated Universal Time')
    tz_time = datetime(2011, 11, 6, 4, 0, 0, tzinfo=tzutc)
    tzi.utcoffset(tz_time).total_seconds()/60/60

    But this is academic for me at this point, plus it might break existing code.
    Maybe a new function that is accepts tz-aware datetimes?

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.





No, thanks