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