def test_isoformat_timezone(self): tzoffsets = [ ("05:00", timedelta(hours=5)), ("02:00", timedelta(hours=2)), ("06:27", timedelta(hours=6, minutes=27)), ("12:32:30", timedelta(hours=12, minutes=32, seconds=30)), ( "02:04:09.123456", timedelta(hours=2, minutes=4, seconds=9, microseconds=123456), ), ] tzinfos = [ ("", None), ("+00:00", timezone.utc), ("+00:00", timezone(timedelta(0))), ] tzinfos += [(prefix + expected, timezone(sign * td)) for expected, td in tzoffsets for prefix, sign in [("-", -1), ("+", 1)]] dt_base = self.theclass(2016, 4, 1, 12, 37, 9) exp_base = "2016-04-01T12:37:09" for exp_tz, tzi in tzinfos: dt = dt_base.replace(tzinfo=tzi) exp = exp_base + exp_tz with self.subTest(tzi=tzi): assert dt.isoformat() == exp
def test_fromisoformat_timespecs(self): datetime_bases = [(2009, 12, 4, 8, 17, 45, 123456), (2009, 12, 4, 8, 17, 45, 0)] tzinfos = [ None, timezone.utc, timezone(timedelta(hours=-5)), timezone(timedelta(hours=2)), timezone(timedelta(hours=6, minutes=27)), ] timespecs = [ "hours", "minutes", "seconds", "milliseconds", "microseconds" ] for ip, ts in enumerate(timespecs): for tzi in tzinfos: for dt_tuple in datetime_bases: if ts == "milliseconds": new_microseconds = 1000 * (dt_tuple[6] // 1000) dt_tuple = dt_tuple[0:6] + (new_microseconds, ) dt = self.theclass(*(dt_tuple[0:(4 + ip)]), tzinfo=tzi) dtstr = dt.isoformat(timespec=ts) with self.subTest(dtstr=dtstr): dt_rt = self.theclass.fromisoformat(dtstr) self.assertEqual(dt, dt_rt)
def test_fromisoformat_datetime(self): # Test that isoformat() is reversible base_dates = [(1, 1, 1), (1900, 1, 1), (2004, 11, 12), (2017, 5, 30)] base_times = [ (0, 0, 0, 0), (0, 0, 0, 241000), (0, 0, 0, 234567), (12, 30, 45, 234567), ] separators = [" ", "T"] tzinfos = [ None, timezone.utc, timezone(timedelta(hours=-5)), timezone(timedelta(hours=2)), ] dts = [ self.theclass(*date_tuple, *time_tuple, tzinfo=tzi) for date_tuple in base_dates for time_tuple in base_times for tzi in tzinfos ] for dt in dts: for sep in separators: dtstr = dt.isoformat(sep=sep) with self.subTest(dtstr=dtstr): dt_rt = self.theclass.fromisoformat(dtstr) self.assertEqual(dt, dt_rt)
def test_subclass_now(self): # Test that alternate constructors call the constructor class DateTimeSubclass(self.theclass): def __new__(cls, *args, **kwargs): result = self.theclass.__new__(cls, *args, **kwargs) result.extra = 7 return result test_cases = [ ("now", "now", {}), ("utcnow", "utcnow", {}), ("now_utc", "now", { "tz": timezone.utc }), ("now_fixed", "now", { "tz": timezone(timedelta(hours=-5), "EST") }), ] for name, meth_name, kwargs in test_cases: with self.subTest(name): constr = getattr(DateTimeSubclass, meth_name) dt = constr(**kwargs) self.assertIsInstance(dt, DateTimeSubclass) self.assertEqual(dt.extra, 7)
def test_timestamp_aware(self): t = self.theclass(1970, 1, 1, tzinfo=timezone.utc) self.assertEqual(t.timestamp(), 0.0) t = self.theclass(1970, 1, 1, 1, 2, 3, 4, tzinfo=timezone.utc) self.assertEqual(t.timestamp(), 3600 + 2 * 60 + 3 + 4 * 1e-6) t = self.theclass(1970, 1, 1, 1, 2, 3, 4, tzinfo=timezone(timedelta(hours=-5), "EST")) self.assertEqual(t.timestamp(), 18000 + 3600 + 2 * 60 + 3 + 4 * 1e-6)
def test_fromisoformat_timezone(self): base_dt = self.theclass(2014, 12, 30, 12, 30, 45, 217456) tzoffsets = [ timedelta(hours=5), timedelta(hours=2), timedelta(hours=6, minutes=27), timedelta(hours=12, minutes=32, seconds=30), timedelta(hours=2, minutes=4, seconds=9, microseconds=123456), ] tzoffsets += [-1 * td for td in tzoffsets] tzinfos = [None, timezone.utc, timezone(timedelta(hours=0))] tzinfos += [timezone(td) for td in tzoffsets] for tzi in tzinfos: dt = base_dt.replace(tzinfo=tzi) dtstr = dt.isoformat() with self.subTest(tstr=dtstr): dt_rt = self.theclass.fromisoformat(dtstr) assert dt == dt_rt, dt_rt
def test_fromisoformat_subclass(self): class DateTimeSubclass(self.theclass): pass dt = DateTimeSubclass(2014, 12, 14, 9, 30, 45, 457390, tzinfo=timezone(timedelta(hours=10, minutes=45))) dt_rt = DateTimeSubclass.fromisoformat(dt.isoformat()) self.assertEqual(dt, dt_rt) self.assertIsInstance(dt_rt, DateTimeSubclass)
def test_more_strftime(self): # This tests fields beyond those tested by the TestDate.test_strftime. t = self.theclass(2004, 12, 31, 6, 22, 33, 47) self.assertEqual(t.strftime("%m %d %y %f %S %M %H %j"), "12 31 04 000047 33 22 06 366") for (s, us), z in [ ((33, 123), "33.000123"), ((33, 0), "33"), ]: tz = timezone(-timedelta(hours=2, seconds=s, microseconds=us)) t = t.replace(tzinfo=tz) self.assertEqual(t.strftime("%z"), "-0200" + z) # bpo-34482: Check that surrogates don't cause a crash. try: t.strftime("%y\ud800%m %H\ud800%M") except UnicodeEncodeError: pass
def test_astimezone(self): dt = self.theclass.now() f = FixedOffset(44, "0044") dt_utc = dt.replace(tzinfo=timezone(timedelta(hours=-4), "EDT")) self.assertEqual(dt.astimezone(), dt_utc) # naive self.assertRaises(TypeError, dt.astimezone, f, f) # too many args self.assertRaises(TypeError, dt.astimezone, dt) # arg wrong type dt_f = dt.replace(tzinfo=f) + timedelta(hours=4, minutes=44) self.assertEqual(dt.astimezone(f), dt_f) # naive self.assertEqual(dt.astimezone(tz=f), dt_f) # naive class Bogus(tzinfo): def utcoffset(self, dt): return None def dst(self, dt): return timedelta(0) bog = Bogus() self.assertRaises(ValueError, dt.astimezone, bog) # naive self.assertEqual(dt.replace(tzinfo=bog).astimezone(f), dt_f) class AlsoBogus(tzinfo): def utcoffset(self, dt): return timedelta(0) def dst(self, dt): return None alsobog = AlsoBogus() self.assertRaises(ValueError, dt.astimezone, alsobog) # also naive class Broken(tzinfo): def utcoffset(self, dt): return 1 def dst(self, dt): return 1 broken = Broken() dt_broken = dt.replace(tzinfo=broken) with self.assertRaises(TypeError): dt_broken.astimezone()