diff options
author | Alexander Belopolsky <alexander.belopolsky@gmail.com> | 2012-06-22 16:23:23 (GMT) |
---|---|---|
committer | Alexander Belopolsky <alexander.belopolsky@gmail.com> | 2012-06-22 16:23:23 (GMT) |
commit | fdc860f3106b59ec908e0b605e51a1607ea2ff4b (patch) | |
tree | 987e362d240fea4f004803dd9fa0dd62b5d35db2 /Lib | |
parent | 8f904daee9dcb6b36b925f184144921e8bf6aaa6 (diff) | |
download | cpython-fdc860f3106b59ec908e0b605e51a1607ea2ff4b.zip cpython-fdc860f3106b59ec908e0b605e51a1607ea2ff4b.tar.gz cpython-fdc860f3106b59ec908e0b605e51a1607ea2ff4b.tar.bz2 |
Issue #9527: datetime.astimezone() method will now supply a class
timezone instance corresponding to the system local timezone when
called with no arguments.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/datetime.py | 28 | ||||
-rw-r--r-- | Lib/test/datetimetester.py | 21 |
2 files changed, 44 insertions, 5 deletions
diff --git a/Lib/datetime.py b/Lib/datetime.py index 6ab2499..ce88d85 100644 --- a/Lib/datetime.py +++ b/Lib/datetime.py @@ -1493,8 +1493,32 @@ class datetime(date): return datetime(year, month, day, hour, minute, second, microsecond, tzinfo) - def astimezone(self, tz): - if not isinstance(tz, tzinfo): + def astimezone(self, tz=None): + if tz is None: + if self.tzinfo is None: + raise ValueError("astimezone() requires an aware datetime") + ts = (self - _EPOCH) // timedelta(seconds=1) + localtm = _time.localtime(ts) + local = datetime(*localtm[:6]) + try: + # Extract TZ data if available + gmtoff = localtm.tm_gmtoff + zone = localtm.tm_zone + except AttributeError: + # Compute UTC offset and compare with the value implied + # by tm_isdst. If the values match, use the zone name + # implied by tm_isdst. + delta = local - datetime(*_time.gmtime(ts)[:6]) + dst = _time.daylight and localtm.tm_isdst > 0 + gmtoff = _time.altzone if dst else _time.timezone + if delta == timedelta(seconds=-gmtoff): + tz = timezone(delta, _time.tzname[dst]) + else: + tz = timezone(delta) + else: + tz = timezone(timedelta(seconds=-gmtoff), zone) + + elif not isinstance(tz, tzinfo): raise TypeError("tz argument must be an instance of tzinfo") mytz = self.tzinfo diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 048d63c..e045447 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -1972,7 +1972,7 @@ class TestDateTime(TestDate): # simply can't be applied to a naive object. dt = self.theclass.now() f = FixedOffset(44, "") - self.assertRaises(TypeError, dt.astimezone) # not enough args + self.assertRaises(ValueError, dt.astimezone) # naive self.assertRaises(TypeError, dt.astimezone, f, f) # too many args self.assertRaises(TypeError, dt.astimezone, dt) # arg wrong type self.assertRaises(ValueError, dt.astimezone, f) # naive @@ -3253,8 +3253,6 @@ class TestDateTimeTZ(TestDateTime, TZInfoBase, unittest.TestCase): self.assertTrue(dt.tzinfo is f44m) # Replacing with degenerate tzinfo raises an exception. self.assertRaises(ValueError, dt.astimezone, fnone) - # Ditto with None tz. - self.assertRaises(TypeError, dt.astimezone, None) # Replacing with same tzinfo makes no change. x = dt.astimezone(dt.tzinfo) self.assertTrue(x.tzinfo is f44m) @@ -3274,6 +3272,23 @@ class TestDateTimeTZ(TestDateTime, TZInfoBase, unittest.TestCase): self.assertTrue(got.tzinfo is expected.tzinfo) self.assertEqual(got, expected) + @support.run_with_tz('UTC') + def test_astimezone_default_utc(self): + dt = self.theclass.now(timezone.utc) + self.assertEqual(dt.astimezone(None), dt) + self.assertEqual(dt.astimezone(), dt) + + @support.run_with_tz('EST+05EDT,M3.2.0,M11.1.0') + def test_astimezone_default_eastern(self): + dt = self.theclass(2012, 11, 4, 6, 30, tzinfo=timezone.utc) + local = dt.astimezone() + self.assertEqual(dt, local) + self.assertEqual(local.strftime("%z %Z"), "+0500 EST") + dt = self.theclass(2012, 11, 4, 5, 30, tzinfo=timezone.utc) + local = dt.astimezone() + self.assertEqual(dt, local) + self.assertEqual(local.strftime("%z %Z"), "+0400 EDT") + def test_aware_subtract(self): cls = self.theclass |