diff options
author | Stuart Bishop <stuart@stuartbishop.net> | 2014-11-03 08:24:30 +0000 |
---|---|---|
committer | Stuart Bishop <stuart@stuartbishop.net> | 2014-11-03 08:24:30 +0000 |
commit | 25d85435699db22861bdbdcc9d7244f9ea6c220f (patch) | |
tree | d5860011c54c4e6f6ea9e24c5bf390fae57af3a1 /src | |
parent | 86eb5b8775bd9fa105ddc3338a99c8df6c73c161 (diff) | |
download | pytz-25d85435699db22861bdbdcc9d7244f9ea6c220f.tar.gz |
Handle non-DST->non-DST transitions better, from jfs per https://bugs.launchpad.net/pytz/+bug/1378150
Diffstat (limited to 'src')
-rw-r--r-- | src/pytz/tests/test_tzinfo.py | 20 | ||||
-rw-r--r-- | src/pytz/tzinfo.py | 17 |
2 files changed, 27 insertions, 10 deletions
diff --git a/src/pytz/tests/test_tzinfo.py b/src/pytz/tests/test_tzinfo.py index adf622a..677649d 100644 --- a/src/pytz/tests/test_tzinfo.py +++ b/src/pytz/tests/test_tzinfo.py @@ -659,6 +659,23 @@ class LocalTestCase(unittest.TestCase): loc_time = loc_tz.localize(datetime(1945, 9, 30, 1, 0, 0), is_dst=0) self.assertEqual(loc_time.strftime('%Z%z'), 'EST-0500') + # Weird changes - ambiguous time (end-of-DST like) but is_dst==False + for zonename, ambiguous_naive, expected in [ + ('Europe/Warsaw', datetime(1915, 8, 4, 23, 59, 59), + ['1915-08-04 23:59:59 WMT+0124', + '1915-08-04 23:59:59 CET+0100']), + ('Europe/Moscow', datetime(2014, 10, 26, 1, 30), + ['2014-10-26 01:30:00 MSK+0400', + '2014-10-26 01:30:00 MSK+0300'])]: + loc_tz = pytz.timezone(zonename) + self.assertRaises(pytz.AmbiguousTimeError, + loc_tz.localize, ambiguous_naive, is_dst=None + ) + # Also test non-boolean is_dst in the weird case + for dst in [True, timedelta(1), False, timedelta(0)]: + loc_time = loc_tz.localize(ambiguous_naive, is_dst=dst) + self.assertEqual(loc_time.strftime(fmt), expected[not dst]) + def testNormalize(self): tz = pytz.timezone('US/Eastern') dt = datetime(2004, 4, 4, 7, 0, 0, tzinfo=UTC).astimezone(tz) @@ -677,7 +694,7 @@ class LocalTestCase(unittest.TestCase): def testPartialMinuteOffsets(self): # utcoffset in Amsterdam was not a whole minute until 1937 # However, we fudge this by rounding them, as the Python - # datetime library + # datetime library tz = pytz.timezone('Europe/Amsterdam') utc_dt = datetime(1914, 1, 1, 13, 40, 28, tzinfo=UTC) # correct utc_dt = utc_dt.replace(second=0) # But we need to fudge it @@ -817,4 +834,3 @@ def test_suite(): if __name__ == '__main__': warnings.simplefilter("error") # Warnings should be fatal in tests. unittest.main(defaultTest='test_suite') - diff --git a/src/pytz/tzinfo.py b/src/pytz/tzinfo.py index d53e9ff..1318872 100644 --- a/src/pytz/tzinfo.py +++ b/src/pytz/tzinfo.py @@ -142,7 +142,7 @@ class StaticTzInfo(BaseTzInfo): def __reduce__(self): # Special pickle to zone remains a singleton and to cope with - # database changes. + # database changes. return pytz._p, (self.zone,) @@ -369,13 +369,15 @@ class DstTzInfo(BaseTzInfo): # hints to be passed in (such as the UTC offset or abbreviation), # but that is just getting silly. # - # Choose the earliest (by UTC) applicable timezone. - sorting_keys = {} + # Choose the earliest (by UTC) applicable timezone if is_dst=True + # Choose the latest (by UTC) applicable timezone if is_dst=False + # i.e., behave like end-of-DST transition + dates = {} # utc -> local for local_dt in filtered_possible_loc_dt: - key = local_dt.replace(tzinfo=None) - local_dt.tzinfo._utcoffset - sorting_keys[key] = local_dt - first_key = sorted(sorting_keys)[0] - return sorting_keys[first_key] + utc_time = local_dt.replace(tzinfo=None) - local_dt.tzinfo._utcoffset + assert utc_time not in dates + dates[utc_time] = local_dt + return dates[[min, max][not is_dst](dates)] def utcoffset(self, dt, is_dst=None): '''See datetime.tzinfo.utcoffset @@ -560,4 +562,3 @@ def unpickler(zone, utcoffset=None, dstoffset=None, tzname=None): inf = (utcoffset, dstoffset, tzname) tz._tzinfos[inf] = tz.__class__(inf, tz._tzinfos) return tz._tzinfos[inf] - |