mhammond / pywin32

Python for Windows (pywin32) Extensions
4.99k stars 790 forks source link

Fix for 3524786 breaks None-ambiguous conversions #593

Open ghost opened 12 years ago

ghost commented 12 years ago

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 >>>

Reported by: bmatthews27

Original Ticket: pywin32/bugs/593

ghost commented 12 years ago

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?

Original comment by: jaraco

ghost commented 12 years ago

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 >>>

Original comment by: bmatthews27

ghost commented 12 years ago

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.

Original comment by: jaraco