#593 Fix for 3524786 breaks None-ambiguous conversions

open
5
2012-05-10
2012-05-10
Brian Matthews
No

I seem to be causing you lots of problems.... :(

The fix for 3524786 has introduced new issues. This example shows a none-ambiguous conversion. The timestamps are in UTC, and therefore do have a correct conversion that is not ambiguous. I dont think raising an exception is going to help here.

The script should be run with the PC in the Pacific Time Zone so localtime() can be used for comparison. It should show local times of 2:00 AM (STD), 1:00 AM (STD), 1:00 AM (DST)

I am going to suggest removing the exception. The ambiguous issue is when converting from localtimes to UTC or another timezone.
I am not really sure how it should be fixed. The only possible solution is to be able to tell the function it is 1:30 in DST or STD. but I dont know how this could be implemented as datetime does not have this. Perhaps it should just be documented as an ambiguity.

Anyway, here is the script showing the problem.

>>> import win32timezone
>>> from datetime import datetime
>>> import time
>>>
... PST = win32timezone.TimeZoneInfo('Pacific Standard Time')
>>>
>>> print datetime.fromtimestamp(1320573600, PST)
2011-11-06 02:00:00-08:00
>>> print datetime.fromtimestamp(1320570000, PST)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\site-packages\win32\lib\win32timezone.py", line 635, in utcoffset
return -winInfo.bias + self.dst(dt)
File "C:\Python27\lib\site-packages\win32\lib\win32timezone.py", line 641, in dst
if not self.fixedStandardTime and self._inDaylightSavings(dt):
File "C:\Python27\lib\site-packages\win32\lib\win32timezone.py", line 664, in _inDaylightSavings
raise AmbiguousTimeError(dt)
win32timezone.AmbiguousTimeError: 2011-11-06 01:00:00
>>> print datetime.fromtimestamp(1320566400, PST)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\site-packages\win32\lib\win32timezone.py", line 635, in utcoffset
return -winInfo.bias + self.dst(dt)
File "C:\Python27\lib\site-packages\win32\lib\win32timezone.py", line 641, in dst
if not self.fixedStandardTime and self._inDaylightSavings(dt):
File "C:\Python27\lib\site-packages\win32\lib\win32timezone.py", line 664, in _inDaylightSavings
raise AmbiguousTimeError(dt)
win32timezone.AmbiguousTimeError: 2011-11-06 01:00:00
>>>
>>> print time.strftime('%c', time.localtime(1320573600))
11/06/11 02:00:00
>>> print time.strftime('%c', time.localtime(1320570000))
11/06/11 01:00:00
>>> print time.strftime('%c', time.localtime(1320566400))
11/06/11 01:00:00
>>>

Discussion

  • I was afraid we might encounter something like this. In that case, would you try the parent revision, which doesn't add the ambiguous exception?

     
  • Brian Matthews
    Brian Matthews
    2012-05-10

    Ok, that is much better. There is still one issue, datetime is showing the offset as -08:00 for the last timestamp, and it should be -07:00. But the hour is correct now.

    >>> import win32timezone
    >>> from datetime import datetime
    >>> import time
    >>>
    ... PST = win32timezone.TimeZoneInfo('Pacific Standard Time')
    >>>
    >>> print datetime.fromtimestamp(1320573600, PST)
    2011-11-06 02:00:00-08:00
    >>> print datetime.fromtimestamp(1320570000, PST)
    2011-11-06 01:00:00-08:00
    >>> print datetime.fromtimestamp(1320566400, PST)
    2011-11-06 01:00:00-08:00
    >>>
    >>> print time.strftime('%c', time.localtime(1320573600))
    11/06/11 02:00:00
    >>> print time.strftime('%c', time.localtime(1320570000))
    11/06/11 01:00:00
    >>> print time.strftime('%c', time.localtime(1320566400))
    11/06/11 01:00:00
    >>>

     
  • Thanks. I've backed out the ambiguous timezone detection, so the code is using the earlier code against which you tested. Now to figure out how to determine the correct time zone for timestamps. It's not at all clear from the datetime documentation what needs to be done to produce a proper result in the case of the timestamp.

    Looking at another implementation, pytz, I see that it actually uses a different timezone object than the one that was passed in when it processes the fromtimestamp, and the tzinfo objects themselves have daylight savings time awareness:

    >>> import pytz
    >>> PST = pytz.timezone('US/Pacific')
    >>> PST
    <DstTzInfo 'US/Pacific' PST-1 day, 16:00:00 STD>
    >>> import datetime
    >>> datetime.datetime.fromtimestamp(1320566400, PST)
    datetime.datetime(2011, 11, 6, 1, 0, tzinfo=<DstTzInfo 'US/Pacific' PDT-1 day, 17:00:00 DST>)
    >>> _.tzinfo
    <DstTzInfo 'US/Pacific' PDT-1 day, 17:00:00 DST>

    This finding makes me think that the proper implementation of a timezone object on Python is far more complicated than the datetime docs suggest it should be. I plan to revisit this at some point.