14adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao"""Test date/time type. 24adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 34adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoSee http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases 44adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao""" 54adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom __future__ import division 64adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport sys 74adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport pickle 84adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport cPickle 94adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport unittest 104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom test import test_support 124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom datetime import MINYEAR, MAXYEAR 144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom datetime import timedelta 154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom datetime import tzinfo 164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom datetime import time 174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom datetime import date, datetime 184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaopickle_choices = [(pickler, unpickler, proto) 204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for pickler in pickle, cPickle 214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for unpickler in pickle, cPickle 224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for proto in range(3)] 234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoassert len(pickle_choices) == 2*2*3 244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# An arbitrary collection of objects of non-datetime types, for testing 264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# mixed-type comparisons. 274adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoOTHERSTUFF = (10, 10L, 34.5, "abc", {}, [], ()) 284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao############################################################################# 314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# module tests 324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass TestModule(unittest.TestCase): 344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_constants(self): 364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import datetime 374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(datetime.MINYEAR, 1) 384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(datetime.MAXYEAR, 9999) 394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao############################################################################# 414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# tzinfo tests 424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass FixedOffset(tzinfo): 444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self, offset, name, dstoffset=42): 454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if isinstance(offset, int): 464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao offset = timedelta(minutes=offset) 474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if isinstance(dstoffset, int): 484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dstoffset = timedelta(minutes=dstoffset) 494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.__offset = offset 504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.__name = name 514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.__dstoffset = dstoffset 524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __repr__(self): 534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.__name.lower() 544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, dt): 554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.__offset 564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def tzname(self, dt): 574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.__name 584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def dst(self, dt): 594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.__dstoffset 604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass PicklableFixedOffset(FixedOffset): 624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self, offset=None, name=None, dstoffset=None): 634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao FixedOffset.__init__(self, offset, name, dstoffset) 644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass TestTZInfo(unittest.TestCase): 664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_non_abstractness(self): 684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # In order to allow subclasses to get pickled, the C implementation 694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # wasn't able to get away with having __init__ raise 704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # NotImplementedError. 714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao useless = tzinfo() 724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt = datetime.max 734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(NotImplementedError, useless.tzname, dt) 744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(NotImplementedError, useless.utcoffset, dt) 754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(NotImplementedError, useless.dst, dt) 764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_subclass_must_override(self): 784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class NotEnough(tzinfo): 794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self, offset, name): 804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.__offset = offset 814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.__name = name 824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(issubclass(NotEnough, tzinfo)) 834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ne = NotEnough(3, "NotByALongShot") 844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIsInstance(ne, tzinfo) 854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt = datetime.now() 874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(NotImplementedError, ne.tzname, dt) 884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(NotImplementedError, ne.utcoffset, dt) 894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(NotImplementedError, ne.dst, dt) 904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_normal(self): 924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fo = FixedOffset(3, "Three") 934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIsInstance(fo, tzinfo) 944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for dt in datetime.now(), None: 954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(fo.utcoffset(dt), timedelta(minutes=3)) 964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(fo.tzname(dt), "Three") 974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(fo.dst(dt), timedelta(minutes=42)) 984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_pickling_base(self): 1004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # There's no point to pickling tzinfo objects on their own (they 1014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # carry no data), but they need to be picklable anyway else 1024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # concrete subclasses can't be pickled. 1034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao orig = tzinfo.__new__(tzinfo) 1044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(type(orig) is tzinfo) 1054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for pickler, unpickler, proto in pickle_choices: 1064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao green = pickler.dumps(orig, proto) 1074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao derived = unpickler.loads(green) 1084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(type(derived) is tzinfo) 1094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_pickling_subclass(self): 1114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Make sure we can pickle/unpickle an instance of a subclass. 1124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao offset = timedelta(minutes=-300) 1134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao orig = PicklableFixedOffset(offset, 'cookie') 1144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIsInstance(orig, tzinfo) 1154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(type(orig) is PicklableFixedOffset) 1164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(orig.utcoffset(None), offset) 1174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(orig.tzname(None), 'cookie') 1184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for pickler, unpickler, proto in pickle_choices: 1194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao green = pickler.dumps(orig, proto) 1204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao derived = unpickler.loads(green) 1214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIsInstance(derived, tzinfo) 1224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(type(derived) is PicklableFixedOffset) 1234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(derived.utcoffset(None), offset) 1244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(derived.tzname(None), 'cookie') 1254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao############################################################################# 1274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Base clase for testing a particular aspect of timedelta, time, date and 1284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# datetime comparisons. 1294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass HarmlessMixedComparison: 1314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Test that __eq__ and __ne__ don't complain for mixed-type comparisons. 1324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Subclasses must define 'theclass', and theclass(1, 1, 1) must be a 1344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # legit constructor. 1354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_harmless_mixed_comparison(self): 1374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao me = self.theclass(1, 1, 1) 1384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertFalse(me == ()) 1404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(me != ()) 1414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertFalse(() == me) 1424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(() != me) 1434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIn(me, [1, 20L, [], me]) 1454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIn([], [me, 1, 20L, []]) 1464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_harmful_mixed_comparison(self): 1484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao me = self.theclass(1, 1, 1) 1494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: me < ()) 1514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: me <= ()) 1524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: me > ()) 1534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: me >= ()) 1544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: () < me) 1564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: () <= me) 1574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: () > me) 1584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: () >= me) 1594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, cmp, (), me) 1614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, cmp, me, ()) 1624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao############################################################################# 1644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# timedelta tests 1654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass TestTimeDelta(HarmlessMixedComparison, unittest.TestCase): 1674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao theclass = timedelta 1694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_constructor(self): 1714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq = self.assertEqual 1724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao td = timedelta 1734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Check keyword args to constructor 1754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(), td(weeks=0, days=0, hours=0, minutes=0, seconds=0, 1764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao milliseconds=0, microseconds=0)) 1774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(1), td(days=1)) 1784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(0, 1), td(seconds=1)) 1794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(0, 0, 1), td(microseconds=1)) 1804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(weeks=1), td(days=7)) 1814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(days=1), td(hours=24)) 1824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(hours=1), td(minutes=60)) 1834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(minutes=1), td(seconds=60)) 1844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(seconds=1), td(milliseconds=1000)) 1854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(milliseconds=1), td(microseconds=1000)) 1864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Check float args to constructor 1884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(weeks=1.0/7), td(days=1)) 1894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(days=1.0/24), td(hours=1)) 1904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(hours=1.0/60), td(minutes=1)) 1914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(minutes=1.0/60), td(seconds=1)) 1924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(seconds=0.001), td(milliseconds=1)) 1934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(milliseconds=0.001), td(microseconds=1)) 1944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_computations(self): 1964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq = self.assertEqual 1974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao td = timedelta 1984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao a = td(7) # One week 2004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao b = td(0, 60) # One minute 2014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao c = td(0, 0, 1000) # One millisecond 2024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(a+b+c, td(7, 60, 1000)) 2034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(a-b, td(6, 24*3600 - 60)) 2044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(-a, td(-7)) 2054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(+a, td(7)) 2064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(-b, td(-1, 24*3600 - 60)) 2074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(-c, td(-1, 24*3600 - 1, 999000)) 2084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(abs(a), a) 2094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(abs(-a), a) 2104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(6, 24*3600), a) 2114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(0, 0, 60*1000000), b) 2124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(a*10, td(70)) 2134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(a*10, 10*a) 2144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(a*10L, 10*a) 2154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(b*10, td(0, 600)) 2164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(10*b, td(0, 600)) 2174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(b*10L, td(0, 600)) 2184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(c*10, td(0, 0, 10000)) 2194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(10*c, td(0, 0, 10000)) 2204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(c*10L, td(0, 0, 10000)) 2214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(a*-1, -a) 2224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(b*-2, -b-b) 2234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(c*-2, -c+-c) 2244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(b*(60*24), (b*60)*24) 2254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(b*(60*24), (60*b)*24) 2264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(c*1000, td(0, 1)) 2274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(1000*c, td(0, 1)) 2284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(a//7, td(1)) 2294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(b//10, td(0, 6)) 2304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(c//1000, td(0, 0, 1)) 2314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(a//10, td(0, 7*24*360)) 2324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(a//3600000, td(0, 0, 7*24*1000)) 2334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Issue #11576 2354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(999999999, 86399, 999999) - td(999999999, 86399, 999998), 2364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao td(0, 0, 1)) 2374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(999999999, 1, 1) - td(999999999, 1, 0), 2384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao td(0, 0, 1)) 2394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_disallowed_computations(self): 2424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao a = timedelta(42) 2434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Add/sub ints, longs, floats should be illegal 2454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in 1, 1L, 1.0: 2464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: a+i) 2474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: a-i) 2484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: i+a) 2494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: i-a) 2504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Mul/div by float isn't supported. 2524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao x = 2.3 2534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: a*x) 2544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: x*a) 2554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: a/x) 2564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: x/a) 2574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: a // x) 2584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: x // a) 2594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Division of int by timedelta doesn't make sense. 2614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Division by zero doesn't make sense. 2624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for zero in 0, 0L: 2634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: zero // a) 2644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ZeroDivisionError, lambda: a // zero) 2654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_basic_attributes(self): 2674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao days, seconds, us = 1, 7, 31 2684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao td = timedelta(days, seconds, us) 2694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(td.days, days) 2704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(td.seconds, seconds) 2714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(td.microseconds, us) 2724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_total_seconds(self): 2744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao td = timedelta(days=365) 2754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(td.total_seconds(), 31536000.0) 2764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for total_seconds in [123456.789012, -123456.789012, 0.123456, 0, 1e6]: 2774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao td = timedelta(seconds=total_seconds) 2784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(td.total_seconds(), total_seconds) 2794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Issue8644: Test that td.total_seconds() has the same 2804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # accuracy as td / timedelta(seconds=1). 2814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for ms in [-1, -2, -123]: 2824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao td = timedelta(microseconds=ms) 2834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(td.total_seconds(), 2844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ((24*3600*td.days + td.seconds)*10**6 2854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao + td.microseconds)/10**6) 2864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_carries(self): 2884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = timedelta(days=100, 2894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao weeks=-7, 2904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao hours=-24*(100-49), 2914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao minutes=-3, 2924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao seconds=12, 2934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao microseconds=(3*60 - 12) * 1e6 + 1) 2944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = timedelta(microseconds=1) 2954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1, t2) 2964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_hash_equality(self): 2984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = timedelta(days=100, 2994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao weeks=-7, 3004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao hours=-24*(100-49), 3014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao minutes=-3, 3024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao seconds=12, 3034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao microseconds=(3*60 - 12) * 1000000) 3044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = timedelta() 3054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(hash(t1), hash(t2)) 3064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 += timedelta(weeks=7) 3084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 += timedelta(days=7*7) 3094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1, t2) 3104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(hash(t1), hash(t2)) 3114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = {t1: 1} 3134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d[t2] = 2 3144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(len(d), 1) 3154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d[t1], 2) 3164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_pickling(self): 3184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = 12, 34, 56 3194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao orig = timedelta(*args) 3204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for pickler, unpickler, proto in pickle_choices: 3214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao green = pickler.dumps(orig, proto) 3224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao derived = unpickler.loads(green) 3234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(orig, derived) 3244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_compare(self): 3264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = timedelta(2, 3, 4) 3274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = timedelta(2, 3, 4) 3284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 == t2) 3294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 <= t2) 3304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 >= t2) 3314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 != t2) 3324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 < t2) 3334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 > t2) 3344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cmp(t1, t2), 0) 3354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cmp(t2, t1), 0) 3364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for args in (3, 3, 3), (2, 4, 4), (2, 3, 5): 3384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = timedelta(*args) # this is larger than t1 3394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 < t2) 3404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t2 > t1) 3414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 <= t2) 3424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t2 >= t1) 3434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 != t2) 3444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t2 != t1) 3454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 == t2) 3464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t2 == t1) 3474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 > t2) 3484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t2 < t1) 3494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 >= t2) 3504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t2 <= t1) 3514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cmp(t1, t2), -1) 3524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cmp(t2, t1), 1) 3534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for badarg in OTHERSTUFF: 3554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1 == badarg, False) 3564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1 != badarg, True) 3574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(badarg == t1, False) 3584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(badarg != t1, True) 3594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: t1 <= badarg) 3614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: t1 < badarg) 3624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: t1 > badarg) 3634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: t1 >= badarg) 3644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: badarg <= t1) 3654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: badarg < t1) 3664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: badarg > t1) 3674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: badarg >= t1) 3684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_str(self): 3704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao td = timedelta 3714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq = self.assertEqual 3724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(str(td(1)), "1 day, 0:00:00") 3744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(str(td(-1)), "-1 day, 0:00:00") 3754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(str(td(2)), "2 days, 0:00:00") 3764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(str(td(-2)), "-2 days, 0:00:00") 3774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(str(td(hours=12, minutes=58, seconds=59)), "12:58:59") 3794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(str(td(hours=2, minutes=3, seconds=4)), "2:03:04") 3804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(str(td(weeks=-30, hours=23, minutes=12, seconds=34)), 3814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "-210 days, 23:12:34") 3824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(str(td(milliseconds=1)), "0:00:00.001000") 3844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(str(td(microseconds=3)), "0:00:00.000003") 3854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(str(td(days=999999999, hours=23, minutes=59, seconds=59, 3874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao microseconds=999999)), 3884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "999999999 days, 23:59:59.999999") 3894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_roundtrip(self): 3914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for td in (timedelta(days=999999999, hours=23, minutes=59, 3924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao seconds=59, microseconds=999999), 3934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao timedelta(days=-999999999), 3944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao timedelta(days=1, seconds=2, microseconds=3)): 3954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify td -> string -> td identity. 3974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao s = repr(td) 3984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(s.startswith('datetime.')) 3994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao s = s[9:] 4004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao td2 = eval(s) 4014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(td, td2) 4024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify identity via reconstructing from pieces. 4044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao td2 = timedelta(td.days, td.seconds, td.microseconds) 4054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(td, td2) 4064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_resolution_info(self): 4084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIsInstance(timedelta.min, timedelta) 4094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIsInstance(timedelta.max, timedelta) 4104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIsInstance(timedelta.resolution, timedelta) 4114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(timedelta.max > timedelta.min) 4124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(timedelta.min, timedelta(-999999999)) 4134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(timedelta.max, timedelta(999999999, 24*3600-1, 1e6-1)) 4144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(timedelta.resolution, timedelta(0, 0, 1)) 4154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_overflow(self): 4174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao tiny = timedelta.resolution 4184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao td = timedelta.min + tiny 4204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao td -= tiny # no problem 4214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(OverflowError, td.__sub__, tiny) 4224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(OverflowError, td.__add__, -tiny) 4234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao td = timedelta.max - tiny 4254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao td += tiny # no problem 4264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(OverflowError, td.__add__, tiny) 4274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(OverflowError, td.__sub__, -tiny) 4284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(OverflowError, lambda: -timedelta.max) 4304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_microsecond_rounding(self): 4324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao td = timedelta 4334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq = self.assertEqual 4344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Single-field rounding. 4364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(milliseconds=0.4/1000), td(0)) # rounds to 0 4374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(milliseconds=-0.4/1000), td(0)) # rounds to 0 4384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(milliseconds=0.6/1000), td(microseconds=1)) 4394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(milliseconds=-0.6/1000), td(microseconds=-1)) 4404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Rounding due to contributions from more than one field. 4424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao us_per_hour = 3600e6 4434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao us_per_day = us_per_hour * 24 4444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(days=.4/us_per_day), td(0)) 4454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(hours=.2/us_per_hour), td(0)) 4464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(days=.4/us_per_day, hours=.2/us_per_hour), td(microseconds=1)) 4474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(days=-.4/us_per_day), td(0)) 4494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(hours=-.2/us_per_hour), td(0)) 4504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao eq(td(days=-.4/us_per_day, hours=-.2/us_per_hour), td(microseconds=-1)) 4514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_massive_normalization(self): 4534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao td = timedelta(microseconds=-1) 4544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual((td.days, td.seconds, td.microseconds), 4554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (-1, 24*3600-1, 999999)) 4564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_bool(self): 4584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(timedelta(1)) 4594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(timedelta(0, 1)) 4604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(timedelta(0, 0, 1)) 4614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(timedelta(microseconds=1)) 4624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not timedelta(0)) 4634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_subclass_timedelta(self): 4654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class T(timedelta): 4674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao @staticmethod 4684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def from_td(td): 4694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return T(td.days, td.seconds, td.microseconds) 4704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def as_hours(self): 4724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao sum = (self.days * 24 + 4734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.seconds / 3600.0 + 4744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.microseconds / 3600e6) 4754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return round(sum) 4764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = T(days=1) 4784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(type(t1) is T) 4794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1.as_hours(), 24) 4804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = T(days=-1, seconds=-3600) 4824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(type(t2) is T) 4834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t2.as_hours(), -25) 4844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t3 = t1 + t2 4864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(type(t3) is timedelta) 4874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t4 = T.from_td(t3) 4884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(type(t4) is T) 4894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t3.days, t4.days) 4904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t3.seconds, t4.seconds) 4914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t3.microseconds, t4.microseconds) 4924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(str(t3), str(t4)) 4934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t4.as_hours(), -1) 4944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao############################################################################# 4964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# date tests 4974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass TestDateOnly(unittest.TestCase): 4994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Tests here won't pass if also run on datetime objects, so don't 5004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # subclass this to test datetimes too. 5014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_delta_non_days_ignored(self): 5034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt = date(2000, 1, 2) 5044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao delta = timedelta(days=1, hours=2, minutes=3, seconds=4, 5054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao microseconds=5) 5064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao days = timedelta(delta.days) 5074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(days, timedelta(1)) 5084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt2 = dt + delta 5104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2, dt + days) 5114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt2 = delta + dt 5134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2, dt + days) 5144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt2 = dt - delta 5164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2, dt - days) 5174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao delta = -delta 5194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao days = timedelta(delta.days) 5204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(days, timedelta(-2)) 5214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt2 = dt + delta 5234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2, dt + days) 5244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt2 = delta + dt 5264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2, dt + days) 5274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt2 = dt - delta 5294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2, dt - days) 5304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass SubclassDate(date): 5324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao sub_var = 1 5334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass TestDate(HarmlessMixedComparison, unittest.TestCase): 5354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Tests here should pass for both dates and datetimes, except for a 5364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # few tests that TestDateTime overrides. 5374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao theclass = date 5394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_basic_attributes(self): 5414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt = self.theclass(2002, 3, 1) 5424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.year, 2002) 5434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.month, 3) 5444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.day, 1) 5454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_roundtrip(self): 5474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for dt in (self.theclass(1, 2, 3), 5484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass.today()): 5494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify dt -> string -> date identity. 5504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao s = repr(dt) 5514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(s.startswith('datetime.')) 5524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao s = s[9:] 5534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt2 = eval(s) 5544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt, dt2) 5554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify identity via reconstructing from pieces. 5574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt2 = self.theclass(dt.year, dt.month, dt.day) 5584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt, dt2) 5594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_ordinal_conversions(self): 5614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Check some fixed values. 5624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for y, m, d, n in [(1, 1, 1, 1), # calendar origin 5634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (1, 12, 31, 365), 5644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (2, 1, 1, 366), 5654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # first example from "Calendrical Calculations" 5664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (1945, 11, 12, 710347)]: 5674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass(y, m, d) 5684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(n, d.toordinal()) 5694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fromord = self.theclass.fromordinal(n) 5704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d, fromord) 5714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if hasattr(fromord, "hour"): 5724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # if we're checking something fancier than a date, verify 5734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # the extra fields have been zeroed out 5744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(fromord.hour, 0) 5754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(fromord.minute, 0) 5764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(fromord.second, 0) 5774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(fromord.microsecond, 0) 5784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Check first and last days of year spottily across the whole 5804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # range of years supported. 5814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for year in xrange(MINYEAR, MAXYEAR+1, 7): 5824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify (year, 1, 1) -> ordinal -> y, m, d is identity. 5834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass(year, 1, 1) 5844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao n = d.toordinal() 5854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d2 = self.theclass.fromordinal(n) 5864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d, d2) 5874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify that moving back a day gets to the end of year-1. 5884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if year > 1: 5894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass.fromordinal(n-1) 5904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d2 = self.theclass(year-1, 12, 31) 5914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d, d2) 5924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d2.toordinal(), n-1) 5934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Test every day in a leap-year and a non-leap year. 5954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dim = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] 5964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for year, isleap in (2000, True), (2002, False): 5974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao n = self.theclass(year, 1, 1).toordinal() 5984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for month, maxday in zip(range(1, 13), dim): 5994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if month == 2 and isleap: 6004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao maxday += 1 6014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for day in range(1, maxday+1): 6024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass(year, month, day) 6034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d.toordinal(), n) 6044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d, self.theclass.fromordinal(n)) 6054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao n += 1 6064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_extreme_ordinals(self): 6084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao a = self.theclass.min 6094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao a = self.theclass(a.year, a.month, a.day) # get rid of time parts 6104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao aord = a.toordinal() 6114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao b = a.fromordinal(aord) 6124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a, b) 6134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, lambda: a.fromordinal(aord - 1)) 6154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao b = a + timedelta(days=1) 6174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(b.toordinal(), aord + 1) 6184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(b, self.theclass.fromordinal(aord + 1)) 6194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao a = self.theclass.max 6214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao a = self.theclass(a.year, a.month, a.day) # get rid of time parts 6224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao aord = a.toordinal() 6234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao b = a.fromordinal(aord) 6244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a, b) 6254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, lambda: a.fromordinal(aord + 1)) 6274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao b = a - timedelta(days=1) 6294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(b.toordinal(), aord - 1) 6304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(b, self.theclass.fromordinal(aord - 1)) 6314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_bad_constructor_arguments(self): 6334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # bad years 6344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(MINYEAR, 1, 1) # no exception 6354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(MAXYEAR, 1, 1) # no exception 6364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, MINYEAR-1, 1, 1) 6374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, MAXYEAR+1, 1, 1) 6384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # bad months 6394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(2000, 1, 1) # no exception 6404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(2000, 12, 1) # no exception 6414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 2000, 0, 1) 6424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 2000, 13, 1) 6434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # bad days 6444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(2000, 2, 29) # no exception 6454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(2004, 2, 29) # no exception 6464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(2400, 2, 29) # no exception 6474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 2000, 2, 30) 6484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 2001, 2, 29) 6494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 2100, 2, 29) 6504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 1900, 2, 29) 6514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 2000, 1, 0) 6524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 2000, 1, 32) 6534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_hash_equality(self): 6554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass(2000, 12, 31) 6564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # same thing 6574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao e = self.theclass(2000, 12, 31) 6584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d, e) 6594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(hash(d), hash(e)) 6604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dic = {d: 1} 6624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dic[e] = 2 6634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(len(dic), 1) 6644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dic[d], 2) 6654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dic[e], 2) 6664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass(2001, 1, 1) 6684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # same thing 6694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao e = self.theclass(2001, 1, 1) 6704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d, e) 6714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(hash(d), hash(e)) 6724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dic = {d: 1} 6744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dic[e] = 2 6754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(len(dic), 1) 6764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dic[d], 2) 6774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dic[e], 2) 6784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_computations(self): 6804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao a = self.theclass(2002, 1, 31) 6814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao b = self.theclass(1956, 1, 31) 6824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao diff = a-b 6844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(diff.days, 46*365 + len(range(1956, 2002, 4))) 6854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(diff.seconds, 0) 6864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(diff.microseconds, 0) 6874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 6884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao day = timedelta(1) 6894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao week = timedelta(7) 6904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao a = self.theclass(2002, 3, 2) 6914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a + day, self.theclass(2002, 3, 3)) 6924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(day + a, self.theclass(2002, 3, 3)) 6934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - day, self.theclass(2002, 3, 1)) 6944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(-day + a, self.theclass(2002, 3, 1)) 6954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a + week, self.theclass(2002, 3, 9)) 6964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - week, self.theclass(2002, 2, 23)) 6974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a + 52*week, self.theclass(2003, 3, 1)) 6984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - 52*week, self.theclass(2001, 3, 3)) 6994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual((a + week) - a, week) 7004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual((a + day) - a, day) 7014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual((a - week) - a, -week) 7024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual((a - day) - a, -day) 7034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - (a + week), -week) 7044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - (a + day), -day) 7054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - (a - week), week) 7064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - (a - day), day) 7074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Add/sub ints, longs, floats should be illegal 7094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in 1, 1L, 1.0: 7104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: a+i) 7114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: a-i) 7124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: i+a) 7134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: i-a) 7144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # delta - date is senseless. 7164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: day - a) 7174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # mixing date and (delta or date) via * or // is senseless 7184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: day * a) 7194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: a * day) 7204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: day // a) 7214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: a // day) 7224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: a * a) 7234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: a // a) 7244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # date + date is senseless 7254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: a + a) 7264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_overflow(self): 7284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao tiny = self.theclass.resolution 7294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for delta in [tiny, timedelta(1), timedelta(2)]: 7314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt = self.theclass.min + delta 7324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt -= delta # no problem 7334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(OverflowError, dt.__sub__, delta) 7344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(OverflowError, dt.__add__, -delta) 7354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt = self.theclass.max - delta 7374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt += delta # no problem 7384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(OverflowError, dt.__add__, delta) 7394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(OverflowError, dt.__sub__, -delta) 7404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_fromtimestamp(self): 7424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import time 7434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Try an arbitrary fixed value. 7454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao year, month, day = 1999, 9, 19 7464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ts = time.mktime((year, month, day, 0, 0, 0, 0, 0, -1)) 7474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass.fromtimestamp(ts) 7484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d.year, year) 7494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d.month, month) 7504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d.day, day) 7514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_insane_fromtimestamp(self): 7534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # It's possible that some platform maps time_t to double, 7544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # and that this test will fail there. This test should 7554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # exempt such platforms (provided they return reasonable 7564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # results!). 7574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for insane in -1e200, 1e200: 7584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass.fromtimestamp, 7594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao insane) 7604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_today(self): 7624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import time 7634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # We claim that today() is like fromtimestamp(time.time()), so 7654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # prove it. 7664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for dummy in range(3): 7674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao today = self.theclass.today() 7684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ts = time.time() 7694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao todayagain = self.theclass.fromtimestamp(ts) 7704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if today == todayagain: 7714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao break 7724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # There are several legit reasons that could fail: 7734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # 1. It recently became midnight, between the today() and the 7744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # time() calls. 7754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # 2. The platform time() has such fine resolution that we'll 7764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # never get the same value twice. 7774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # 3. The platform time() has poor resolution, and we just 7784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # happened to call today() right before a resolution quantum 7794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # boundary. 7804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # 4. The system clock got fiddled between calls. 7814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # In any case, wait a little while and try again. 7824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao time.sleep(0.1) 7834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # It worked or it didn't. If it didn't, assume it's reason #2, and 7854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # let the test pass if they're within half a second of each other. 7864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(today == todayagain or 7874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao abs(todayagain - today) < timedelta(seconds=0.5)) 7884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_weekday(self): 7904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in range(7): 7914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # March 4, 2002 is a Monday 7924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(self.theclass(2002, 3, 4+i).weekday(), i) 7934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(self.theclass(2002, 3, 4+i).isoweekday(), i+1) 7944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # January 2, 1956 is a Monday 7954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(self.theclass(1956, 1, 2+i).weekday(), i) 7964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(self.theclass(1956, 1, 2+i).isoweekday(), i+1) 7974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 7984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_isocalendar(self): 7994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Check examples from 8004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm 8014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in range(7): 8024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass(2003, 12, 22+i) 8034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d.isocalendar(), (2003, 52, i+1)) 8044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass(2003, 12, 29) + timedelta(i) 8054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d.isocalendar(), (2004, 1, i+1)) 8064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass(2004, 1, 5+i) 8074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d.isocalendar(), (2004, 2, i+1)) 8084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass(2009, 12, 21+i) 8094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d.isocalendar(), (2009, 52, i+1)) 8104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass(2009, 12, 28) + timedelta(i) 8114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d.isocalendar(), (2009, 53, i+1)) 8124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass(2010, 1, 4+i) 8134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d.isocalendar(), (2010, 1, i+1)) 8144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_iso_long_years(self): 8164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Calculate long ISO years and compare to table from 8174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm 8184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ISO_LONG_YEARS_TABLE = """ 8194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4 32 60 88 8204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 9 37 65 93 8214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 15 43 71 99 8224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 20 48 76 8234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 26 54 82 8244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 105 133 161 189 8264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 111 139 167 195 8274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 116 144 172 8284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 122 150 178 8294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 128 156 184 8304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 201 229 257 285 8324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 207 235 263 291 8334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 212 240 268 296 8344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 218 246 274 8354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 224 252 280 8364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 303 331 359 387 8384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 308 336 364 392 8394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 314 342 370 398 8404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 320 348 376 8414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 325 353 381 8424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao """ 8434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao iso_long_years = map(int, ISO_LONG_YEARS_TABLE.split()) 8444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao iso_long_years.sort() 8454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao L = [] 8464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in range(400): 8474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass(2000+i, 12, 31) 8484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d1 = self.theclass(1600+i, 12, 31) 8494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d.isocalendar()[1:], d1.isocalendar()[1:]) 8504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if d.isocalendar()[1] == 53: 8514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao L.append(i) 8524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(L, iso_long_years) 8534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_isoformat(self): 8554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(2, 3, 2) 8564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(), "0002-03-02") 8574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_ctime(self): 8594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(2002, 3, 2) 8604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.ctime(), "Sat Mar 2 00:00:00 2002") 8614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_strftime(self): 8634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(2005, 3, 2) 8644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.strftime("m:%m d:%d y:%y"), "m:03 d:02 y:05") 8654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.strftime(""), "") # SF bug #761337 8664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.strftime('x'*1000), 'x'*1000) # SF bug #1556784 8674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, t.strftime) # needs an arg 8694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, t.strftime, "one", "two") # too many args 8704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, t.strftime, 42) # arg wrong type 8714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # test that unicode input is allowed (issue 2782) 8734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.strftime(u"%m"), "03") 8744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # A naive object replaces %z and %Z w/ empty strings. 8764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''") 8774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao #make sure that invalid format specifiers are handled correctly 8794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao #self.assertRaises(ValueError, t.strftime, "%e") 8804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao #self.assertRaises(ValueError, t.strftime, "%") 8814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao #self.assertRaises(ValueError, t.strftime, "%#") 8824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao #oh well, some systems just ignore those invalid ones. 8844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao #at least, excercise them to make sure that no crashes 8854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao #are generated 8864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for f in ["%e", "%", "%#"]: 8874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 8884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t.strftime(f) 8894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except ValueError: 8904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pass 8914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao #check that this standard extension works 8934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t.strftime("%f") 8944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 8964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_format(self): 8974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt = self.theclass(2007, 9, 10) 8984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.__format__(''), str(dt)) 8994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 9004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # check that a derived class's __str__() gets called 9014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class A(self.theclass): 9024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __str__(self): 9034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return 'A' 9044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao a = A(2007, 9, 10) 9054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a.__format__(''), 'A') 9064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 9074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # check that a derived class's strftime gets called 9084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class B(self.theclass): 9094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def strftime(self, format_spec): 9104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return 'B' 9114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao b = B(2007, 9, 10) 9124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(b.__format__(''), str(dt)) 9134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 9144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for fmt in ["m:%m d:%d y:%y", 9154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "m:%m d:%d y:%y H:%H M:%M S:%S", 9164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "%z %Z", 9174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ]: 9184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.__format__(fmt), dt.strftime(fmt)) 9194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a.__format__(fmt), dt.strftime(fmt)) 9204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(b.__format__(fmt), 'B') 9214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 9224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_resolution_info(self): 9234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIsInstance(self.theclass.min, self.theclass) 9244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIsInstance(self.theclass.max, self.theclass) 9254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIsInstance(self.theclass.resolution, timedelta) 9264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(self.theclass.max > self.theclass.min) 9274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 9284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_extreme_timedelta(self): 9294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao big = self.theclass.max - self.theclass.min 9304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # 3652058 days, 23 hours, 59 minutes, 59 seconds, 999999 microseconds 9314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao n = (big.days*24*3600 + big.seconds)*1000000 + big.microseconds 9324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # n == 315537897599999999 ~= 2**58.13 9334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao justasbig = timedelta(0, 0, n) 9344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(big, justasbig) 9354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(self.theclass.min + big, self.theclass.max) 9364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(self.theclass.max - big, self.theclass.min) 9374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 9384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_timetuple(self): 9394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in range(7): 9404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # January 2, 1956 is a Monday (0) 9414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass(1956, 1, 2+i) 9424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = d.timetuple() 9434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t, (1956, 1, 2+i, 0, 0, 0, i, 2+i, -1)) 9444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # February 1, 1956 is a Wednesday (2) 9454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass(1956, 2, 1+i) 9464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = d.timetuple() 9474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t, (1956, 2, 1+i, 0, 0, 0, (2+i)%7, 32+i, -1)) 9484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # March 1, 1956 is a Thursday (3), and is the 31+29+1 = 61st day 9494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # of the year. 9504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass(1956, 3, 1+i) 9514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = d.timetuple() 9524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t, (1956, 3, 1+i, 0, 0, 0, (3+i)%7, 61+i, -1)) 9534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_year, 1956) 9544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_mon, 3) 9554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_mday, 1+i) 9564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_hour, 0) 9574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_min, 0) 9584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_sec, 0) 9594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_wday, (3+i)%7) 9604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_yday, 61+i) 9614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_isdst, -1) 9624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 9634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_pickling(self): 9644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = 6, 7, 23 9654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao orig = self.theclass(*args) 9664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for pickler, unpickler, proto in pickle_choices: 9674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao green = pickler.dumps(orig, proto) 9684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao derived = unpickler.loads(green) 9694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(orig, derived) 9704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 9714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_compare(self): 9724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = self.theclass(2, 3, 4) 9734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = self.theclass(2, 3, 4) 9744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 == t2) 9754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 <= t2) 9764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 >= t2) 9774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 != t2) 9784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 < t2) 9794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 > t2) 9804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cmp(t1, t2), 0) 9814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cmp(t2, t1), 0) 9824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 9834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for args in (3, 3, 3), (2, 4, 4), (2, 3, 5): 9844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = self.theclass(*args) # this is larger than t1 9854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 < t2) 9864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t2 > t1) 9874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 <= t2) 9884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t2 >= t1) 9894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 != t2) 9904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t2 != t1) 9914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 == t2) 9924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t2 == t1) 9934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 > t2) 9944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t2 < t1) 9954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 >= t2) 9964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t2 <= t1) 9974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cmp(t1, t2), -1) 9984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cmp(t2, t1), 1) 9994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for badarg in OTHERSTUFF: 10014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1 == badarg, False) 10024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1 != badarg, True) 10034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(badarg == t1, False) 10044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(badarg != t1, True) 10054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: t1 < badarg) 10074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: t1 > badarg) 10084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: t1 >= badarg) 10094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: badarg <= t1) 10104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: badarg < t1) 10114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: badarg > t1) 10124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: badarg >= t1) 10134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_mixed_compare(self): 10154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao our = self.theclass(2000, 4, 5) 10164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, cmp, our, 1) 10174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, cmp, 1, our) 10184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class AnotherDateTimeClass(object): 10204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __cmp__(self, other): 10214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Return "equal" so calling this can't be confused with 10224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # compare-by-address (which never says "equal" for distinct 10234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # objects). 10244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return 0 10254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao __hash__ = None # Silence Py3k warning 10264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # This still errors, because date and datetime comparison raise 10284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # TypeError instead of NotImplemented when they don't know what to 10294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # do, in order to stop comparison from falling back to the default 10304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # compare-by-address. 10314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao their = AnotherDateTimeClass() 10324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, cmp, our, their) 10334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Oops: The next stab raises TypeError in the C implementation, 10344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # but not in the Python implementation of datetime. The difference 10354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # is due to that the Python implementation defines __cmp__ but 10364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # the C implementation defines tp_richcompare. This is more pain 10374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # to fix than it's worth, so commenting out the test. 10384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # self.assertEqual(cmp(their, our), 0) 10394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # But date and datetime comparison return NotImplemented instead if the 10414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # other object has a timetuple attr. This gives the other object a 10424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # chance to do the comparison. 10434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class Comparable(AnotherDateTimeClass): 10444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def timetuple(self): 10454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return () 10464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao their = Comparable() 10484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cmp(our, their), 0) 10494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cmp(their, our), 0) 10504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(our == their) 10514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(their == our) 10524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_bool(self): 10544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # All dates are considered true. 10554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(self.theclass.min) 10564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(self.theclass.max) 10574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_strftime_out_of_range(self): 10594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # For nasty technical reasons, we can't handle years before 1900. 10604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls = self.theclass 10614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cls(1900, 1, 1).strftime("%Y"), "1900") 10624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for y in 1, 49, 51, 99, 100, 1000, 1899: 10634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, cls(y, 1, 1).strftime, "%Y") 10644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_replace(self): 10664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls = self.theclass 10674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = [1, 2, 3] 10684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = cls(*args) 10694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(base, base.replace()) 10704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao i = 0 10724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for name, newval in (("year", 2), 10734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("month", 3), 10744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("day", 4)): 10754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newargs = args[:] 10764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newargs[i] = newval 10774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = cls(*newargs) 10784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = base.replace(**{name: newval}) 10794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected, got) 10804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao i += 1 10814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Out of bounds. 10834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = cls(2000, 2, 29) 10844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, base.replace, year=2001) 10854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_subclass_date(self): 10874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class C(self.theclass): 10894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao theAnswer = 42 10904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __new__(cls, *args, **kws): 10924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao temp = kws.copy() 10934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao extra = temp.pop('extra') 10944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao result = self.theclass.__new__(cls, *args, **temp) 10954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao result.extra = extra 10964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return result 10974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 10984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def newmeth(self, start): 10994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return start + self.year + self.month 11004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = 2003, 4, 14 11024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt1 = self.theclass(*args) 11044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt2 = C(*args, **{'extra': 7}) 11054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2.__class__, C) 11074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2.theAnswer, 42) 11084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2.extra, 7) 11094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt1.toordinal(), dt2.toordinal()) 11104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2.newmeth(-7), dt1.year + dt1.month - 7) 11114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_pickling_subclass_date(self): 11134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = 6, 7, 23 11154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao orig = SubclassDate(*args) 11164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for pickler, unpickler, proto in pickle_choices: 11174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao green = pickler.dumps(orig, proto) 11184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao derived = unpickler.loads(green) 11194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(orig, derived) 11204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_backdoor_resistance(self): 11224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # For fast unpickling, the constructor accepts a pickle string. 11234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # This is a low-overhead backdoor. A user can (by intent or 11244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # mistake) pass a string directly, which (if it's the right length) 11254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # will get treated like a pickle, and bypass the normal sanity 11264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # checks in the constructor. This can create insane objects. 11274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # The constructor doesn't want to burn the time to validate all 11284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # fields, but does check the month field. This stops, e.g., 11294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # datetime.datetime('1995-03-25') from yielding an insane object. 11304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = '1995-03-25' 11314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if not issubclass(self.theclass, datetime): 11324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = base[:4] 11334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for month_byte in '9', chr(0), chr(13), '\xff': 11344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, self.theclass, 11354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base[:2] + month_byte + base[3:]) 11364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for ord_byte in range(1, 13): 11374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # This shouldn't blow up because of the month byte alone. If 11384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # the implementation changes to do more-careful checking, it may 11394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # blow up because other fields are insane. 11404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(base[:2] + chr(ord_byte) + base[3:]) 11414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao############################################################################# 11434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# datetime tests 11444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass SubclassDatetime(datetime): 11464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao sub_var = 1 11474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass TestDateTime(TestDate): 11494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao theclass = datetime 11514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_basic_attributes(self): 11534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt = self.theclass(2002, 3, 1, 12, 0) 11544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.year, 2002) 11554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.month, 3) 11564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.day, 1) 11574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.hour, 12) 11584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.minute, 0) 11594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.second, 0) 11604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.microsecond, 0) 11614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_basic_attributes_nonzero(self): 11634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Make sure all attributes are non-zero so bugs in 11644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # bit-shifting access show up. 11654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt = self.theclass(2002, 3, 1, 12, 59, 59, 8000) 11664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.year, 2002) 11674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.month, 3) 11684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.day, 1) 11694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.hour, 12) 11704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.minute, 59) 11714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.second, 59) 11724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.microsecond, 8000) 11734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_roundtrip(self): 11754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for dt in (self.theclass(1, 2, 3, 4, 5, 6, 7), 11764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass.now()): 11774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify dt -> string -> datetime identity. 11784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao s = repr(dt) 11794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(s.startswith('datetime.')) 11804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao s = s[9:] 11814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt2 = eval(s) 11824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt, dt2) 11834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify identity via reconstructing from pieces. 11854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt2 = self.theclass(dt.year, dt.month, dt.day, 11864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt.hour, dt.minute, dt.second, 11874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt.microsecond) 11884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt, dt2) 11894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_isoformat(self): 11914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(2, 3, 2, 4, 5, 1, 123) 11924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(), "0002-03-02T04:05:01.000123") 11934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat('T'), "0002-03-02T04:05:01.000123") 11944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(' '), "0002-03-02 04:05:01.000123") 11954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat('\x00'), "0002-03-02\x0004:05:01.000123") 11964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # str is ISO format with the separator forced to a blank. 11974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(str(t), "0002-03-02 04:05:01.000123") 11984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 11994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(2, 3, 2) 12004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(), "0002-03-02T00:00:00") 12014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat('T'), "0002-03-02T00:00:00") 12024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(' '), "0002-03-02 00:00:00") 12034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # str is ISO format with the separator forced to a blank. 12044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(str(t), "0002-03-02 00:00:00") 12054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_format(self): 12074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt = self.theclass(2007, 9, 10, 4, 5, 1, 123) 12084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.__format__(''), str(dt)) 12094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # check that a derived class's __str__() gets called 12114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class A(self.theclass): 12124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __str__(self): 12134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return 'A' 12144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao a = A(2007, 9, 10, 4, 5, 1, 123) 12154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a.__format__(''), 'A') 12164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # check that a derived class's strftime gets called 12184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class B(self.theclass): 12194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def strftime(self, format_spec): 12204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return 'B' 12214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao b = B(2007, 9, 10, 4, 5, 1, 123) 12224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(b.__format__(''), str(dt)) 12234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for fmt in ["m:%m d:%d y:%y", 12254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "m:%m d:%d y:%y H:%H M:%M S:%S", 12264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "%z %Z", 12274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ]: 12284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.__format__(fmt), dt.strftime(fmt)) 12294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a.__format__(fmt), dt.strftime(fmt)) 12304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(b.__format__(fmt), 'B') 12314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_more_ctime(self): 12334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Test fields that TestDate doesn't touch. 12344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import time 12354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(2002, 3, 2, 18, 3, 5, 123) 12374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.ctime(), "Sat Mar 2 18:03:05 2002") 12384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Oops! The next line fails on Win2K under MSVC 6, so it's commented 12394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # out. The difference is that t.ctime() produces " 2" for the day, 12404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # but platform ctime() produces "02" for the day. According to 12414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # C99, t.ctime() is correct here. 12424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # self.assertEqual(t.ctime(), time.ctime(time.mktime(t.timetuple()))) 12434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # So test a case where that difference doesn't matter. 12454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(2002, 3, 22, 18, 3, 5, 123) 12464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.ctime(), time.ctime(time.mktime(t.timetuple()))) 12474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_tz_independent_comparing(self): 12494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt1 = self.theclass(2002, 3, 1, 9, 0, 0) 12504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt2 = self.theclass(2002, 3, 1, 10, 0, 0) 12514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt3 = self.theclass(2002, 3, 1, 9, 0, 0) 12524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt1, dt3) 12534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(dt2 > dt3) 12544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Make sure comparison doesn't forget microseconds, and isn't done 12564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # via comparing a float timestamp (an IEEE double doesn't have enough 12574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # precision to span microsecond resolution across years 1 thru 9999, 12584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # so comparing via timestamp necessarily calls some distinct values 12594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # equal). 12604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt1 = self.theclass(MAXYEAR, 12, 31, 23, 59, 59, 999998) 12614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao us = timedelta(microseconds=1) 12624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt2 = dt1 + us 12634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2 - dt1, us) 12644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(dt1 < dt2) 12654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_strftime_with_bad_tzname_replace(self): 12674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # verify ok if tzinfo.tzname().replace() returns a non-string 12684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class MyTzInfo(FixedOffset): 12694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def tzname(self, dt): 12704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class MyStr(str): 12714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def replace(self, *args): 12724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return None 12734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return MyStr('name') 12744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(2005, 3, 2, 0, 0, 0, 0, MyTzInfo(3, 'name')) 12754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, t.strftime, '%Z') 12764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 12774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_bad_constructor_arguments(self): 12784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # bad years 12794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(MINYEAR, 1, 1) # no exception 12804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(MAXYEAR, 1, 1) # no exception 12814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, MINYEAR-1, 1, 1) 12824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, MAXYEAR+1, 1, 1) 12834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # bad months 12844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(2000, 1, 1) # no exception 12854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(2000, 12, 1) # no exception 12864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 2000, 0, 1) 12874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 2000, 13, 1) 12884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # bad days 12894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(2000, 2, 29) # no exception 12904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(2004, 2, 29) # no exception 12914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(2400, 2, 29) # no exception 12924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 2000, 2, 30) 12934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 2001, 2, 29) 12944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 2100, 2, 29) 12954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 1900, 2, 29) 12964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 2000, 1, 0) 12974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 2000, 1, 32) 12984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # bad hours 12994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(2000, 1, 31, 0) # no exception 13004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(2000, 1, 31, 23) # no exception 13014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 2000, 1, 31, -1) 13024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 2000, 1, 31, 24) 13034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # bad minutes 13044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(2000, 1, 31, 23, 0) # no exception 13054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(2000, 1, 31, 23, 59) # no exception 13064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 2000, 1, 31, 23, -1) 13074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 2000, 1, 31, 23, 60) 13084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # bad seconds 13094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(2000, 1, 31, 23, 59, 0) # no exception 13104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(2000, 1, 31, 23, 59, 59) # no exception 13114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 2000, 1, 31, 23, 59, -1) 13124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 2000, 1, 31, 23, 59, 60) 13134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # bad microseconds 13144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(2000, 1, 31, 23, 59, 59, 0) # no exception 13154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(2000, 1, 31, 23, 59, 59, 999999) # no exception 13164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 13174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2000, 1, 31, 23, 59, 59, -1) 13184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 13194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2000, 1, 31, 23, 59, 59, 13204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1000000) 13214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 13224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_hash_equality(self): 13234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass(2000, 12, 31, 23, 30, 17) 13244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao e = self.theclass(2000, 12, 31, 23, 30, 17) 13254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d, e) 13264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(hash(d), hash(e)) 13274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 13284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dic = {d: 1} 13294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dic[e] = 2 13304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(len(dic), 1) 13314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dic[d], 2) 13324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dic[e], 2) 13334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 13344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass(2001, 1, 1, 0, 5, 17) 13354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao e = self.theclass(2001, 1, 1, 0, 5, 17) 13364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d, e) 13374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(hash(d), hash(e)) 13384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 13394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dic = {d: 1} 13404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dic[e] = 2 13414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(len(dic), 1) 13424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dic[d], 2) 13434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dic[e], 2) 13444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 13454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_computations(self): 13464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao a = self.theclass(2002, 1, 31) 13474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao b = self.theclass(1956, 1, 31) 13484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao diff = a-b 13494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(diff.days, 46*365 + len(range(1956, 2002, 4))) 13504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(diff.seconds, 0) 13514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(diff.microseconds, 0) 13524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao a = self.theclass(2002, 3, 2, 17, 6) 13534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao millisec = timedelta(0, 0, 1000) 13544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao hour = timedelta(0, 3600) 13554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao day = timedelta(1) 13564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao week = timedelta(7) 13574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a + hour, self.theclass(2002, 3, 2, 18, 6)) 13584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(hour + a, self.theclass(2002, 3, 2, 18, 6)) 13594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a + 10*hour, self.theclass(2002, 3, 3, 3, 6)) 13604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - hour, self.theclass(2002, 3, 2, 16, 6)) 13614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(-hour + a, self.theclass(2002, 3, 2, 16, 6)) 13624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - hour, a + -hour) 13634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - 20*hour, self.theclass(2002, 3, 1, 21, 6)) 13644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a + day, self.theclass(2002, 3, 3, 17, 6)) 13654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - day, self.theclass(2002, 3, 1, 17, 6)) 13664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a + week, self.theclass(2002, 3, 9, 17, 6)) 13674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - week, self.theclass(2002, 2, 23, 17, 6)) 13684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a + 52*week, self.theclass(2003, 3, 1, 17, 6)) 13694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - 52*week, self.theclass(2001, 3, 3, 17, 6)) 13704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual((a + week) - a, week) 13714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual((a + day) - a, day) 13724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual((a + hour) - a, hour) 13734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual((a + millisec) - a, millisec) 13744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual((a - week) - a, -week) 13754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual((a - day) - a, -day) 13764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual((a - hour) - a, -hour) 13774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual((a - millisec) - a, -millisec) 13784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - (a + week), -week) 13794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - (a + day), -day) 13804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - (a + hour), -hour) 13814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - (a + millisec), -millisec) 13824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - (a - week), week) 13834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - (a - day), day) 13844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - (a - hour), hour) 13854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - (a - millisec), millisec) 13864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a + (week + day + hour + millisec), 13874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(2002, 3, 10, 18, 6, 0, 1000)) 13884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a + (week + day + hour + millisec), 13894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (((a + week) + day) + hour) + millisec) 13904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - (week + day + hour + millisec), 13914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(2002, 2, 22, 16, 5, 59, 999000)) 13924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a - (week + day + hour + millisec), 13934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (((a - week) - day) - hour) - millisec) 13944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Add/sub ints, longs, floats should be illegal 13954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in 1, 1L, 1.0: 13964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: a+i) 13974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: a-i) 13984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: i+a) 13994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: i-a) 14004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 14014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # delta - datetime is senseless. 14024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: day - a) 14034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # mixing datetime and (delta or datetime) via * or // is senseless 14044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: day * a) 14054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: a * day) 14064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: day // a) 14074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: a // day) 14084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: a * a) 14094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: a // a) 14104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # datetime + datetime is senseless 14114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: a + a) 14124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 14134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_pickling(self): 14144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = 6, 7, 23, 20, 59, 1, 64**2 14154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao orig = self.theclass(*args) 14164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for pickler, unpickler, proto in pickle_choices: 14174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao green = pickler.dumps(orig, proto) 14184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao derived = unpickler.loads(green) 14194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(orig, derived) 14204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 14214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_more_pickling(self): 14224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao a = self.theclass(2003, 2, 7, 16, 48, 37, 444116) 14234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao s = pickle.dumps(a) 14244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao b = pickle.loads(s) 14254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(b.year, 2003) 14264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(b.month, 2) 14274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(b.day, 7) 14284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 14294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_pickling_subclass_datetime(self): 14304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = 6, 7, 23, 20, 59, 1, 64**2 14314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao orig = SubclassDatetime(*args) 14324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for pickler, unpickler, proto in pickle_choices: 14334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao green = pickler.dumps(orig, proto) 14344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao derived = unpickler.loads(green) 14354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(orig, derived) 14364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 14374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_more_compare(self): 14384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # The test_compare() inherited from TestDate covers the error cases. 14394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # We just want to test lexicographic ordering on the members datetime 14404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # has that date lacks. 14414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = [2000, 11, 29, 20, 58, 16, 999998] 14424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = self.theclass(*args) 14434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = self.theclass(*args) 14444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 == t2) 14454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 <= t2) 14464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 >= t2) 14474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 != t2) 14484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 < t2) 14494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 > t2) 14504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cmp(t1, t2), 0) 14514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cmp(t2, t1), 0) 14524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 14534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in range(len(args)): 14544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newargs = args[:] 14554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newargs[i] = args[i] + 1 14564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = self.theclass(*newargs) # this is larger than t1 14574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 < t2) 14584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t2 > t1) 14594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 <= t2) 14604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t2 >= t1) 14614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 != t2) 14624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t2 != t1) 14634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 == t2) 14644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t2 == t1) 14654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 > t2) 14664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t2 < t1) 14674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 >= t2) 14684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t2 <= t1) 14694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cmp(t1, t2), -1) 14704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cmp(t2, t1), 1) 14714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 14724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 14734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # A helper for timestamp constructor tests. 14744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def verify_field_equality(self, expected, got): 14754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected.tm_year, got.year) 14764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected.tm_mon, got.month) 14774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected.tm_mday, got.day) 14784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected.tm_hour, got.hour) 14794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected.tm_min, got.minute) 14804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected.tm_sec, got.second) 14814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 14824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_fromtimestamp(self): 14834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import time 14844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 14854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ts = time.time() 14864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = time.localtime(ts) 14874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = self.theclass.fromtimestamp(ts) 14884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.verify_field_equality(expected, got) 14894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 14904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_utcfromtimestamp(self): 14914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import time 14924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 14934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ts = time.time() 14944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = time.gmtime(ts) 14954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = self.theclass.utcfromtimestamp(ts) 14964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.verify_field_equality(expected, got) 14974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 14984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_microsecond_rounding(self): 14994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Test whether fromtimestamp "rounds up" floats that are less 15004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # than one microsecond smaller than an integer. 15014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(self.theclass.fromtimestamp(0.9999999), 15024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass.fromtimestamp(1)) 15034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 15044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_insane_fromtimestamp(self): 15054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # It's possible that some platform maps time_t to double, 15064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # and that this test will fail there. This test should 15074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # exempt such platforms (provided they return reasonable 15084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # results!). 15094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for insane in -1e200, 1e200: 15104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass.fromtimestamp, 15114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao insane) 15124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 15134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_insane_utcfromtimestamp(self): 15144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # It's possible that some platform maps time_t to double, 15154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # and that this test will fail there. This test should 15164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # exempt such platforms (provided they return reasonable 15174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # results!). 15184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for insane in -1e200, 1e200: 15194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass.utcfromtimestamp, 15204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao insane) 15214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao @unittest.skipIf(sys.platform == "win32", "Windows doesn't accept negative timestamps") 15224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_negative_float_fromtimestamp(self): 15234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # The result is tz-dependent; at least test that this doesn't 15244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # fail (like it did before bug 1646728 was fixed). 15254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass.fromtimestamp(-1.05) 15264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 15274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao @unittest.skipIf(sys.platform == "win32", "Windows doesn't accept negative timestamps") 15284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_negative_float_utcfromtimestamp(self): 15294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass.utcfromtimestamp(-1.05) 15304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d, self.theclass(1969, 12, 31, 23, 59, 58, 950000)) 15314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 15324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_utcnow(self): 15334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import time 15344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 15354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Call it a success if utcnow() and utcfromtimestamp() are within 15364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # a second of each other. 15374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao tolerance = timedelta(seconds=1) 15384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for dummy in range(3): 15394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao from_now = self.theclass.utcnow() 15404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao from_timestamp = self.theclass.utcfromtimestamp(time.time()) 15414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if abs(from_timestamp - from_now) <= tolerance: 15424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao break 15434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Else try again a few times. 15444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(abs(from_timestamp - from_now) <= tolerance) 15454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 15464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_strptime(self): 15474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import _strptime 15484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 15494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao string = '2004-12-01 13:02:47.197' 15504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao format = '%Y-%m-%d %H:%M:%S.%f' 15514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao result, frac = _strptime._strptime(string, format) 15524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = self.theclass(*(result[0:6]+(frac,))) 15534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = self.theclass.strptime(string, format) 15544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected, got) 15554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 15564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_more_timetuple(self): 15574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # This tests fields beyond those tested by the TestDate.test_timetuple. 15584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(2004, 12, 31, 6, 22, 33) 15594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.timetuple(), (2004, 12, 31, 6, 22, 33, 4, 366, -1)) 15604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.timetuple(), 15614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (t.year, t.month, t.day, 15624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t.hour, t.minute, t.second, 15634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t.weekday(), 15644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t.toordinal() - date(t.year, 1, 1).toordinal() + 1, 15654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao -1)) 15664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao tt = t.timetuple() 15674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(tt.tm_year, t.year) 15684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(tt.tm_mon, t.month) 15694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(tt.tm_mday, t.day) 15704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(tt.tm_hour, t.hour) 15714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(tt.tm_min, t.minute) 15724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(tt.tm_sec, t.second) 15734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(tt.tm_wday, t.weekday()) 15744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(tt.tm_yday, t.toordinal() - 15754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao date(t.year, 1, 1).toordinal() + 1) 15764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(tt.tm_isdst, -1) 15774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 15784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_more_strftime(self): 15794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # This tests fields beyond those tested by the TestDate.test_strftime. 15804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(2004, 12, 31, 6, 22, 33, 47) 15814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.strftime("%m %d %y %f %S %M %H %j"), 15824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "12 31 04 000047 33 22 06 366") 15834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 15844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_extract(self): 15854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt = self.theclass(2002, 3, 4, 18, 45, 3, 1234) 15864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.date(), date(2002, 3, 4)) 15874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.time(), time(18, 45, 3, 1234)) 15884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 15894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_combine(self): 15904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = date(2002, 3, 4) 15914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = time(18, 45, 3, 1234) 15924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = self.theclass(2002, 3, 4, 18, 45, 3, 1234) 15934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao combine = self.theclass.combine 15944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt = combine(d, t) 15954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt, expected) 15964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 15974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt = combine(time=t, date=d) 15984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt, expected) 15994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 16004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d, dt.date()) 16014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t, dt.time()) 16024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt, combine(dt.date(), dt.time())) 16034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 16044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, combine) # need an arg 16054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, combine, d) # need two args 16064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, combine, t, d) # args reversed 16074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, combine, d, t, 1) # too many args 16084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, combine, "date", "time") # wrong types 16094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 16104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_replace(self): 16114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls = self.theclass 16124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = [1, 2, 3, 4, 5, 6, 7] 16134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = cls(*args) 16144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(base, base.replace()) 16154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 16164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao i = 0 16174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for name, newval in (("year", 2), 16184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("month", 3), 16194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("day", 4), 16204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("hour", 5), 16214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("minute", 6), 16224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("second", 7), 16234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("microsecond", 8)): 16244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newargs = args[:] 16254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newargs[i] = newval 16264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = cls(*newargs) 16274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = base.replace(**{name: newval}) 16284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected, got) 16294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao i += 1 16304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 16314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Out of bounds. 16324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = cls(2000, 2, 29) 16334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, base.replace, year=2001) 16344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 16354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_astimezone(self): 16364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Pretty boring! The TZ test is more interesting here. astimezone() 16374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # simply can't be applied to a naive object. 16384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt = self.theclass.now() 16394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao f = FixedOffset(44, "") 16404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, dt.astimezone) # not enough args 16414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, dt.astimezone, f, f) # too many args 16424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, dt.astimezone, dt) # arg wrong type 16434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, dt.astimezone, f) # naive 16444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, dt.astimezone, tz=f) # naive 16454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 16464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class Bogus(tzinfo): 16474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, dt): return None 16484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def dst(self, dt): return timedelta(0) 16494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao bog = Bogus() 16504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, dt.astimezone, bog) # naive 16514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 16524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class AlsoBogus(tzinfo): 16534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, dt): return timedelta(0) 16544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def dst(self, dt): return None 16554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao alsobog = AlsoBogus() 16564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, dt.astimezone, alsobog) # also naive 16574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 16584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_subclass_datetime(self): 16594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 16604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class C(self.theclass): 16614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao theAnswer = 42 16624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 16634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __new__(cls, *args, **kws): 16644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao temp = kws.copy() 16654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao extra = temp.pop('extra') 16664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao result = self.theclass.__new__(cls, *args, **temp) 16674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao result.extra = extra 16684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return result 16694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 16704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def newmeth(self, start): 16714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return start + self.year + self.month + self.second 16724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 16734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = 2003, 4, 14, 12, 13, 41 16744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 16754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt1 = self.theclass(*args) 16764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt2 = C(*args, **{'extra': 7}) 16774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 16784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2.__class__, C) 16794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2.theAnswer, 42) 16804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2.extra, 7) 16814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt1.toordinal(), dt2.toordinal()) 16824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2.newmeth(-7), dt1.year + dt1.month + 16834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt1.second - 7) 16844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 16854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass SubclassTime(time): 16864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao sub_var = 1 16874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 16884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass TestTime(HarmlessMixedComparison, unittest.TestCase): 16894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 16904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao theclass = time 16914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 16924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_basic_attributes(self): 16934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(12, 0) 16944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.hour, 12) 16954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.minute, 0) 16964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.second, 0) 16974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.microsecond, 0) 16984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 16994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_basic_attributes_nonzero(self): 17004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Make sure all attributes are non-zero so bugs in 17014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # bit-shifting access show up. 17024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(12, 59, 59, 8000) 17034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.hour, 12) 17044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.minute, 59) 17054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.second, 59) 17064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.microsecond, 8000) 17074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 17084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_roundtrip(self): 17094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(1, 2, 3, 4) 17104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 17114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify t -> string -> time identity. 17124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao s = repr(t) 17134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(s.startswith('datetime.')) 17144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao s = s[9:] 17154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = eval(s) 17164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t, t2) 17174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 17184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Verify identity via reconstructing from pieces. 17194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = self.theclass(t.hour, t.minute, t.second, 17204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t.microsecond) 17214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t, t2) 17224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 17234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_comparing(self): 17244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = [1, 2, 3, 4] 17254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = self.theclass(*args) 17264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = self.theclass(*args) 17274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 == t2) 17284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 <= t2) 17294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 >= t2) 17304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 != t2) 17314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 < t2) 17324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 > t2) 17334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cmp(t1, t2), 0) 17344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cmp(t2, t1), 0) 17354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 17364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for i in range(len(args)): 17374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newargs = args[:] 17384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newargs[i] = args[i] + 1 17394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = self.theclass(*newargs) # this is larger than t1 17404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 < t2) 17414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t2 > t1) 17424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 <= t2) 17434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t2 >= t1) 17444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 != t2) 17454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t2 != t1) 17464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 == t2) 17474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t2 == t1) 17484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 > t2) 17494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t2 < t1) 17504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t1 >= t2) 17514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t2 <= t1) 17524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cmp(t1, t2), -1) 17534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cmp(t2, t1), 1) 17544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 17554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for badarg in OTHERSTUFF: 17564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1 == badarg, False) 17574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1 != badarg, True) 17584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(badarg == t1, False) 17594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(badarg != t1, True) 17604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 17614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: t1 <= badarg) 17624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: t1 < badarg) 17634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: t1 > badarg) 17644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: t1 >= badarg) 17654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: badarg <= t1) 17664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: badarg < t1) 17674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: badarg > t1) 17684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: badarg >= t1) 17694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 17704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_bad_constructor_arguments(self): 17714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # bad hours 17724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(0, 0) # no exception 17734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(23, 0) # no exception 17744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, -1, 0) 17754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 24, 0) 17764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # bad minutes 17774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(23, 0) # no exception 17784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(23, 59) # no exception 17794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 23, -1) 17804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 23, 60) 17814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # bad seconds 17824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(23, 59, 0) # no exception 17834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(23, 59, 59) # no exception 17844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 23, 59, -1) 17854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 23, 59, 60) 17864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # bad microseconds 17874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(23, 59, 59, 0) # no exception 17884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.theclass(23, 59, 59, 999999) # no exception 17894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 23, 59, 59, -1) 17904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, self.theclass, 23, 59, 59, 1000000) 17914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 17924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_hash_equality(self): 17934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass(23, 30, 17) 17944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao e = self.theclass(23, 30, 17) 17954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d, e) 17964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(hash(d), hash(e)) 17974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 17984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dic = {d: 1} 17994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dic[e] = 2 18004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(len(dic), 1) 18014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dic[d], 2) 18024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dic[e], 2) 18034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 18044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = self.theclass(0, 5, 17) 18054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao e = self.theclass(0, 5, 17) 18064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d, e) 18074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(hash(d), hash(e)) 18084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 18094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dic = {d: 1} 18104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dic[e] = 2 18114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(len(dic), 1) 18124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dic[d], 2) 18134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dic[e], 2) 18144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 18154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_isoformat(self): 18164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(4, 5, 1, 123) 18174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(), "04:05:01.000123") 18184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(), str(t)) 18194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 18204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass() 18214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(), "00:00:00") 18224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(), str(t)) 18234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 18244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(microsecond=1) 18254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(), "00:00:00.000001") 18264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(), str(t)) 18274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 18284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(microsecond=10) 18294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(), "00:00:00.000010") 18304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(), str(t)) 18314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 18324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(microsecond=100) 18334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(), "00:00:00.000100") 18344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(), str(t)) 18354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 18364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(microsecond=1000) 18374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(), "00:00:00.001000") 18384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(), str(t)) 18394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 18404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(microsecond=10000) 18414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(), "00:00:00.010000") 18424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(), str(t)) 18434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 18444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(microsecond=100000) 18454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(), "00:00:00.100000") 18464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.isoformat(), str(t)) 18474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 18484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_1653736(self): 18494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # verify it doesn't accept extra keyword arguments 18504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(second=1) 18514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, t.isoformat, foo=3) 18524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 18534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_strftime(self): 18544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(1, 2, 3, 4) 18554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.strftime('%H %M %S %f'), "01 02 03 000004") 18564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # A naive object replaces %z and %Z with empty strings. 18574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''") 18584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 18594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_format(self): 18604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(1, 2, 3, 4) 18614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.__format__(''), str(t)) 18624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 18634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # check that a derived class's __str__() gets called 18644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class A(self.theclass): 18654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __str__(self): 18664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return 'A' 18674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao a = A(1, 2, 3, 4) 18684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a.__format__(''), 'A') 18694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 18704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # check that a derived class's strftime gets called 18714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class B(self.theclass): 18724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def strftime(self, format_spec): 18734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return 'B' 18744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao b = B(1, 2, 3, 4) 18754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(b.__format__(''), str(t)) 18764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 18774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for fmt in ['%H %M %S', 18784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ]: 18794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.__format__(fmt), t.strftime(fmt)) 18804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(a.__format__(fmt), t.strftime(fmt)) 18814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(b.__format__(fmt), 'B') 18824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 18834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_str(self): 18844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(str(self.theclass(1, 2, 3, 4)), "01:02:03.000004") 18854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(str(self.theclass(10, 2, 3, 4000)), "10:02:03.004000") 18864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(str(self.theclass(0, 2, 3, 400000)), "00:02:03.400000") 18874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(str(self.theclass(12, 2, 3, 0)), "12:02:03") 18884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(str(self.theclass(23, 15, 0, 0)), "23:15:00") 18894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 18904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_repr(self): 18914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao name = 'datetime.' + self.theclass.__name__ 18924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(repr(self.theclass(1, 2, 3, 4)), 18934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "%s(1, 2, 3, 4)" % name) 18944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(repr(self.theclass(10, 2, 3, 4000)), 18954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "%s(10, 2, 3, 4000)" % name) 18964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(repr(self.theclass(0, 2, 3, 400000)), 18974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "%s(0, 2, 3, 400000)" % name) 18984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(repr(self.theclass(12, 2, 3, 0)), 18994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "%s(12, 2, 3)" % name) 19004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(repr(self.theclass(23, 15, 0, 0)), 19014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "%s(23, 15)" % name) 19024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 19034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_resolution_info(self): 19044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIsInstance(self.theclass.min, self.theclass) 19054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIsInstance(self.theclass.max, self.theclass) 19064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIsInstance(self.theclass.resolution, timedelta) 19074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(self.theclass.max > self.theclass.min) 19084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 19094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_pickling(self): 19104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = 20, 59, 16, 64**2 19114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao orig = self.theclass(*args) 19124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for pickler, unpickler, proto in pickle_choices: 19134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao green = pickler.dumps(orig, proto) 19144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao derived = unpickler.loads(green) 19154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(orig, derived) 19164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 19174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_pickling_subclass_time(self): 19184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = 20, 59, 16, 64**2 19194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao orig = SubclassTime(*args) 19204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for pickler, unpickler, proto in pickle_choices: 19214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao green = pickler.dumps(orig, proto) 19224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao derived = unpickler.loads(green) 19234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(orig, derived) 19244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 19254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_bool(self): 19264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls = self.theclass 19274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(cls(1)) 19284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(cls(0, 1)) 19294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(cls(0, 0, 1)) 19304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(cls(0, 0, 0, 1)) 19314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not cls(0)) 19324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not cls()) 19334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 19344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_replace(self): 19354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls = self.theclass 19364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = [1, 2, 3, 4] 19374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = cls(*args) 19384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(base, base.replace()) 19394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 19404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao i = 0 19414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for name, newval in (("hour", 5), 19424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("minute", 6), 19434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("second", 7), 19444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("microsecond", 8)): 19454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newargs = args[:] 19464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newargs[i] = newval 19474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = cls(*newargs) 19484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = base.replace(**{name: newval}) 19494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected, got) 19504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao i += 1 19514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 19524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Out of bounds. 19534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = cls(1) 19544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, base.replace, hour=24) 19554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, base.replace, minute=-1) 19564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, base.replace, second=100) 19574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, base.replace, microsecond=1000000) 19584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 19594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_subclass_time(self): 19604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 19614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class C(self.theclass): 19624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao theAnswer = 42 19634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 19644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __new__(cls, *args, **kws): 19654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao temp = kws.copy() 19664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao extra = temp.pop('extra') 19674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao result = self.theclass.__new__(cls, *args, **temp) 19684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao result.extra = extra 19694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return result 19704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 19714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def newmeth(self, start): 19724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return start + self.hour + self.second 19734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 19744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = 4, 5, 6 19754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 19764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt1 = self.theclass(*args) 19774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt2 = C(*args, **{'extra': 7}) 19784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 19794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2.__class__, C) 19804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2.theAnswer, 42) 19814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2.extra, 7) 19824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt1.isoformat(), dt2.isoformat()) 19834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2.newmeth(-7), dt1.hour + dt1.second - 7) 19844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 19854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_backdoor_resistance(self): 19864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # see TestDate.test_backdoor_resistance(). 19874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = '2:59.0' 19884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for hour_byte in ' ', '9', chr(24), '\xff': 19894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, self.theclass, 19904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao hour_byte + base[1:]) 19914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 19924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# A mixin for classes with a tzinfo= argument. Subclasses must define 19934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# theclass as a class atribute, and theclass(1, 1, 1, tzinfo=whatever) 19944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# must be legit (which is true for time and datetime). 19954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass TZInfoBase: 19964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 19974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_argument_passing(self): 19984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls = self.theclass 19994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # A datetime passes itself on, a time passes None. 20004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class introspective(tzinfo): 20014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def tzname(self, dt): return dt and "real" or "none" 20024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, dt): 20034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return timedelta(minutes = dt and 42 or -42) 20044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dst = utcoffset 20054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 20064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao obj = cls(1, 2, 3, tzinfo=introspective()) 20074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 20084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = cls is time and "none" or "real" 20094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(obj.tzname(), expected) 20104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 20114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = timedelta(minutes=(cls is time and -42 or 42)) 20124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(obj.utcoffset(), expected) 20134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(obj.dst(), expected) 20144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 20154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_bad_tzinfo_classes(self): 20164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls = self.theclass 20174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, cls, 1, 1, 1, tzinfo=12) 20184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 20194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class NiceTry(object): 20204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self): pass 20214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, dt): pass 20224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, cls, 1, 1, 1, tzinfo=NiceTry) 20234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 20244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class BetterTry(tzinfo): 20254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self): pass 20264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, dt): pass 20274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao b = BetterTry() 20284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = cls(1, 1, 1, tzinfo=b) 20294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t.tzinfo is b) 20304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 20314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_utc_offset_out_of_bounds(self): 20324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class Edgy(tzinfo): 20334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self, offset): 20344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.offset = timedelta(minutes=offset) 20354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, dt): 20364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.offset 20374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 20384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls = self.theclass 20394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for offset, legit in ((-1440, False), 20404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (-1439, True), 20414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (1439, True), 20424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (1440, False)): 20434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if cls is time: 20444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = cls(1, 2, 3, tzinfo=Edgy(offset)) 20454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif cls is datetime: 20464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = cls(6, 6, 6, 1, 2, 3, tzinfo=Edgy(offset)) 20474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 20484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert 0, "impossible" 20494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if legit: 20504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao aofs = abs(offset) 20514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao h, m = divmod(aofs, 60) 20524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao tag = "%c%02d:%02d" % (offset < 0 and '-' or '+', h, m) 20534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if isinstance(t, datetime): 20544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = t.timetz() 20554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(str(t), "01:02:03" + tag) 20564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 20574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, str, t) 20584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 20594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_tzinfo_classes(self): 20604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls = self.theclass 20614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class C1(tzinfo): 20624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, dt): return None 20634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def dst(self, dt): return None 20644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def tzname(self, dt): return None 20654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for t in (cls(1, 1, 1), 20664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls(1, 1, 1, tzinfo=None), 20674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls(1, 1, 1, tzinfo=C1())): 20684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t.utcoffset() is None) 20694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t.dst() is None) 20704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t.tzname() is None) 20714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 20724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class C3(tzinfo): 20734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, dt): return timedelta(minutes=-1439) 20744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def dst(self, dt): return timedelta(minutes=1439) 20754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def tzname(self, dt): return "aname" 20764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = cls(1, 1, 1, tzinfo=C3()) 20774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.utcoffset(), timedelta(minutes=-1439)) 20784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.dst(), timedelta(minutes=1439)) 20794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tzname(), "aname") 20804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 20814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Wrong types. 20824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class C4(tzinfo): 20834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, dt): return "aname" 20844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def dst(self, dt): return 7 20854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def tzname(self, dt): return 0 20864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = cls(1, 1, 1, tzinfo=C4()) 20874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, t.utcoffset) 20884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, t.dst) 20894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, t.tzname) 20904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 20914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Offset out of range. 20924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class C6(tzinfo): 20934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, dt): return timedelta(hours=-24) 20944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def dst(self, dt): return timedelta(hours=24) 20954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = cls(1, 1, 1, tzinfo=C6()) 20964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, t.utcoffset) 20974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, t.dst) 20984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 20994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Not a whole number of minutes. 21004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class C7(tzinfo): 21014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, dt): return timedelta(seconds=61) 21024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def dst(self, dt): return timedelta(microseconds=-81) 21034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = cls(1, 1, 1, tzinfo=C7()) 21044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, t.utcoffset) 21054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, t.dst) 21064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 21074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_aware_compare(self): 21084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls = self.theclass 21094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 21104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Ensure that utcoffset() gets ignored if the comparands have 21114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # the same tzinfo member. 21124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class OperandDependentOffset(tzinfo): 21134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, t): 21144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if t.minute < 10: 21154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # d0 and d1 equal after adjustment 21164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return timedelta(minutes=t.minute) 21174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 21184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # d2 off in the weeds 21194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return timedelta(minutes=59) 21204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 21214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = cls(8, 9, 10, tzinfo=OperandDependentOffset()) 21224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d0 = base.replace(minute=3) 21234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d1 = base.replace(minute=9) 21244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d2 = base.replace(minute=11) 21254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for x in d0, d1, d2: 21264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for y in d0, d1, d2: 21274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = cmp(x, y) 21284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = cmp(x.minute, y.minute) 21294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(got, expected) 21304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 21314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # However, if they're different members, uctoffset is not ignored. 21324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Note that a time can't actually have an operand-depedent offset, 21334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # though (and time.utcoffset() passes None to tzinfo.utcoffset()), 21344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # so skip this test for time. 21354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if cls is not time: 21364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d0 = base.replace(minute=3, tzinfo=OperandDependentOffset()) 21374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d1 = base.replace(minute=9, tzinfo=OperandDependentOffset()) 21384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d2 = base.replace(minute=11, tzinfo=OperandDependentOffset()) 21394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for x in d0, d1, d2: 21404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for y in d0, d1, d2: 21414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = cmp(x, y) 21424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if (x is d0 or x is d1) and (y is d0 or y is d1): 21434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = 0 21444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif x is y is d2: 21454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = 0 21464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif x is d2: 21474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = -1 21484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 21494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert y is d2 21504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = 1 21514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(got, expected) 21524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 21534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 21544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Testing time objects with a non-None tzinfo. 21554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass TestTimeTZ(TestTime, TZInfoBase, unittest.TestCase): 21564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao theclass = time 21574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 21584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_empty(self): 21594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass() 21604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.hour, 0) 21614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.minute, 0) 21624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.second, 0) 21634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.microsecond, 0) 21644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t.tzinfo is None) 21654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 21664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_zones(self): 21674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao est = FixedOffset(-300, "EST", 1) 21684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao utc = FixedOffset(0, "UTC", -2) 21694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao met = FixedOffset(60, "MET", 3) 21704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = time( 7, 47, tzinfo=est) 21714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = time(12, 47, tzinfo=utc) 21724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t3 = time(13, 47, tzinfo=met) 21734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t4 = time(microsecond=40) 21744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t5 = time(microsecond=40, tzinfo=utc) 21754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 21764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1.tzinfo, est) 21774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t2.tzinfo, utc) 21784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t3.tzinfo, met) 21794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t4.tzinfo is None) 21804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t5.tzinfo, utc) 21814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 21824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1.utcoffset(), timedelta(minutes=-300)) 21834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t2.utcoffset(), timedelta(minutes=0)) 21844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t3.utcoffset(), timedelta(minutes=60)) 21854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t4.utcoffset() is None) 21864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, t1.utcoffset, "no args") 21874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 21884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1.tzname(), "EST") 21894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t2.tzname(), "UTC") 21904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t3.tzname(), "MET") 21914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t4.tzname() is None) 21924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, t1.tzname, "no args") 21934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 21944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1.dst(), timedelta(minutes=1)) 21954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t2.dst(), timedelta(minutes=-2)) 21964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t3.dst(), timedelta(minutes=3)) 21974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t4.dst() is None) 21984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, t1.dst, "no args") 21994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 22004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(hash(t1), hash(t2)) 22014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(hash(t1), hash(t3)) 22024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(hash(t2), hash(t3)) 22034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 22044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1, t2) 22054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1, t3) 22064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t2, t3) 22074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: t4 == t5) # mixed tz-aware & naive 22084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: t4 < t5) # mixed tz-aware & naive 22094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: t5 < t4) # mixed tz-aware & naive 22104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 22114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(str(t1), "07:47:00-05:00") 22124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(str(t2), "12:47:00+00:00") 22134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(str(t3), "13:47:00+01:00") 22144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(str(t4), "00:00:00.000040") 22154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(str(t5), "00:00:00.000040+00:00") 22164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 22174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1.isoformat(), "07:47:00-05:00") 22184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t2.isoformat(), "12:47:00+00:00") 22194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t3.isoformat(), "13:47:00+01:00") 22204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t4.isoformat(), "00:00:00.000040") 22214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t5.isoformat(), "00:00:00.000040+00:00") 22224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 22234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = 'datetime.time' 22244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(repr(t1), d + "(7, 47, tzinfo=est)") 22254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(repr(t2), d + "(12, 47, tzinfo=utc)") 22264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(repr(t3), d + "(13, 47, tzinfo=met)") 22274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(repr(t4), d + "(0, 0, 0, 40)") 22284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(repr(t5), d + "(0, 0, 0, 40, tzinfo=utc)") 22294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 22304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1.strftime("%H:%M:%S %%Z=%Z %%z=%z"), 22314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "07:47:00 %Z=EST %z=-0500") 22324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t2.strftime("%H:%M:%S %Z %z"), "12:47:00 UTC +0000") 22334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t3.strftime("%H:%M:%S %Z %z"), "13:47:00 MET +0100") 22344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 22354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao yuck = FixedOffset(-1439, "%z %Z %%z%%Z") 22364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = time(23, 59, tzinfo=yuck) 22374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1.strftime("%H:%M %%Z='%Z' %%z='%z'"), 22384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao "23:59 %Z='%z %Z %%z%%Z' %z='-2359'") 22394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 22404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Check that an invalid tzname result raises an exception. 22414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class Badtzname(tzinfo): 22424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def tzname(self, dt): return 42 22434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = time(2, 3, 4, tzinfo=Badtzname()) 22444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.strftime("%H:%M:%S"), "02:03:04") 22454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, t.strftime, "%Z") 22464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 22474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_hash_edge_cases(self): 22484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Offsets that overflow a basic time. 22494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = self.theclass(0, 1, 2, 3, tzinfo=FixedOffset(1439, "")) 22504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = self.theclass(0, 0, 2, 3, tzinfo=FixedOffset(1438, "")) 22514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(hash(t1), hash(t2)) 22524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 22534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = self.theclass(23, 58, 6, 100, tzinfo=FixedOffset(-1000, "")) 22544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = self.theclass(23, 48, 6, 100, tzinfo=FixedOffset(-1010, "")) 22554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(hash(t1), hash(t2)) 22564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 22574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_pickling(self): 22584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Try one without a tzinfo. 22594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = 20, 59, 16, 64**2 22604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao orig = self.theclass(*args) 22614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for pickler, unpickler, proto in pickle_choices: 22624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao green = pickler.dumps(orig, proto) 22634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao derived = unpickler.loads(green) 22644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(orig, derived) 22654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 22664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Try one with a tzinfo. 22674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao tinfo = PicklableFixedOffset(-300, 'cookie') 22684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao orig = self.theclass(5, 6, 7, tzinfo=tinfo) 22694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for pickler, unpickler, proto in pickle_choices: 22704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao green = pickler.dumps(orig, proto) 22714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao derived = unpickler.loads(green) 22724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(orig, derived) 22734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIsInstance(derived.tzinfo, PicklableFixedOffset) 22744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(derived.utcoffset(), timedelta(minutes=-300)) 22754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(derived.tzname(), 'cookie') 22764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 22774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_more_bool(self): 22784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Test cases with non-None tzinfo. 22794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls = self.theclass 22804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 22814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = cls(0, tzinfo=FixedOffset(-300, "")) 22824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t) 22834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 22844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = cls(5, tzinfo=FixedOffset(-300, "")) 22854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t) 22864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 22874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = cls(5, tzinfo=FixedOffset(300, "")) 22884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t) 22894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 22904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = cls(23, 59, tzinfo=FixedOffset(23*60 + 59, "")) 22914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not t) 22924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 22934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Mostly ensuring this doesn't overflow internally. 22944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = cls(0, tzinfo=FixedOffset(23*60 + 59, "")) 22954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t) 22964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 22974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # But this should yield a value error -- the utcoffset is bogus. 22984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = cls(0, tzinfo=FixedOffset(24*60, "")) 22994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, lambda: bool(t)) 23004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 23014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Likewise. 23024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = cls(0, tzinfo=FixedOffset(-24*60, "")) 23034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, lambda: bool(t)) 23044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 23054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_replace(self): 23064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls = self.theclass 23074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao z100 = FixedOffset(100, "+100") 23084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao zm200 = FixedOffset(timedelta(minutes=-200), "-200") 23094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = [1, 2, 3, 4, z100] 23104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = cls(*args) 23114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(base, base.replace()) 23124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 23134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao i = 0 23144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for name, newval in (("hour", 5), 23154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("minute", 6), 23164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("second", 7), 23174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("microsecond", 8), 23184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("tzinfo", zm200)): 23194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newargs = args[:] 23204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newargs[i] = newval 23214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = cls(*newargs) 23224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = base.replace(**{name: newval}) 23234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected, got) 23244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao i += 1 23254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 23264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Ensure we can get rid of a tzinfo. 23274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(base.tzname(), "+100") 23284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base2 = base.replace(tzinfo=None) 23294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(base2.tzinfo is None) 23304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(base2.tzname() is None) 23314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 23324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Ensure we can add one. 23334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base3 = base2.replace(tzinfo=z100) 23344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(base, base3) 23354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(base.tzinfo is base3.tzinfo) 23364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 23374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Out of bounds. 23384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = cls(1) 23394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, base.replace, hour=24) 23404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, base.replace, minute=-1) 23414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, base.replace, second=100) 23424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, base.replace, microsecond=1000000) 23434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 23444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_mixed_compare(self): 23454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = time(1, 2, 3) 23464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = time(1, 2, 3) 23474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1, t2) 23484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = t2.replace(tzinfo=None) 23494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1, t2) 23504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = t2.replace(tzinfo=FixedOffset(None, "")) 23514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1, t2) 23524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = t2.replace(tzinfo=FixedOffset(0, "")) 23534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: t1 == t2) 23544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 23554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # In time w/ identical tzinfo objects, utcoffset is ignored. 23564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class Varies(tzinfo): 23574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self): 23584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.offset = timedelta(minutes=22) 23594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, t): 23604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.offset += timedelta(minutes=1) 23614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.offset 23624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 23634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao v = Varies() 23644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = t2.replace(tzinfo=v) 23654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = t2.replace(tzinfo=v) 23664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1.utcoffset(), timedelta(minutes=23)) 23674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t2.utcoffset(), timedelta(minutes=24)) 23684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1, t2) 23694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 23704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # But if they're not identical, it isn't ignored. 23714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = t2.replace(tzinfo=Varies()) 23724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 < t2) # t1's offset counter still going up 23734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 23744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_subclass_timetz(self): 23754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 23764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class C(self.theclass): 23774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao theAnswer = 42 23784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 23794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __new__(cls, *args, **kws): 23804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao temp = kws.copy() 23814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao extra = temp.pop('extra') 23824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao result = self.theclass.__new__(cls, *args, **temp) 23834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao result.extra = extra 23844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return result 23854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 23864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def newmeth(self, start): 23874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return start + self.hour + self.second 23884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 23894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = 4, 5, 6, 500, FixedOffset(-300, "EST", 1) 23904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 23914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt1 = self.theclass(*args) 23924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt2 = C(*args, **{'extra': 7}) 23934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 23944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2.__class__, C) 23954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2.theAnswer, 42) 23964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2.extra, 7) 23974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt1.utcoffset(), dt2.utcoffset()) 23984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2.newmeth(-7), dt1.hour + dt1.second - 7) 23994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 24004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 24014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Testing datetime objects with a non-None tzinfo. 24024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 24034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass TestDateTimeTZ(TestDateTime, TZInfoBase, unittest.TestCase): 24044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao theclass = datetime 24054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 24064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_trivial(self): 24074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt = self.theclass(1, 2, 3, 4, 5, 6, 7) 24084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.year, 1) 24094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.month, 2) 24104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.day, 3) 24114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.hour, 4) 24124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.minute, 5) 24134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.second, 6) 24144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.microsecond, 7) 24154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.tzinfo, None) 24164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 24174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_even_more_compare(self): 24184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # The test_compare() and test_more_compare() inherited from TestDate 24194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # and TestDateTime covered non-tzinfo cases. 24204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 24214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Smallest possible after UTC adjustment. 24224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = self.theclass(1, 1, 1, tzinfo=FixedOffset(1439, "")) 24234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Largest possible after UTC adjustment. 24244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = self.theclass(MAXYEAR, 12, 31, 23, 59, 59, 999999, 24254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao tzinfo=FixedOffset(-1439, "")) 24264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 24274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Make sure those compare correctly, and w/o overflow. 24284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 < t2) 24294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 != t2) 24304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t2 > t1) 24314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 24324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 == t1) 24334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t2 == t2) 24344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 24354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Equal afer adjustment. 24364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(1, "")) 24374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = self.theclass(2, 1, 1, 3, 13, tzinfo=FixedOffset(3*60+13+2, "")) 24384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1, t2) 24394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 24404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Change t1 not to subtract a minute, and t1 should be larger. 24414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(0, "")) 24424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 > t2) 24434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 24444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Change t1 to subtract 2 minutes, and t1 should be smaller. 24454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(2, "")) 24464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 < t2) 24474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 24484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Back to the original t1, but make seconds resolve it. 24494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(1, ""), 24504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao second=1) 24514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 > t2) 24524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 24534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Likewise, but make microseconds resolve it. 24544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(1, ""), 24554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao microsecond=1) 24564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 > t2) 24574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 24584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Make t2 naive and it should fail. 24594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = self.theclass.min 24604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: t1 == t2) 24614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t2, t2) 24624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 24634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # It's also naive if it has tzinfo but tzinfo.utcoffset() is None. 24644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class Naive(tzinfo): 24654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, dt): return None 24664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = self.theclass(5, 6, 7, tzinfo=Naive()) 24674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: t1 == t2) 24684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t2, t2) 24694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 24704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # OTOH, it's OK to compare two of these mixing the two ways of being 24714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # naive. 24724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = self.theclass(5, 6, 7) 24734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1, t2) 24744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 24754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Try a bogus uctoffset. 24764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class Bogus(tzinfo): 24774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, dt): 24784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return timedelta(minutes=1440) # out of bounds 24794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = self.theclass(2, 2, 2, tzinfo=Bogus()) 24804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = self.theclass(2, 2, 2, tzinfo=FixedOffset(0, "")) 24814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, lambda: t1 == t2) 24824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 24834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_pickling(self): 24844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Try one without a tzinfo. 24854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = 6, 7, 23, 20, 59, 1, 64**2 24864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao orig = self.theclass(*args) 24874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for pickler, unpickler, proto in pickle_choices: 24884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao green = pickler.dumps(orig, proto) 24894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao derived = unpickler.loads(green) 24904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(orig, derived) 24914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 24924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Try one with a tzinfo. 24934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao tinfo = PicklableFixedOffset(-300, 'cookie') 24944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao orig = self.theclass(*args, **{'tzinfo': tinfo}) 24954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao derived = self.theclass(1, 1, 1, tzinfo=FixedOffset(0, "", 0)) 24964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for pickler, unpickler, proto in pickle_choices: 24974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao green = pickler.dumps(orig, proto) 24984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao derived = unpickler.loads(green) 24994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(orig, derived) 25004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertIsInstance(derived.tzinfo, PicklableFixedOffset) 25014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(derived.utcoffset(), timedelta(minutes=-300)) 25024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(derived.tzname(), 'cookie') 25034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 25044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_extreme_hashes(self): 25054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # If an attempt is made to hash these via subtracting the offset 25064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # then hashing a datetime object, OverflowError results. The 25074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Python implementation used to blow up here. 25084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(1, 1, 1, tzinfo=FixedOffset(1439, "")) 25094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao hash(t) 25104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(MAXYEAR, 12, 31, 23, 59, 59, 999999, 25114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao tzinfo=FixedOffset(-1439, "")) 25124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao hash(t) 25134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 25144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # OTOH, an OOB offset should blow up. 25154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = self.theclass(5, 5, 5, tzinfo=FixedOffset(-1440, "")) 25164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, hash, t) 25174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 25184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_zones(self): 25194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao est = FixedOffset(-300, "EST") 25204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao utc = FixedOffset(0, "UTC") 25214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao met = FixedOffset(60, "MET") 25224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = datetime(2002, 3, 19, 7, 47, tzinfo=est) 25234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = datetime(2002, 3, 19, 12, 47, tzinfo=utc) 25244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t3 = datetime(2002, 3, 19, 13, 47, tzinfo=met) 25254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1.tzinfo, est) 25264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t2.tzinfo, utc) 25274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t3.tzinfo, met) 25284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1.utcoffset(), timedelta(minutes=-300)) 25294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t2.utcoffset(), timedelta(minutes=0)) 25304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t3.utcoffset(), timedelta(minutes=60)) 25314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1.tzname(), "EST") 25324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t2.tzname(), "UTC") 25334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t3.tzname(), "MET") 25344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(hash(t1), hash(t2)) 25354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(hash(t1), hash(t3)) 25364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(hash(t2), hash(t3)) 25374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1, t2) 25384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1, t3) 25394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t2, t3) 25404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(str(t1), "2002-03-19 07:47:00-05:00") 25414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(str(t2), "2002-03-19 12:47:00+00:00") 25424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(str(t3), "2002-03-19 13:47:00+01:00") 25434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = 'datetime.datetime(2002, 3, 19, ' 25444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(repr(t1), d + "7, 47, tzinfo=est)") 25454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(repr(t2), d + "12, 47, tzinfo=utc)") 25464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(repr(t3), d + "13, 47, tzinfo=met)") 25474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 25484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_combine(self): 25494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao met = FixedOffset(60, "MET") 25504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = date(2002, 3, 4) 25514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao tz = time(18, 45, 3, 1234, tzinfo=met) 25524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt = datetime.combine(d, tz) 25534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt, datetime(2002, 3, 4, 18, 45, 3, 1234, 25544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao tzinfo=met)) 25554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 25564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_extract(self): 25574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao met = FixedOffset(60, "MET") 25584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt = self.theclass(2002, 3, 4, 18, 45, 3, 1234, tzinfo=met) 25594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.date(), date(2002, 3, 4)) 25604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.time(), time(18, 45, 3, 1234)) 25614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.timetz(), time(18, 45, 3, 1234, tzinfo=met)) 25624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 25634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_tz_aware_arithmetic(self): 25644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import random 25654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 25664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao now = self.theclass.now() 25674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao tz55 = FixedOffset(-330, "west 5:30") 25684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao timeaware = now.time().replace(tzinfo=tz55) 25694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao nowaware = self.theclass.combine(now.date(), timeaware) 25704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(nowaware.tzinfo is tz55) 25714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(nowaware.timetz(), timeaware) 25724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 25734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Can't mix aware and non-aware. 25744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: now - nowaware) 25754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: nowaware - now) 25764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 25774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # And adding datetime's doesn't make sense, aware or not. 25784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: now + nowaware) 25794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: nowaware + now) 25804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: nowaware + nowaware) 25814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 25824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Subtracting should yield 0. 25834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(now - now, timedelta(0)) 25844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(nowaware - nowaware, timedelta(0)) 25854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 25864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Adding a delta should preserve tzinfo. 25874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao delta = timedelta(weeks=1, minutes=12, microseconds=5678) 25884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao nowawareplus = nowaware + delta 25894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(nowaware.tzinfo is tz55) 25904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao nowawareplus2 = delta + nowaware 25914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(nowawareplus2.tzinfo is tz55) 25924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(nowawareplus, nowawareplus2) 25934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 25944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # that - delta should be what we started with, and that - what we 25954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # started with should be delta. 25964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao diff = nowawareplus - delta 25974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(diff.tzinfo is tz55) 25984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(nowaware, diff) 25994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: delta - nowawareplus) 26004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(nowawareplus - nowaware, delta) 26014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 26024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Make up a random timezone. 26034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao tzr = FixedOffset(random.randrange(-1439, 1440), "randomtimezone") 26044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Attach it to nowawareplus. 26054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao nowawareplus = nowawareplus.replace(tzinfo=tzr) 26064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(nowawareplus.tzinfo is tzr) 26074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Make sure the difference takes the timezone adjustments into account. 26084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = nowaware - nowawareplus 26094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Expected: (nowaware base - nowaware offset) - 26104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # (nowawareplus base - nowawareplus offset) = 26114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # (nowaware base - nowawareplus base) + 26124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # (nowawareplus offset - nowaware offset) = 26134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # -delta + nowawareplus offset - nowaware offset 26144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = nowawareplus.utcoffset() - nowaware.utcoffset() - delta 26154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(got, expected) 26164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 26174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Try max possible difference. 26184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao min = self.theclass(1, 1, 1, tzinfo=FixedOffset(1439, "min")) 26194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao max = self.theclass(MAXYEAR, 12, 31, 23, 59, 59, 999999, 26204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao tzinfo=FixedOffset(-1439, "max")) 26214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao maxdiff = max - min 26224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(maxdiff, self.theclass.max - self.theclass.min + 26234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao timedelta(minutes=2*1439)) 26244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 26254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_tzinfo_now(self): 26264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao meth = self.theclass.now 26274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Ensure it doesn't require tzinfo (i.e., that this doesn't blow up). 26284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = meth() 26294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Try with and without naming the keyword. 26304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao off42 = FixedOffset(42, "42") 26314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao another = meth(off42) 26324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao again = meth(tz=off42) 26334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(another.tzinfo is again.tzinfo) 26344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(another.utcoffset(), timedelta(minutes=42)) 26354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Bad argument with and w/o naming the keyword. 26364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, meth, 16) 26374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, meth, tzinfo=16) 26384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Bad keyword name. 26394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, meth, tinfo=off42) 26404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Too many args. 26414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, meth, off42, off42) 26424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 26434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # We don't know which time zone we're in, and don't have a tzinfo 26444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # class to represent it, so seeing whether a tz argument actually 26454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # does a conversion is tricky. 26464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao weirdtz = FixedOffset(timedelta(hours=15, minutes=58), "weirdtz", 0) 26474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao utc = FixedOffset(0, "utc", 0) 26484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for dummy in range(3): 26494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao now = datetime.now(weirdtz) 26504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(now.tzinfo is weirdtz) 26514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao utcnow = datetime.utcnow().replace(tzinfo=utc) 26524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao now2 = utcnow.astimezone(weirdtz) 26534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if abs(now - now2) < timedelta(seconds=30): 26544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao break 26554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Else the code is broken, or more than 30 seconds passed between 26564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # calls; assuming the latter, just try again. 26574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 26584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Three strikes and we're out. 26594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.fail("utcnow(), now(tz), or astimezone() may be broken") 26604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 26614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_tzinfo_fromtimestamp(self): 26624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import time 26634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao meth = self.theclass.fromtimestamp 26644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ts = time.time() 26654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Ensure it doesn't require tzinfo (i.e., that this doesn't blow up). 26664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = meth(ts) 26674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Try with and without naming the keyword. 26684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao off42 = FixedOffset(42, "42") 26694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao another = meth(ts, off42) 26704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao again = meth(ts, tz=off42) 26714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(another.tzinfo is again.tzinfo) 26724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(another.utcoffset(), timedelta(minutes=42)) 26734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Bad argument with and w/o naming the keyword. 26744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, meth, ts, 16) 26754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, meth, ts, tzinfo=16) 26764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Bad keyword name. 26774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, meth, ts, tinfo=off42) 26784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Too many args. 26794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, meth, ts, off42, off42) 26804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Too few args. 26814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, meth) 26824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 26834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Try to make sure tz= actually does some conversion. 26844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao timestamp = 1000000000 26854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao utcdatetime = datetime.utcfromtimestamp(timestamp) 26864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # In POSIX (epoch 1970), that's 2001-09-09 01:46:40 UTC, give or take. 26874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # But on some flavor of Mac, it's nowhere near that. So we can't have 26884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # any idea here what time that actually is, we can only test that 26894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # relative changes match. 26904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao utcoffset = timedelta(hours=-15, minutes=39) # arbitrary, but not zero 26914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao tz = FixedOffset(utcoffset, "tz", 0) 26924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = utcdatetime + utcoffset 26934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = datetime.fromtimestamp(timestamp, tz) 26944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected, got.replace(tzinfo=None)) 26954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 26964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_tzinfo_utcnow(self): 26974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao meth = self.theclass.utcnow 26984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Ensure it doesn't require tzinfo (i.e., that this doesn't blow up). 26994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = meth() 27004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Try with and without naming the keyword; for whatever reason, 27014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # utcnow() doesn't accept a tzinfo argument. 27024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao off42 = FixedOffset(42, "42") 27034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, meth, off42) 27044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, meth, tzinfo=off42) 27054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 27064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_tzinfo_utcfromtimestamp(self): 27074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import time 27084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao meth = self.theclass.utcfromtimestamp 27094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ts = time.time() 27104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Ensure it doesn't require tzinfo (i.e., that this doesn't blow up). 27114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = meth(ts) 27124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Try with and without naming the keyword; for whatever reason, 27134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # utcfromtimestamp() doesn't accept a tzinfo argument. 27144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao off42 = FixedOffset(42, "42") 27154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, meth, ts, off42) 27164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, meth, ts, tzinfo=off42) 27174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 27184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_tzinfo_timetuple(self): 27194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # TestDateTime tested most of this. datetime adds a twist to the 27204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # DST flag. 27214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class DST(tzinfo): 27224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self, dstvalue): 27234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if isinstance(dstvalue, int): 27244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dstvalue = timedelta(minutes=dstvalue) 27254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.dstvalue = dstvalue 27264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def dst(self, dt): 27274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.dstvalue 27284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 27294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls = self.theclass 27304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for dstvalue, flag in (-33, 1), (33, 1), (0, 0), (None, -1): 27314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = cls(1, 1, 1, 10, 20, 30, 40, tzinfo=DST(dstvalue)) 27324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = d.timetuple() 27334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(1, t.tm_year) 27344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(1, t.tm_mon) 27354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(1, t.tm_mday) 27364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(10, t.tm_hour) 27374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(20, t.tm_min) 27384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(30, t.tm_sec) 27394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(0, t.tm_wday) 27404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(1, t.tm_yday) 27414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(flag, t.tm_isdst) 27424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 27434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # dst() returns wrong type. 27444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, cls(1, 1, 1, tzinfo=DST("x")).timetuple) 27454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 27464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # dst() at the edge. 27474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cls(1,1,1, tzinfo=DST(1439)).timetuple().tm_isdst, 1) 27484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(cls(1,1,1, tzinfo=DST(-1439)).timetuple().tm_isdst, 1) 27494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 27504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # dst() out of range. 27514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, cls(1,1,1, tzinfo=DST(1440)).timetuple) 27524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, cls(1,1,1, tzinfo=DST(-1440)).timetuple) 27534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 27544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_utctimetuple(self): 27554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class DST(tzinfo): 27564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self, dstvalue): 27574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if isinstance(dstvalue, int): 27584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dstvalue = timedelta(minutes=dstvalue) 27594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.dstvalue = dstvalue 27604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def dst(self, dt): 27614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.dstvalue 27624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 27634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls = self.theclass 27644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # This can't work: DST didn't implement utcoffset. 27654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(NotImplementedError, 27664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls(1, 1, 1, tzinfo=DST(0)).utcoffset) 27674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 27684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class UOFS(DST): 27694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self, uofs, dofs=None): 27704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao DST.__init__(self, dofs) 27714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.uofs = timedelta(minutes=uofs) 27724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, dt): 27734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.uofs 27744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 27754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Ensure tm_isdst is 0 regardless of what dst() says: DST is never 27764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # in effect for a UTC time. 27774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for dstvalue in -33, 33, 0, None: 27784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = cls(1, 2, 3, 10, 20, 30, 40, tzinfo=UOFS(-53, dstvalue)) 27794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = d.utctimetuple() 27804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d.year, t.tm_year) 27814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d.month, t.tm_mon) 27824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d.day, t.tm_mday) 27834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(11, t.tm_hour) # 20mm + 53mm = 1hn + 13mm 27844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(13, t.tm_min) 27854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d.second, t.tm_sec) 27864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d.weekday(), t.tm_wday) 27874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d.toordinal() - date(1, 1, 1).toordinal() + 1, 27884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t.tm_yday) 27894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(0, t.tm_isdst) 27904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 27914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # At the edges, UTC adjustment can normalize into years out-of-range 27924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # for a datetime object. Ensure that a correct timetuple is 27934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # created anyway. 27944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao tiny = cls(MINYEAR, 1, 1, 0, 0, 37, tzinfo=UOFS(1439)) 27954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # That goes back 1 minute less than a full day. 27964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = tiny.utctimetuple() 27974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_year, MINYEAR-1) 27984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_mon, 12) 27994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_mday, 31) 28004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_hour, 0) 28014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_min, 1) 28024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_sec, 37) 28034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_yday, 366) # "year 0" is a leap year 28044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_isdst, 0) 28054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 28064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao huge = cls(MAXYEAR, 12, 31, 23, 59, 37, 999999, tzinfo=UOFS(-1439)) 28074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # That goes forward 1 minute less than a full day. 28084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t = huge.utctimetuple() 28094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_year, MAXYEAR+1) 28104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_mon, 1) 28114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_mday, 1) 28124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_hour, 23) 28134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_min, 58) 28144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_sec, 37) 28154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_yday, 1) 28164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t.tm_isdst, 0) 28174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 28184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_tzinfo_isoformat(self): 28194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao zero = FixedOffset(0, "+00:00") 28204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao plus = FixedOffset(220, "+03:40") 28214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao minus = FixedOffset(-231, "-03:51") 28224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao unknown = FixedOffset(None, "") 28234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 28244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls = self.theclass 28254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao datestr = '0001-02-03' 28264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for ofs in None, zero, plus, minus, unknown: 28274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for us in 0, 987001: 28284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = cls(1, 2, 3, 4, 5, 59, us, tzinfo=ofs) 28294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao timestr = '04:05:59' + (us and '.987001' or '') 28304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ofsstr = ofs is not None and d.tzname() or '' 28314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao tailstr = timestr + ofsstr 28324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao iso = d.isoformat() 28334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(iso, datestr + 'T' + tailstr) 28344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(iso, d.isoformat('T')) 28354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(d.isoformat('k'), datestr + 'k' + tailstr) 28364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(str(d), datestr + ' ' + tailstr) 28374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 28384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_replace(self): 28394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls = self.theclass 28404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao z100 = FixedOffset(100, "+100") 28414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao zm200 = FixedOffset(timedelta(minutes=-200), "-200") 28424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = [1, 2, 3, 4, 5, 6, 7, z100] 28434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = cls(*args) 28444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(base, base.replace()) 28454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 28464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao i = 0 28474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for name, newval in (("year", 2), 28484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("month", 3), 28494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("day", 4), 28504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("hour", 5), 28514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("minute", 6), 28524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("second", 7), 28534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("microsecond", 8), 28544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ("tzinfo", zm200)): 28554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newargs = args[:] 28564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao newargs[i] = newval 28574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = cls(*newargs) 28584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = base.replace(**{name: newval}) 28594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected, got) 28604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao i += 1 28614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 28624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Ensure we can get rid of a tzinfo. 28634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(base.tzname(), "+100") 28644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base2 = base.replace(tzinfo=None) 28654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(base2.tzinfo is None) 28664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(base2.tzname() is None) 28674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 28684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Ensure we can add one. 28694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base3 = base2.replace(tzinfo=z100) 28704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(base, base3) 28714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(base.tzinfo is base3.tzinfo) 28724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 28734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Out of bounds. 28744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = cls(2000, 2, 29) 28754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, base.replace, year=2001) 28764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 28774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_more_astimezone(self): 28784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # The inherited test_astimezone covered some trivial and error cases. 28794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fnone = FixedOffset(None, "None") 28804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao f44m = FixedOffset(44, "44") 28814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fm5h = FixedOffset(-timedelta(hours=5), "m300") 28824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 28834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt = self.theclass.now(tz=f44m) 28844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(dt.tzinfo is f44m) 28854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Replacing with degenerate tzinfo raises an exception. 28864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, dt.astimezone, fnone) 28874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Ditto with None tz. 28884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, dt.astimezone, None) 28894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Replacing with same tzinfo makes no change. 28904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao x = dt.astimezone(dt.tzinfo) 28914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(x.tzinfo is f44m) 28924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(x.date(), dt.date()) 28934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(x.time(), dt.time()) 28944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 28954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Replacing with different tzinfo does adjust. 28964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = dt.astimezone(fm5h) 28974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(got.tzinfo is fm5h) 28984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(got.utcoffset(), timedelta(hours=-5)) 28994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = dt - dt.utcoffset() # in effect, convert to UTC 29004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected += fm5h.utcoffset(dt) # and from there to local time 29014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = expected.replace(tzinfo=fm5h) # and attach new tzinfo 29024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(got.date(), expected.date()) 29034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(got.time(), expected.time()) 29044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(got.timetz(), expected.timetz()) 29054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(got.tzinfo is expected.tzinfo) 29064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(got, expected) 29074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 29084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_aware_subtract(self): 29094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls = self.theclass 29104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 29114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Ensure that utcoffset() is ignored when the operands have the 29124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # same tzinfo member. 29134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class OperandDependentOffset(tzinfo): 29144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, t): 29154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if t.minute < 10: 29164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # d0 and d1 equal after adjustment 29174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return timedelta(minutes=t.minute) 29184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 29194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # d2 off in the weeds 29204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return timedelta(minutes=59) 29214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 29224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = cls(8, 9, 10, 11, 12, 13, 14, tzinfo=OperandDependentOffset()) 29234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d0 = base.replace(minute=3) 29244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d1 = base.replace(minute=9) 29254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d2 = base.replace(minute=11) 29264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for x in d0, d1, d2: 29274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for y in d0, d1, d2: 29284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = x - y 29294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = timedelta(minutes=x.minute - y.minute) 29304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(got, expected) 29314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 29324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # OTOH, if the tzinfo members are distinct, utcoffsets aren't 29334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # ignored. 29344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao base = cls(8, 9, 10, 11, 12, 13, 14) 29354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d0 = base.replace(minute=3, tzinfo=OperandDependentOffset()) 29364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d1 = base.replace(minute=9, tzinfo=OperandDependentOffset()) 29374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d2 = base.replace(minute=11, tzinfo=OperandDependentOffset()) 29384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for x in d0, d1, d2: 29394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for y in d0, d1, d2: 29404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = x - y 29414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if (x is d0 or x is d1) and (y is d0 or y is d1): 29424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = timedelta(0) 29434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif x is y is d2: 29444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = timedelta(0) 29454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif x is d2: 29464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = timedelta(minutes=(11-59)-0) 29474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 29484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert y is d2 29494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = timedelta(minutes=0-(11-59)) 29504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(got, expected) 29514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 29524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_mixed_compare(self): 29534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = datetime(1, 2, 3, 4, 5, 6, 7) 29544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = datetime(1, 2, 3, 4, 5, 6, 7) 29554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1, t2) 29564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = t2.replace(tzinfo=None) 29574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1, t2) 29584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = t2.replace(tzinfo=FixedOffset(None, "")) 29594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1, t2) 29604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = t2.replace(tzinfo=FixedOffset(0, "")) 29614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: t1 == t2) 29624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 29634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # In datetime w/ identical tzinfo objects, utcoffset is ignored. 29644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class Varies(tzinfo): 29654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self): 29664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.offset = timedelta(minutes=22) 29674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, t): 29684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.offset += timedelta(minutes=1) 29694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.offset 29704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 29714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao v = Varies() 29724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t1 = t2.replace(tzinfo=v) 29734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = t2.replace(tzinfo=v) 29744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1.utcoffset(), timedelta(minutes=23)) 29754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t2.utcoffset(), timedelta(minutes=24)) 29764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(t1, t2) 29774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 29784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # But if they're not identical, it isn't ignored. 29794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao t2 = t2.replace(tzinfo=Varies()) 29804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(t1 < t2) # t1's offset counter still going up 29814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 29824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_subclass_datetimetz(self): 29834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 29844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class C(self.theclass): 29854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao theAnswer = 42 29864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 29874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __new__(cls, *args, **kws): 29884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao temp = kws.copy() 29894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao extra = temp.pop('extra') 29904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao result = self.theclass.__new__(cls, *args, **temp) 29914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao result.extra = extra 29924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return result 29934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 29944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def newmeth(self, start): 29954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return start + self.hour + self.year 29964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 29974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao args = 2002, 12, 31, 4, 5, 6, 500, FixedOffset(-300, "EST", 1) 29984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 29994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt1 = self.theclass(*args) 30004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt2 = C(*args, **{'extra': 7}) 30014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 30024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2.__class__, C) 30034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2.theAnswer, 42) 30044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2.extra, 7) 30054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt1.utcoffset(), dt2.utcoffset()) 30064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt2.newmeth(-7), dt1.hour + dt1.year - 7) 30074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 30084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Pain to set up DST-aware tzinfo classes. 30094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 30104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef first_sunday_on_or_after(dt): 30114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao days_to_go = 6 - dt.weekday() 30124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if days_to_go: 30134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt += timedelta(days_to_go) 30144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return dt 30154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 30164adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoZERO = timedelta(0) 30174adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoHOUR = timedelta(hours=1) 30184adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoDAY = timedelta(days=1) 30194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# In the US, DST starts at 2am (standard time) on the first Sunday in April. 30204adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoDSTSTART = datetime(1, 4, 1, 2) 30214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct, 30224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# which is the first Sunday on or after Oct 25. Because we view 1:MM as 30234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# being standard time on that day, there is no spelling in local time of 30244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# the last hour of DST (that's 1:MM DST, but 1:MM is taken as standard time). 30254adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoDSTEND = datetime(1, 10, 25, 1) 30264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 30274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass USTimeZone(tzinfo): 30284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 30294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self, hours, reprname, stdname, dstname): 30304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.stdoffset = timedelta(hours=hours) 30314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.reprname = reprname 30324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.stdname = stdname 30334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.dstname = dstname 30344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 30354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __repr__(self): 30364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.reprname 30374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 30384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def tzname(self, dt): 30394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if self.dst(dt): 30404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.dstname 30414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 30424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.stdname 30434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 30444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, dt): 30454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self.stdoffset + self.dst(dt) 30464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 30474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def dst(self, dt): 30484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if dt is None or dt.tzinfo is None: 30494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # An exception instead may be sensible here, in one or more of 30504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # the cases. 30514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return ZERO 30524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert dt.tzinfo is self 30534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 30544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Find first Sunday in April. 30554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao start = first_sunday_on_or_after(DSTSTART.replace(year=dt.year)) 30564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert start.weekday() == 6 and start.month == 4 and start.day <= 7 30574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 30584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Find last Sunday in October. 30594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao end = first_sunday_on_or_after(DSTEND.replace(year=dt.year)) 30604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert end.weekday() == 6 and end.month == 10 and end.day >= 25 30614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 30624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Can't compare naive to aware objects, so strip the timezone from 30634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # dt first. 30644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if start <= dt.replace(tzinfo=None) < end: 30654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return HOUR 30664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 30674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return ZERO 30684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 30694adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoEastern = USTimeZone(-5, "Eastern", "EST", "EDT") 30704adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoCentral = USTimeZone(-6, "Central", "CST", "CDT") 30714adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoMountain = USTimeZone(-7, "Mountain", "MST", "MDT") 30724adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoPacific = USTimeZone(-8, "Pacific", "PST", "PDT") 30734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoutc_real = FixedOffset(0, "UTC", 0) 30744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# For better test coverage, we want another flavor of UTC that's west of 30754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# the Eastern and Pacific timezones. 30764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoutc_fake = FixedOffset(-12*60, "UTCfake", 0) 30774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 30784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass TestTimezoneConversions(unittest.TestCase): 30794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # The DST switch times for 2002, in std time. 30804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dston = datetime(2002, 4, 7, 2) 30814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dstoff = datetime(2002, 10, 27, 1) 30824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 30834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao theclass = datetime 30844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 30854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Check a time that's inside DST. 30864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def checkinside(self, dt, tz, utc, dston, dstoff): 30874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.dst(), HOUR) 30884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 30894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Conversion to our own timezone is always an identity. 30904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.astimezone(tz), dt) 30914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 30924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao asutc = dt.astimezone(utc) 30934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao there_and_back = asutc.astimezone(tz) 30944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 30954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Conversion to UTC and back isn't always an identity here, 30964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # because there are redundant spellings (in local time) of 30974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # UTC time when DST begins: the clock jumps from 1:59:59 30984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # to 3:00:00, and a local time of 2:MM:SS doesn't really 30994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # make sense then. The classes above treat 2:MM:SS as 31004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # daylight time then (it's "after 2am"), really an alias 31014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # for 1:MM:SS standard time. The latter form is what 31024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # conversion back from UTC produces. 31034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if dt.date() == dston.date() and dt.hour == 2: 31044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # We're in the redundant hour, and coming back from 31054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # UTC gives the 1:MM:SS standard-time spelling. 31064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(there_and_back + HOUR, dt) 31074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Although during was considered to be in daylight 31084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # time, there_and_back is not. 31094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(there_and_back.dst(), ZERO) 31104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # They're the same times in UTC. 31114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(there_and_back.astimezone(utc), 31124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dt.astimezone(utc)) 31134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 31144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # We're not in the redundant hour. 31154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt, there_and_back) 31164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 31174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Because we have a redundant spelling when DST begins, there is 31184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # (unfortunately) an hour when DST ends that can't be spelled at all in 31194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # local time. When DST ends, the clock jumps from 1:59 back to 1:00 31204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # again. The hour 1:MM DST has no spelling then: 1:MM is taken to be 31214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # standard time. 1:MM DST == 0:MM EST, but 0:MM is taken to be 31224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # daylight time. The hour 1:MM daylight == 0:MM standard can't be 31234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # expressed in local time. Nevertheless, we want conversion back 31244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # from UTC to mimic the local clock's "repeat an hour" behavior. 31254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao nexthour_utc = asutc + HOUR 31264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao nexthour_tz = nexthour_utc.astimezone(tz) 31274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if dt.date() == dstoff.date() and dt.hour == 0: 31284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # We're in the hour before the last DST hour. The last DST hour 31294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # is ineffable. We want the conversion back to repeat 1:MM. 31304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(nexthour_tz, dt.replace(hour=1)) 31314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao nexthour_utc += HOUR 31324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao nexthour_tz = nexthour_utc.astimezone(tz) 31334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(nexthour_tz, dt.replace(hour=1)) 31344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 31354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(nexthour_tz - dt, HOUR) 31364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 31374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Check a time that's outside DST. 31384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def checkoutside(self, dt, tz, utc): 31394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.dst(), ZERO) 31404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 31414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Conversion to our own timezone is always an identity. 31424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt.astimezone(tz), dt) 31434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 31444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Converting to UTC and back is an identity too. 31454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao asutc = dt.astimezone(utc) 31464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao there_and_back = asutc.astimezone(tz) 31474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(dt, there_and_back) 31484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 31494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def convert_between_tz_and_utc(self, tz, utc): 31504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dston = self.dston.replace(tzinfo=tz) 31514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Because 1:MM on the day DST ends is taken as being standard time, 31524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # there is no spelling in tz for the last hour of daylight time. 31534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # For purposes of the test, the last hour of DST is 0:MM, which is 31544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # taken as being daylight time (and 1:MM is taken as being standard 31554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # time). 31564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao dstoff = self.dstoff.replace(tzinfo=tz) 31574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for delta in (timedelta(weeks=13), 31584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao DAY, 31594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao HOUR, 31604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao timedelta(minutes=1), 31614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao timedelta(microseconds=1)): 31624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 31634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.checkinside(dston, tz, utc, dston, dstoff) 31644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for during in dston + delta, dstoff - delta: 31654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.checkinside(during, tz, utc, dston, dstoff) 31664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 31674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.checkoutside(dstoff, tz, utc) 31684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for outside in dston - delta, dstoff + delta: 31694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.checkoutside(outside, tz, utc) 31704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 31714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_easy(self): 31724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Despite the name of this test, the endcases are excruciating. 31734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.convert_between_tz_and_utc(Eastern, utc_real) 31744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.convert_between_tz_and_utc(Pacific, utc_real) 31754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.convert_between_tz_and_utc(Eastern, utc_fake) 31764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.convert_between_tz_and_utc(Pacific, utc_fake) 31774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # The next is really dancing near the edge. It works because 31784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Pacific and Eastern are far enough apart that their "problem 31794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # hours" don't overlap. 31804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.convert_between_tz_and_utc(Eastern, Pacific) 31814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.convert_between_tz_and_utc(Pacific, Eastern) 31824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # OTOH, these fail! Don't enable them. The difficulty is that 31834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # the edge case tests assume that every hour is representable in 31844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # the "utc" class. This is always true for a fixed-offset tzinfo 31854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # class (lke utc_real and utc_fake), but not for Eastern or Central. 31864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # For these adjacent DST-aware time zones, the range of time offsets 31874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # tested ends up creating hours in the one that aren't representable 31884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # in the other. For the same reason, we would see failures in the 31894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Eastern vs Pacific tests too if we added 3*HOUR to the list of 31904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # offset deltas in convert_between_tz_and_utc(). 31914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # 31924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # self.convert_between_tz_and_utc(Eastern, Central) # can't work 31934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # self.convert_between_tz_and_utc(Central, Eastern) # can't work 31944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 31954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_tricky(self): 31964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # 22:00 on day before daylight starts. 31974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fourback = self.dston - timedelta(hours=4) 31984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ninewest = FixedOffset(-9*60, "-0900", 0) 31994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fourback = fourback.replace(tzinfo=ninewest) 32004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # 22:00-0900 is 7:00 UTC == 2:00 EST == 3:00 DST. Since it's "after 32014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # 2", we should get the 3 spelling. 32024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # If we plug 22:00 the day before into Eastern, it "looks like std 32034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # time", so its offset is returned as -5, and -5 - -9 = 4. Adding 4 32044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # to 22:00 lands on 2:00, which makes no sense in local time (the 32054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # local clock jumps from 1 to 3). The point here is to make sure we 32064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # get the 3 spelling. 32074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = self.dston.replace(hour=3) 32084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = fourback.astimezone(Eastern).replace(tzinfo=None) 32094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected, got) 32104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 32114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Similar, but map to 6:00 UTC == 1:00 EST == 2:00 DST. In that 32124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # case we want the 1:00 spelling. 32134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao sixutc = self.dston.replace(hour=6, tzinfo=utc_real) 32144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Now 6:00 "looks like daylight", so the offset wrt Eastern is -4, 32154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # and adding -4-0 == -4 gives the 2:00 spelling. We want the 1:00 EST 32164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # spelling. 32174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = self.dston.replace(hour=1) 32184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = sixutc.astimezone(Eastern).replace(tzinfo=None) 32194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected, got) 32204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 32214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Now on the day DST ends, we want "repeat an hour" behavior. 32224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # UTC 4:MM 5:MM 6:MM 7:MM checking these 32234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # EST 23:MM 0:MM 1:MM 2:MM 32244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # EDT 0:MM 1:MM 2:MM 3:MM 32254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # wall 0:MM 1:MM 1:MM 2:MM against these 32264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for utc in utc_real, utc_fake: 32274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for tz in Eastern, Pacific: 32284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao first_std_hour = self.dstoff - timedelta(hours=2) # 23:MM 32294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Convert that to UTC. 32304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao first_std_hour -= tz.utcoffset(None) 32314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Adjust for possibly fake UTC. 32324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao asutc = first_std_hour + utc.utcoffset(None) 32334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # First UTC hour to convert; this is 4:00 when utc=utc_real & 32344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # tz=Eastern. 32354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao asutcbase = asutc.replace(tzinfo=utc) 32364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for tzhour in (0, 1, 1, 2): 32374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expectedbase = self.dstoff.replace(hour=tzhour) 32384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for minute in 0, 30, 59: 32394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = expectedbase.replace(minute=minute) 32404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao asutc = asutcbase.replace(minute=minute) 32414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao astz = asutc.astimezone(tz) 32424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(astz.replace(tzinfo=None), expected) 32434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao asutcbase += HOUR 32444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 32454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 32464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_bogus_dst(self): 32474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class ok(tzinfo): 32484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def utcoffset(self, dt): return HOUR 32494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def dst(self, dt): return HOUR 32504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 32514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao now = self.theclass.now().replace(tzinfo=utc_real) 32524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Doesn't blow up. 32534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao now.astimezone(ok()) 32544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 32554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Does blow up. 32564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class notok(ok): 32574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def dst(self, dt): return None 32584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, now.astimezone, notok()) 32594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 32604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_fromutc(self): 32614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, Eastern.fromutc) # not enough args 32624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao now = datetime.utcnow().replace(tzinfo=utc_real) 32634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(ValueError, Eastern.fromutc, now) # wrong tzinfo 32644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao now = now.replace(tzinfo=Eastern) # insert correct tzinfo 32654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao enow = Eastern.fromutc(now) # doesn't blow up 32664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(enow.tzinfo, Eastern) # has right tzinfo member 32674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, Eastern.fromutc, now, now) # too many args 32684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, Eastern.fromutc, date.today()) # wrong type 32694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 32704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Always converts UTC to standard time. 32714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao class FauxUSTimeZone(USTimeZone): 32724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def fromutc(self, dt): 32734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return dt + self.stdoffset 32744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao FEastern = FauxUSTimeZone(-5, "FEastern", "FEST", "FEDT") 32754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 32764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # UTC 4:MM 5:MM 6:MM 7:MM 8:MM 9:MM 32774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # EST 23:MM 0:MM 1:MM 2:MM 3:MM 4:MM 32784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # EDT 0:MM 1:MM 2:MM 3:MM 4:MM 5:MM 32794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 32804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Check around DST start. 32814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao start = self.dston.replace(hour=4, tzinfo=Eastern) 32824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fstart = start.replace(tzinfo=FEastern) 32834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for wall in 23, 0, 1, 3, 4, 5: 32844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = start.replace(hour=wall) 32854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if wall == 23: 32864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected -= timedelta(days=1) 32874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = Eastern.fromutc(start) 32884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected, got) 32894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 32904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = fstart + FEastern.stdoffset 32914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = FEastern.fromutc(fstart) 32924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected, got) 32934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 32944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Ensure astimezone() calls fromutc() too. 32954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = fstart.replace(tzinfo=utc_real).astimezone(FEastern) 32964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected, got) 32974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 32984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao start += HOUR 32994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fstart += HOUR 33004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 33014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Check around DST end. 33024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao start = self.dstoff.replace(hour=4, tzinfo=Eastern) 33034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fstart = start.replace(tzinfo=FEastern) 33044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for wall in 0, 1, 1, 2, 3, 4: 33054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = start.replace(hour=wall) 33064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = Eastern.fromutc(start) 33074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected, got) 33084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 33094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao expected = fstart + FEastern.stdoffset 33104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = FEastern.fromutc(fstart) 33114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected, got) 33124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 33134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Ensure astimezone() calls fromutc() too. 33144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao got = fstart.replace(tzinfo=utc_real).astimezone(FEastern) 33154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(expected, got) 33164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 33174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao start += HOUR 33184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao fstart += HOUR 33194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 33204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 33214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao############################################################################# 33224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# oddballs 33234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 33244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass Oddballs(unittest.TestCase): 33254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 33264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_bug_1028306(self): 33274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Trying to compare a date to a datetime should act like a mixed- 33284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # type comparison, despite that datetime is a subclass of date. 33294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao as_date = date.today() 33304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao as_datetime = datetime.combine(as_date, time()) 33314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(as_date != as_datetime) 33324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(as_datetime != as_date) 33334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not as_date == as_datetime) 33344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not as_datetime == as_date) 33354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: as_date < as_datetime) 33364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: as_datetime < as_date) 33374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: as_date <= as_datetime) 33384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: as_datetime <= as_date) 33394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: as_date > as_datetime) 33404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: as_datetime > as_date) 33414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: as_date >= as_datetime) 33424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertRaises(TypeError, lambda: as_datetime >= as_date) 33434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 33444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Neverthelss, comparison should work with the base-class (date) 33454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # projection if use of a date method is forced. 33464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(as_date.__eq__(as_datetime)) 33474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao different_day = (as_date.day + 1) % 20 + 1 33484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertTrue(not as_date.__eq__(as_datetime.replace(day= 33494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao different_day))) 33504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 33514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # And date should compare with other subclasses of date. If a 33524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # subclass wants to stop this, it's up to the subclass to do so. 33534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao date_sc = SubclassDate(as_date.year, as_date.month, as_date.day) 33544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(as_date, date_sc) 33554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(date_sc, as_date) 33564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 33574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Ditto for datetimes. 33584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao datetime_sc = SubclassDatetime(as_datetime.year, as_datetime.month, 33594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao as_date.day, 0, 0, 0) 33604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(as_datetime, datetime_sc) 33614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(datetime_sc, as_datetime) 33624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 33634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef test_main(): 33644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao test_support.run_unittest(__name__) 33654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 33664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoif __name__ == "__main__": 33674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao test_main() 3368