10a8c90248264a8b26970b4473770bcc3df8515fJosh Gao"""Test date/time type.
20a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30a8c90248264a8b26970b4473770bcc3df8515fJosh GaoSee http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases
40a8c90248264a8b26970b4473770bcc3df8515fJosh Gao"""
50a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom __future__ import division
60a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport sys
70a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport pickle
80a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport cPickle
90a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport unittest
100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
110a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom test import test_support
120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
130a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom datetime import MINYEAR, MAXYEAR
140a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom datetime import timedelta
150a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom datetime import tzinfo
160a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom datetime import time
170a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom datetime import date, datetime
180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
190a8c90248264a8b26970b4473770bcc3df8515fJosh Gaopickle_choices = [(pickler, unpickler, proto)
200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                  for pickler in pickle, cPickle
210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                  for unpickler in pickle, cPickle
220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                  for proto in range(3)]
230a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoassert len(pickle_choices) == 2*2*3
240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# An arbitrary collection of objects of non-datetime types, for testing
260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# mixed-type comparisons.
270a8c90248264a8b26970b4473770bcc3df8515fJosh GaoOTHERSTUFF = (10, 10L, 34.5, "abc", {}, [], ())
280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#############################################################################
310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# module tests
320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
330a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestModule(unittest.TestCase):
340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_constants(self):
360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        import datetime
370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(datetime.MINYEAR, 1)
380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(datetime.MAXYEAR, 9999)
390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#############################################################################
410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# tzinfo tests
420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
430a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass FixedOffset(tzinfo):
440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, offset, name, dstoffset=42):
450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if isinstance(offset, int):
460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            offset = timedelta(minutes=offset)
470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if isinstance(dstoffset, int):
480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            dstoffset = timedelta(minutes=dstoffset)
490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.__offset = offset
500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.__name = name
510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.__dstoffset = dstoffset
520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __repr__(self):
530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.__name.lower()
540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def utcoffset(self, dt):
550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.__offset
560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def tzname(self, dt):
570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.__name
580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def dst(self, dt):
590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.__dstoffset
600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
610a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass PicklableFixedOffset(FixedOffset):
620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, offset=None, name=None, dstoffset=None):
630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        FixedOffset.__init__(self, offset, name, dstoffset)
640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
650a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestTZInfo(unittest.TestCase):
660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_non_abstractness(self):
680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # In order to allow subclasses to get pickled, the C implementation
690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # wasn't able to get away with having __init__ raise
700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # NotImplementedError.
710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        useless = tzinfo()
720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt = datetime.max
730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(NotImplementedError, useless.tzname, dt)
740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(NotImplementedError, useless.utcoffset, dt)
750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(NotImplementedError, useless.dst, dt)
760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_subclass_must_override(self):
780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class NotEnough(tzinfo):
790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __init__(self, offset, name):
800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.__offset = offset
810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.__name = name
820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(issubclass(NotEnough, tzinfo))
830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        ne = NotEnough(3, "NotByALongShot")
840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIsInstance(ne, tzinfo)
850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt = datetime.now()
870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(NotImplementedError, ne.tzname, dt)
880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(NotImplementedError, ne.utcoffset, dt)
890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(NotImplementedError, ne.dst, dt)
900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_normal(self):
920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fo = FixedOffset(3, "Three")
930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIsInstance(fo, tzinfo)
940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for dt in datetime.now(), None:
950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(fo.utcoffset(dt), timedelta(minutes=3))
960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(fo.tzname(dt), "Three")
970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(fo.dst(dt), timedelta(minutes=42))
980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_pickling_base(self):
1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # There's no point to pickling tzinfo objects on their own (they
1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # carry no data), but they need to be picklable anyway else
1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # concrete subclasses can't be pickled.
1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        orig = tzinfo.__new__(tzinfo)
1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(type(orig) is tzinfo)
1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for pickler, unpickler, proto in pickle_choices:
1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            green = pickler.dumps(orig, proto)
1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            derived = unpickler.loads(green)
1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(type(derived) is tzinfo)
1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_pickling_subclass(self):
1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Make sure we can pickle/unpickle an instance of a subclass.
1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        offset = timedelta(minutes=-300)
1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        orig = PicklableFixedOffset(offset, 'cookie')
1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIsInstance(orig, tzinfo)
1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(type(orig) is PicklableFixedOffset)
1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(orig.utcoffset(None), offset)
1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(orig.tzname(None), 'cookie')
1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for pickler, unpickler, proto in pickle_choices:
1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            green = pickler.dumps(orig, proto)
1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            derived = unpickler.loads(green)
1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertIsInstance(derived, tzinfo)
1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(type(derived) is PicklableFixedOffset)
1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(derived.utcoffset(None), offset)
1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(derived.tzname(None), 'cookie')
1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#############################################################################
1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Base clase for testing a particular aspect of timedelta, time, date and
1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# datetime comparisons.
1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass HarmlessMixedComparison:
1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Test that __eq__ and __ne__ don't complain for mixed-type comparisons.
1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Subclasses must define 'theclass', and theclass(1, 1, 1) must be a
1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # legit constructor.
1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_harmless_mixed_comparison(self):
1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        me = self.theclass(1, 1, 1)
1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertFalse(me == ())
1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(me != ())
1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertFalse(() == me)
1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(() != me)
1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(me, [1, 20L, [], me])
1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn([], [me, 1, 20L, []])
1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_harmful_mixed_comparison(self):
1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        me = self.theclass(1, 1, 1)
1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: me < ())
1510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: me <= ())
1520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: me > ())
1530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: me >= ())
1540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: () < me)
1560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: () <= me)
1570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: () > me)
1580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: () >= me)
1590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, cmp, (), me)
1610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, cmp, me, ())
1620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#############################################################################
1640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# timedelta tests
1650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1660a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestTimeDelta(HarmlessMixedComparison, unittest.TestCase):
1670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    theclass = timedelta
1690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_constructor(self):
1710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq = self.assertEqual
1720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        td = timedelta
1730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Check keyword args to constructor
1750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(), td(weeks=0, days=0, hours=0, minutes=0, seconds=0,
1760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    milliseconds=0, microseconds=0))
1770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(1), td(days=1))
1780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(0, 1), td(seconds=1))
1790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(0, 0, 1), td(microseconds=1))
1800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(weeks=1), td(days=7))
1810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(days=1), td(hours=24))
1820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(hours=1), td(minutes=60))
1830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(minutes=1), td(seconds=60))
1840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(seconds=1), td(milliseconds=1000))
1850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(milliseconds=1), td(microseconds=1000))
1860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Check float args to constructor
1880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(weeks=1.0/7), td(days=1))
1890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(days=1.0/24), td(hours=1))
1900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(hours=1.0/60), td(minutes=1))
1910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(minutes=1.0/60), td(seconds=1))
1920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(seconds=0.001), td(milliseconds=1))
1930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(milliseconds=0.001), td(microseconds=1))
1940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_computations(self):
1960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq = self.assertEqual
1970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        td = timedelta
1980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a = td(7) # One week
2000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        b = td(0, 60) # One minute
2010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        c = td(0, 0, 1000) # One millisecond
2020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(a+b+c, td(7, 60, 1000))
2030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(a-b, td(6, 24*3600 - 60))
2040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(-a, td(-7))
2050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(+a, td(7))
2060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(-b, td(-1, 24*3600 - 60))
2070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(-c, td(-1, 24*3600 - 1, 999000))
2080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(abs(a), a)
2090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(abs(-a), a)
2100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(6, 24*3600), a)
2110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(0, 0, 60*1000000), b)
2120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(a*10, td(70))
2130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(a*10, 10*a)
2140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(a*10L, 10*a)
2150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(b*10, td(0, 600))
2160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(10*b, td(0, 600))
2170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(b*10L, td(0, 600))
2180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(c*10, td(0, 0, 10000))
2190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(10*c, td(0, 0, 10000))
2200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(c*10L, td(0, 0, 10000))
2210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(a*-1, -a)
2220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(b*-2, -b-b)
2230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(c*-2, -c+-c)
2240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(b*(60*24), (b*60)*24)
2250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(b*(60*24), (60*b)*24)
2260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(c*1000, td(0, 1))
2270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(1000*c, td(0, 1))
2280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(a//7, td(1))
2290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(b//10, td(0, 6))
2300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(c//1000, td(0, 0, 1))
2310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(a//10, td(0, 7*24*360))
2320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(a//3600000, td(0, 0, 7*24*1000))
2330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Issue #11576
2350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(999999999, 86399, 999999) - td(999999999, 86399, 999998),
2360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao           td(0, 0, 1))
2370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(999999999, 1, 1) - td(999999999, 1, 0),
2380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao           td(0, 0, 1))
2390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_disallowed_computations(self):
2420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a = timedelta(42)
2430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Add/sub ints, longs, floats should be illegal
2450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for i in 1, 1L, 1.0:
2460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: a+i)
2470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: a-i)
2480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: i+a)
2490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: i-a)
2500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Mul/div by float isn't supported.
2520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        x = 2.3
2530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: a*x)
2540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: x*a)
2550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: a/x)
2560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: x/a)
2570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: a // x)
2580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: x // a)
2590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Division of int by timedelta doesn't make sense.
2610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Division by zero doesn't make sense.
2620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for zero in 0, 0L:
2630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: zero // a)
2640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(ZeroDivisionError, lambda: a // zero)
2650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_basic_attributes(self):
2670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        days, seconds, us = 1, 7, 31
2680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        td = timedelta(days, seconds, us)
2690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(td.days, days)
2700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(td.seconds, seconds)
2710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(td.microseconds, us)
2720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_total_seconds(self):
2740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        td = timedelta(days=365)
2750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(td.total_seconds(), 31536000.0)
2760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for total_seconds in [123456.789012, -123456.789012, 0.123456, 0, 1e6]:
2770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            td = timedelta(seconds=total_seconds)
2780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(td.total_seconds(), total_seconds)
2790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Issue8644: Test that td.total_seconds() has the same
2800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # accuracy as td / timedelta(seconds=1).
2810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for ms in [-1, -2, -123]:
2820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            td = timedelta(microseconds=ms)
2830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(td.total_seconds(),
2840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ((24*3600*td.days + td.seconds)*10**6
2850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                              + td.microseconds)/10**6)
2860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_carries(self):
2880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = timedelta(days=100,
2890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                       weeks=-7,
2900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                       hours=-24*(100-49),
2910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                       minutes=-3,
2920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                       seconds=12,
2930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                       microseconds=(3*60 - 12) * 1e6 + 1)
2940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = timedelta(microseconds=1)
2950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1, t2)
2960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_hash_equality(self):
2980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = timedelta(days=100,
2990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                       weeks=-7,
3000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                       hours=-24*(100-49),
3010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                       minutes=-3,
3020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                       seconds=12,
3030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                       microseconds=(3*60 - 12) * 1000000)
3040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = timedelta()
3050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(hash(t1), hash(t2))
3060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 += timedelta(weeks=7)
3080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 += timedelta(days=7*7)
3090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1, t2)
3100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(hash(t1), hash(t2))
3110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d = {t1: 1}
3130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d[t2] = 2
3140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(len(d), 1)
3150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(d[t1], 2)
3160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_pickling(self):
3180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = 12, 34, 56
3190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        orig = timedelta(*args)
3200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for pickler, unpickler, proto in pickle_choices:
3210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            green = pickler.dumps(orig, proto)
3220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            derived = unpickler.loads(green)
3230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(orig, derived)
3240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_compare(self):
3260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = timedelta(2, 3, 4)
3270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = timedelta(2, 3, 4)
3280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 == t2)
3290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 <= t2)
3300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 >= t2)
3310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not t1 != t2)
3320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not t1 < t2)
3330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not t1 > t2)
3340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(cmp(t1, t2), 0)
3350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(cmp(t2, t1), 0)
3360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for args in (3, 3, 3), (2, 4, 4), (2, 3, 5):
3380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            t2 = timedelta(*args)   # this is larger than t1
3390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t1 < t2)
3400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t2 > t1)
3410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t1 <= t2)
3420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t2 >= t1)
3430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t1 != t2)
3440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t2 != t1)
3450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t1 == t2)
3460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t2 == t1)
3470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t1 > t2)
3480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t2 < t1)
3490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t1 >= t2)
3500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t2 <= t1)
3510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(cmp(t1, t2), -1)
3520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(cmp(t2, t1), 1)
3530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for badarg in OTHERSTUFF:
3550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t1 == badarg, False)
3560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t1 != badarg, True)
3570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(badarg == t1, False)
3580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(badarg != t1, True)
3590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: t1 <= badarg)
3610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: t1 < badarg)
3620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: t1 > badarg)
3630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: t1 >= badarg)
3640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: badarg <= t1)
3650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: badarg < t1)
3660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: badarg > t1)
3670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: badarg >= t1)
3680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_str(self):
3700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        td = timedelta
3710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq = self.assertEqual
3720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(str(td(1)), "1 day, 0:00:00")
3740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(str(td(-1)), "-1 day, 0:00:00")
3750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(str(td(2)), "2 days, 0:00:00")
3760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(str(td(-2)), "-2 days, 0:00:00")
3770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(str(td(hours=12, minutes=58, seconds=59)), "12:58:59")
3790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(str(td(hours=2, minutes=3, seconds=4)), "2:03:04")
3800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(str(td(weeks=-30, hours=23, minutes=12, seconds=34)),
3810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao           "-210 days, 23:12:34")
3820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(str(td(milliseconds=1)), "0:00:00.001000")
3840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(str(td(microseconds=3)), "0:00:00.000003")
3850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(str(td(days=999999999, hours=23, minutes=59, seconds=59,
3870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                   microseconds=999999)),
3880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao           "999999999 days, 23:59:59.999999")
3890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_roundtrip(self):
3910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for td in (timedelta(days=999999999, hours=23, minutes=59,
3920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             seconds=59, microseconds=999999),
3930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                   timedelta(days=-999999999),
3940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                   timedelta(days=1, seconds=2, microseconds=3)):
3950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Verify td -> string -> td identity.
3970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            s = repr(td)
3980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(s.startswith('datetime.'))
3990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            s = s[9:]
4000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            td2 = eval(s)
4010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(td, td2)
4020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Verify identity via reconstructing from pieces.
4040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            td2 = timedelta(td.days, td.seconds, td.microseconds)
4050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(td, td2)
4060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_resolution_info(self):
4080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIsInstance(timedelta.min, timedelta)
4090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIsInstance(timedelta.max, timedelta)
4100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIsInstance(timedelta.resolution, timedelta)
4110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(timedelta.max > timedelta.min)
4120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(timedelta.min, timedelta(-999999999))
4130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(timedelta.max, timedelta(999999999, 24*3600-1, 1e6-1))
4140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(timedelta.resolution, timedelta(0, 0, 1))
4150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_overflow(self):
4170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        tiny = timedelta.resolution
4180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        td = timedelta.min + tiny
4200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        td -= tiny  # no problem
4210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(OverflowError, td.__sub__, tiny)
4220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(OverflowError, td.__add__, -tiny)
4230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        td = timedelta.max - tiny
4250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        td += tiny  # no problem
4260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(OverflowError, td.__add__, tiny)
4270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(OverflowError, td.__sub__, -tiny)
4280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(OverflowError, lambda: -timedelta.max)
4300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_microsecond_rounding(self):
4320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        td = timedelta
4330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq = self.assertEqual
4340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Single-field rounding.
4360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(milliseconds=0.4/1000), td(0))    # rounds to 0
4370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(milliseconds=-0.4/1000), td(0))    # rounds to 0
4380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(milliseconds=0.6/1000), td(microseconds=1))
4390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(milliseconds=-0.6/1000), td(microseconds=-1))
4400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Rounding due to contributions from more than one field.
4420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        us_per_hour = 3600e6
4430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        us_per_day = us_per_hour * 24
4440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(days=.4/us_per_day), td(0))
4450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(hours=.2/us_per_hour), td(0))
4460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(days=.4/us_per_day, hours=.2/us_per_hour), td(microseconds=1))
4470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(days=-.4/us_per_day), td(0))
4490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(hours=-.2/us_per_hour), td(0))
4500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        eq(td(days=-.4/us_per_day, hours=-.2/us_per_hour), td(microseconds=-1))
4510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_massive_normalization(self):
4530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        td = timedelta(microseconds=-1)
4540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual((td.days, td.seconds, td.microseconds),
4550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         (-1, 24*3600-1, 999999))
4560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_bool(self):
4580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(timedelta(1))
4590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(timedelta(0, 1))
4600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(timedelta(0, 0, 1))
4610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(timedelta(microseconds=1))
4620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not timedelta(0))
4630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_subclass_timedelta(self):
4650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class T(timedelta):
4670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            @staticmethod
4680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def from_td(td):
4690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return T(td.days, td.seconds, td.microseconds)
4700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def as_hours(self):
4720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                sum = (self.days * 24 +
4730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                       self.seconds / 3600.0 +
4740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                       self.microseconds / 3600e6)
4750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return round(sum)
4760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = T(days=1)
4780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(type(t1) is T)
4790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1.as_hours(), 24)
4800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = T(days=-1, seconds=-3600)
4820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(type(t2) is T)
4830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t2.as_hours(), -25)
4840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t3 = t1 + t2
4860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(type(t3) is timedelta)
4870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t4 = T.from_td(t3)
4880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(type(t4) is T)
4890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t3.days, t4.days)
4900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t3.seconds, t4.seconds)
4910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t3.microseconds, t4.microseconds)
4920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(str(t3), str(t4))
4930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t4.as_hours(), -1)
4940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#############################################################################
4960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# date tests
4970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4980a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestDateOnly(unittest.TestCase):
4990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Tests here won't pass if also run on datetime objects, so don't
5000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # subclass this to test datetimes too.
5010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_delta_non_days_ignored(self):
5030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt = date(2000, 1, 2)
5040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        delta = timedelta(days=1, hours=2, minutes=3, seconds=4,
5050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          microseconds=5)
5060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        days = timedelta(delta.days)
5070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(days, timedelta(1))
5080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt2 = dt + delta
5100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2, dt + days)
5110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt2 = delta + dt
5130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2, dt + days)
5140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt2 = dt - delta
5160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2, dt - days)
5170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        delta = -delta
5190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        days = timedelta(delta.days)
5200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(days, timedelta(-2))
5210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt2 = dt + delta
5230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2, dt + days)
5240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt2 = delta + dt
5260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2, dt + days)
5270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt2 = dt - delta
5290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2, dt - days)
5300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5310a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass SubclassDate(date):
5320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    sub_var = 1
5330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5340a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestDate(HarmlessMixedComparison, unittest.TestCase):
5350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Tests here should pass for both dates and datetimes, except for a
5360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # few tests that TestDateTime overrides.
5370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    theclass = date
5390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_basic_attributes(self):
5410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt = self.theclass(2002, 3, 1)
5420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.year, 2002)
5430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.month, 3)
5440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.day, 1)
5450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_roundtrip(self):
5470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for dt in (self.theclass(1, 2, 3),
5480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                   self.theclass.today()):
5490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Verify dt -> string -> date identity.
5500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            s = repr(dt)
5510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(s.startswith('datetime.'))
5520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            s = s[9:]
5530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            dt2 = eval(s)
5540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(dt, dt2)
5550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Verify identity via reconstructing from pieces.
5570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            dt2 = self.theclass(dt.year, dt.month, dt.day)
5580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(dt, dt2)
5590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_ordinal_conversions(self):
5610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Check some fixed values.
5620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for y, m, d, n in [(1, 1, 1, 1),      # calendar origin
5630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           (1, 12, 31, 365),
5640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           (2, 1, 1, 366),
5650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           # first example from "Calendrical Calculations"
5660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           (1945, 11, 12, 710347)]:
5670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d = self.theclass(y, m, d)
5680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(n, d.toordinal())
5690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fromord = self.theclass.fromordinal(n)
5700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(d, fromord)
5710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if hasattr(fromord, "hour"):
5720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # if we're checking something fancier than a date, verify
5730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # the extra fields have been zeroed out
5740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(fromord.hour, 0)
5750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(fromord.minute, 0)
5760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(fromord.second, 0)
5770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(fromord.microsecond, 0)
5780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Check first and last days of year spottily across the whole
5800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # range of years supported.
5810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for year in xrange(MINYEAR, MAXYEAR+1, 7):
5820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Verify (year, 1, 1) -> ordinal -> y, m, d is identity.
5830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d = self.theclass(year, 1, 1)
5840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            n = d.toordinal()
5850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d2 = self.theclass.fromordinal(n)
5860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(d, d2)
5870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Verify that moving back a day gets to the end of year-1.
5880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if year > 1:
5890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                d = self.theclass.fromordinal(n-1)
5900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                d2 = self.theclass(year-1, 12, 31)
5910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(d, d2)
5920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(d2.toordinal(), n-1)
5930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test every day in a leap-year and a non-leap year.
5950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dim = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
5960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for year, isleap in (2000, True), (2002, False):
5970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            n = self.theclass(year, 1, 1).toordinal()
5980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for month, maxday in zip(range(1, 13), dim):
5990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if month == 2 and isleap:
6000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    maxday += 1
6010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                for day in range(1, maxday+1):
6020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    d = self.theclass(year, month, day)
6030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.assertEqual(d.toordinal(), n)
6040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.assertEqual(d, self.theclass.fromordinal(n))
6050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    n += 1
6060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_extreme_ordinals(self):
6080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a = self.theclass.min
6090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a = self.theclass(a.year, a.month, a.day)  # get rid of time parts
6100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        aord = a.toordinal()
6110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        b = a.fromordinal(aord)
6120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a, b)
6130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, lambda: a.fromordinal(aord - 1))
6150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        b = a + timedelta(days=1)
6170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(b.toordinal(), aord + 1)
6180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(b, self.theclass.fromordinal(aord + 1))
6190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a = self.theclass.max
6210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a = self.theclass(a.year, a.month, a.day)  # get rid of time parts
6220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        aord = a.toordinal()
6230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        b = a.fromordinal(aord)
6240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a, b)
6250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, lambda: a.fromordinal(aord + 1))
6270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        b = a - timedelta(days=1)
6290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(b.toordinal(), aord - 1)
6300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(b, self.theclass.fromordinal(aord - 1))
6310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_bad_constructor_arguments(self):
6330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # bad years
6340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(MINYEAR, 1, 1)  # no exception
6350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(MAXYEAR, 1, 1)  # no exception
6360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, MINYEAR-1, 1, 1)
6370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, MAXYEAR+1, 1, 1)
6380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # bad months
6390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(2000, 1, 1)    # no exception
6400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(2000, 12, 1)   # no exception
6410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 2000, 0, 1)
6420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 2000, 13, 1)
6430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # bad days
6440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(2000, 2, 29)   # no exception
6450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(2004, 2, 29)   # no exception
6460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(2400, 2, 29)   # no exception
6470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 2000, 2, 30)
6480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 2001, 2, 29)
6490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 2100, 2, 29)
6500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 1900, 2, 29)
6510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 2000, 1, 0)
6520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 2000, 1, 32)
6530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_hash_equality(self):
6550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d = self.theclass(2000, 12, 31)
6560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # same thing
6570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        e = self.theclass(2000, 12, 31)
6580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(d, e)
6590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(hash(d), hash(e))
6600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dic = {d: 1}
6620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dic[e] = 2
6630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(len(dic), 1)
6640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dic[d], 2)
6650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dic[e], 2)
6660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d = self.theclass(2001,  1,  1)
6680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # same thing
6690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        e = self.theclass(2001,  1,  1)
6700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(d, e)
6710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(hash(d), hash(e))
6720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dic = {d: 1}
6740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dic[e] = 2
6750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(len(dic), 1)
6760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dic[d], 2)
6770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dic[e], 2)
6780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_computations(self):
6800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a = self.theclass(2002, 1, 31)
6810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        b = self.theclass(1956, 1, 31)
6820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        diff = a-b
6840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(diff.days, 46*365 + len(range(1956, 2002, 4)))
6850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(diff.seconds, 0)
6860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(diff.microseconds, 0)
6870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        day = timedelta(1)
6890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        week = timedelta(7)
6900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a = self.theclass(2002, 3, 2)
6910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a + day, self.theclass(2002, 3, 3))
6920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(day + a, self.theclass(2002, 3, 3))
6930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - day, self.theclass(2002, 3, 1))
6940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(-day + a, self.theclass(2002, 3, 1))
6950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a + week, self.theclass(2002, 3, 9))
6960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - week, self.theclass(2002, 2, 23))
6970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a + 52*week, self.theclass(2003, 3, 1))
6980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - 52*week, self.theclass(2001, 3, 3))
6990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual((a + week) - a, week)
7000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual((a + day) - a, day)
7010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual((a - week) - a, -week)
7020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual((a - day) - a, -day)
7030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - (a + week), -week)
7040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - (a + day), -day)
7050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - (a - week), week)
7060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - (a - day), day)
7070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Add/sub ints, longs, floats should be illegal
7090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for i in 1, 1L, 1.0:
7100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: a+i)
7110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: a-i)
7120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: i+a)
7130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: i-a)
7140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # delta - date is senseless.
7160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: day - a)
7170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # mixing date and (delta or date) via * or // is senseless
7180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: day * a)
7190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: a * day)
7200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: day // a)
7210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: a // day)
7220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: a * a)
7230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: a // a)
7240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # date + date is senseless
7250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: a + a)
7260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_overflow(self):
7280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        tiny = self.theclass.resolution
7290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for delta in [tiny, timedelta(1), timedelta(2)]:
7310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            dt = self.theclass.min + delta
7320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            dt -= delta  # no problem
7330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(OverflowError, dt.__sub__, delta)
7340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(OverflowError, dt.__add__, -delta)
7350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            dt = self.theclass.max - delta
7370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            dt += delta  # no problem
7380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(OverflowError, dt.__add__, delta)
7390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(OverflowError, dt.__sub__, -delta)
7400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_fromtimestamp(self):
7420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        import time
7430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Try an arbitrary fixed value.
7450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        year, month, day = 1999, 9, 19
7460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        ts = time.mktime((year, month, day, 0, 0, 0, 0, 0, -1))
7470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d = self.theclass.fromtimestamp(ts)
7480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(d.year, year)
7490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(d.month, month)
7500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(d.day, day)
7510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_insane_fromtimestamp(self):
7530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # It's possible that some platform maps time_t to double,
7540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # and that this test will fail there.  This test should
7550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # exempt such platforms (provided they return reasonable
7560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # results!).
7570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for insane in -1e200, 1e200:
7580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(ValueError, self.theclass.fromtimestamp,
7590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                              insane)
7600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_today(self):
7620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        import time
7630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # We claim that today() is like fromtimestamp(time.time()), so
7650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # prove it.
7660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for dummy in range(3):
7670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            today = self.theclass.today()
7680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ts = time.time()
7690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            todayagain = self.theclass.fromtimestamp(ts)
7700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if today == todayagain:
7710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                break
7720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # There are several legit reasons that could fail:
7730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # 1. It recently became midnight, between the today() and the
7740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            #    time() calls.
7750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # 2. The platform time() has such fine resolution that we'll
7760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            #    never get the same value twice.
7770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # 3. The platform time() has poor resolution, and we just
7780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            #    happened to call today() right before a resolution quantum
7790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            #    boundary.
7800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # 4. The system clock got fiddled between calls.
7810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # In any case, wait a little while and try again.
7820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            time.sleep(0.1)
7830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # It worked or it didn't.  If it didn't, assume it's reason #2, and
7850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # let the test pass if they're within half a second of each other.
7860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(today == todayagain or
7870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        abs(todayagain - today) < timedelta(seconds=0.5))
7880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_weekday(self):
7900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for i in range(7):
7910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # March 4, 2002 is a Monday
7920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(self.theclass(2002, 3, 4+i).weekday(), i)
7930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(self.theclass(2002, 3, 4+i).isoweekday(), i+1)
7940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # January 2, 1956 is a Monday
7950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(self.theclass(1956, 1, 2+i).weekday(), i)
7960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(self.theclass(1956, 1, 2+i).isoweekday(), i+1)
7970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_isocalendar(self):
7990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Check examples from
8000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm
8010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for i in range(7):
8020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d = self.theclass(2003, 12, 22+i)
8030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(d.isocalendar(), (2003, 52, i+1))
8040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d = self.theclass(2003, 12, 29) + timedelta(i)
8050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(d.isocalendar(), (2004, 1, i+1))
8060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d = self.theclass(2004, 1, 5+i)
8070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(d.isocalendar(), (2004, 2, i+1))
8080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d = self.theclass(2009, 12, 21+i)
8090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(d.isocalendar(), (2009, 52, i+1))
8100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d = self.theclass(2009, 12, 28) + timedelta(i)
8110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(d.isocalendar(), (2009, 53, i+1))
8120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d = self.theclass(2010, 1, 4+i)
8130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(d.isocalendar(), (2010, 1, i+1))
8140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_iso_long_years(self):
8160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Calculate long ISO years and compare to table from
8170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm
8180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        ISO_LONG_YEARS_TABLE = """
8190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao              4   32   60   88
8200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao              9   37   65   93
8210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao             15   43   71   99
8220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao             20   48   76
8230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao             26   54   82
8240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            105  133  161  189
8260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            111  139  167  195
8270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            116  144  172
8280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            122  150  178
8290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            128  156  184
8300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            201  229  257  285
8320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            207  235  263  291
8330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            212  240  268  296
8340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            218  246  274
8350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            224  252  280
8360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            303  331  359  387
8380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            308  336  364  392
8390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            314  342  370  398
8400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            320  348  376
8410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            325  353  381
8420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
8430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        iso_long_years = map(int, ISO_LONG_YEARS_TABLE.split())
8440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        iso_long_years.sort()
8450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        L = []
8460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for i in range(400):
8470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d = self.theclass(2000+i, 12, 31)
8480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d1 = self.theclass(1600+i, 12, 31)
8490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(d.isocalendar()[1:], d1.isocalendar()[1:])
8500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if d.isocalendar()[1] == 53:
8510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                L.append(i)
8520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(L, iso_long_years)
8530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_isoformat(self):
8550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(2, 3, 2)
8560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(), "0002-03-02")
8570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_ctime(self):
8590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(2002, 3, 2)
8600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.ctime(), "Sat Mar  2 00:00:00 2002")
8610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_strftime(self):
8630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(2005, 3, 2)
8640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.strftime("m:%m d:%d y:%y"), "m:03 d:02 y:05")
8650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.strftime(""), "") # SF bug #761337
8660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.strftime('x'*1000), 'x'*1000) # SF bug #1556784
8670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, t.strftime) # needs an arg
8690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, t.strftime, "one", "two") # too many args
8700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, t.strftime, 42) # arg wrong type
8710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # test that unicode input is allowed (issue 2782)
8730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.strftime(u"%m"), "03")
8740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # A naive object replaces %z and %Z w/ empty strings.
8760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''")
8770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #make sure that invalid format specifiers are handled correctly
8790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #self.assertRaises(ValueError, t.strftime, "%e")
8800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #self.assertRaises(ValueError, t.strftime, "%")
8810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #self.assertRaises(ValueError, t.strftime, "%#")
8820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #oh well, some systems just ignore those invalid ones.
8840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #at least, excercise them to make sure that no crashes
8850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #are generated
8860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for f in ["%e", "%", "%#"]:
8870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            try:
8880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                t.strftime(f)
8890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            except ValueError:
8900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                pass
8910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #check that this standard extension works
8930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t.strftime("%f")
8940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_format(self):
8970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt = self.theclass(2007, 9, 10)
8980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.__format__(''), str(dt))
8990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # check that a derived class's __str__() gets called
9010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class A(self.theclass):
9020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __str__(self):
9030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return 'A'
9040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a = A(2007, 9, 10)
9050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a.__format__(''), 'A')
9060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # check that a derived class's strftime gets called
9080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class B(self.theclass):
9090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def strftime(self, format_spec):
9100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return 'B'
9110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        b = B(2007, 9, 10)
9120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(b.__format__(''), str(dt))
9130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for fmt in ["m:%m d:%d y:%y",
9150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    "m:%m d:%d y:%y H:%H M:%M S:%S",
9160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    "%z %Z",
9170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    ]:
9180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(dt.__format__(fmt), dt.strftime(fmt))
9190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(a.__format__(fmt), dt.strftime(fmt))
9200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(b.__format__(fmt), 'B')
9210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_resolution_info(self):
9230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIsInstance(self.theclass.min, self.theclass)
9240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIsInstance(self.theclass.max, self.theclass)
9250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIsInstance(self.theclass.resolution, timedelta)
9260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(self.theclass.max > self.theclass.min)
9270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_extreme_timedelta(self):
9290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        big = self.theclass.max - self.theclass.min
9300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # 3652058 days, 23 hours, 59 minutes, 59 seconds, 999999 microseconds
9310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        n = (big.days*24*3600 + big.seconds)*1000000 + big.microseconds
9320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # n == 315537897599999999 ~= 2**58.13
9330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        justasbig = timedelta(0, 0, n)
9340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(big, justasbig)
9350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(self.theclass.min + big, self.theclass.max)
9360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(self.theclass.max - big, self.theclass.min)
9370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_timetuple(self):
9390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for i in range(7):
9400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # January 2, 1956 is a Monday (0)
9410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d = self.theclass(1956, 1, 2+i)
9420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            t = d.timetuple()
9430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t, (1956, 1, 2+i, 0, 0, 0, i, 2+i, -1))
9440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # February 1, 1956 is a Wednesday (2)
9450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d = self.theclass(1956, 2, 1+i)
9460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            t = d.timetuple()
9470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t, (1956, 2, 1+i, 0, 0, 0, (2+i)%7, 32+i, -1))
9480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # March 1, 1956 is a Thursday (3), and is the 31+29+1 = 61st day
9490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # of the year.
9500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d = self.theclass(1956, 3, 1+i)
9510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            t = d.timetuple()
9520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t, (1956, 3, 1+i, 0, 0, 0, (3+i)%7, 61+i, -1))
9530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t.tm_year, 1956)
9540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t.tm_mon, 3)
9550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t.tm_mday, 1+i)
9560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t.tm_hour, 0)
9570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t.tm_min, 0)
9580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t.tm_sec, 0)
9590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t.tm_wday, (3+i)%7)
9600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t.tm_yday, 61+i)
9610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t.tm_isdst, -1)
9620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_pickling(self):
9640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = 6, 7, 23
9650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        orig = self.theclass(*args)
9660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for pickler, unpickler, proto in pickle_choices:
9670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            green = pickler.dumps(orig, proto)
9680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            derived = unpickler.loads(green)
9690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(orig, derived)
9700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_compare(self):
9720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = self.theclass(2, 3, 4)
9730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = self.theclass(2, 3, 4)
9740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 == t2)
9750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 <= t2)
9760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 >= t2)
9770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not t1 != t2)
9780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not t1 < t2)
9790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not t1 > t2)
9800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(cmp(t1, t2), 0)
9810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(cmp(t2, t1), 0)
9820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for args in (3, 3, 3), (2, 4, 4), (2, 3, 5):
9840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            t2 = self.theclass(*args)   # this is larger than t1
9850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t1 < t2)
9860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t2 > t1)
9870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t1 <= t2)
9880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t2 >= t1)
9890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t1 != t2)
9900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t2 != t1)
9910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t1 == t2)
9920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t2 == t1)
9930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t1 > t2)
9940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t2 < t1)
9950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t1 >= t2)
9960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t2 <= t1)
9970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(cmp(t1, t2), -1)
9980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(cmp(t2, t1), 1)
9990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for badarg in OTHERSTUFF:
10010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t1 == badarg, False)
10020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t1 != badarg, True)
10030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(badarg == t1, False)
10040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(badarg != t1, True)
10050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: t1 < badarg)
10070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: t1 > badarg)
10080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: t1 >= badarg)
10090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: badarg <= t1)
10100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: badarg < t1)
10110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: badarg > t1)
10120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: badarg >= t1)
10130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_mixed_compare(self):
10150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        our = self.theclass(2000, 4, 5)
10160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, cmp, our, 1)
10170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, cmp, 1, our)
10180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class AnotherDateTimeClass(object):
10200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __cmp__(self, other):
10210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # Return "equal" so calling this can't be confused with
10220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # compare-by-address (which never says "equal" for distinct
10230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # objects).
10240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return 0
10250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            __hash__ = None # Silence Py3k warning
10260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # This still errors, because date and datetime comparison raise
10280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # TypeError instead of NotImplemented when they don't know what to
10290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # do, in order to stop comparison from falling back to the default
10300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # compare-by-address.
10310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        their = AnotherDateTimeClass()
10320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, cmp, our, their)
10330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Oops:  The next stab raises TypeError in the C implementation,
10340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # but not in the Python implementation of datetime.  The difference
10350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # is due to that the Python implementation defines __cmp__ but
10360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # the C implementation defines tp_richcompare.  This is more pain
10370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # to fix than it's worth, so commenting out the test.
10380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # self.assertEqual(cmp(their, our), 0)
10390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # But date and datetime comparison return NotImplemented instead if the
10410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # other object has a timetuple attr.  This gives the other object a
10420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # chance to do the comparison.
10430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class Comparable(AnotherDateTimeClass):
10440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def timetuple(self):
10450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return ()
10460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        their = Comparable()
10480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(cmp(our, their), 0)
10490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(cmp(their, our), 0)
10500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(our == their)
10510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(their == our)
10520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_bool(self):
10540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # All dates are considered true.
10550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(self.theclass.min)
10560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(self.theclass.max)
10570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_strftime_out_of_range(self):
10590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # For nasty technical reasons, we can't handle years before 1900.
10600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cls = self.theclass
10610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(cls(1900, 1, 1).strftime("%Y"), "1900")
10620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for y in 1, 49, 51, 99, 100, 1000, 1899:
10630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(ValueError, cls(y, 1, 1).strftime, "%Y")
10640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_replace(self):
10660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cls = self.theclass
10670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = [1, 2, 3]
10680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base = cls(*args)
10690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(base, base.replace())
10700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        i = 0
10720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for name, newval in (("year", 2),
10730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("month", 3),
10740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("day", 4)):
10750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            newargs = args[:]
10760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            newargs[i] = newval
10770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            expected = cls(*newargs)
10780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            got = base.replace(**{name: newval})
10790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(expected, got)
10800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            i += 1
10810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Out of bounds.
10830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base = cls(2000, 2, 29)
10840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, base.replace, year=2001)
10850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_subclass_date(self):
10870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class C(self.theclass):
10890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            theAnswer = 42
10900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __new__(cls, *args, **kws):
10920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                temp = kws.copy()
10930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                extra = temp.pop('extra')
10940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                result = self.theclass.__new__(cls, *args, **temp)
10950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                result.extra = extra
10960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return result
10970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def newmeth(self, start):
10990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return start + self.year + self.month
11000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = 2003, 4, 14
11020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt1 = self.theclass(*args)
11040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt2 = C(*args, **{'extra': 7})
11050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2.__class__, C)
11070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2.theAnswer, 42)
11080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2.extra, 7)
11090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt1.toordinal(), dt2.toordinal())
11100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2.newmeth(-7), dt1.year + dt1.month - 7)
11110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_pickling_subclass_date(self):
11130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = 6, 7, 23
11150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        orig = SubclassDate(*args)
11160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for pickler, unpickler, proto in pickle_choices:
11170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            green = pickler.dumps(orig, proto)
11180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            derived = unpickler.loads(green)
11190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(orig, derived)
11200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_backdoor_resistance(self):
11220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # For fast unpickling, the constructor accepts a pickle string.
11230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # This is a low-overhead backdoor.  A user can (by intent or
11240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # mistake) pass a string directly, which (if it's the right length)
11250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # will get treated like a pickle, and bypass the normal sanity
11260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # checks in the constructor.  This can create insane objects.
11270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # The constructor doesn't want to burn the time to validate all
11280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # fields, but does check the month field.  This stops, e.g.,
11290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # datetime.datetime('1995-03-25') from yielding an insane object.
11300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base = '1995-03-25'
11310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not issubclass(self.theclass, datetime):
11320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            base = base[:4]
11330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for month_byte in '9', chr(0), chr(13), '\xff':
11340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, self.theclass,
11350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                         base[:2] + month_byte + base[3:])
11360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for ord_byte in range(1, 13):
11370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # This shouldn't blow up because of the month byte alone.  If
11380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # the implementation changes to do more-careful checking, it may
11390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # blow up because other fields are insane.
11400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.theclass(base[:2] + chr(ord_byte) + base[3:])
11410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#############################################################################
11430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# datetime tests
11440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11450a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass SubclassDatetime(datetime):
11460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    sub_var = 1
11470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11480a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestDateTime(TestDate):
11490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    theclass = datetime
11510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_basic_attributes(self):
11530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt = self.theclass(2002, 3, 1, 12, 0)
11540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.year, 2002)
11550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.month, 3)
11560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.day, 1)
11570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.hour, 12)
11580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.minute, 0)
11590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.second, 0)
11600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.microsecond, 0)
11610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_basic_attributes_nonzero(self):
11630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Make sure all attributes are non-zero so bugs in
11640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # bit-shifting access show up.
11650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt = self.theclass(2002, 3, 1, 12, 59, 59, 8000)
11660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.year, 2002)
11670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.month, 3)
11680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.day, 1)
11690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.hour, 12)
11700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.minute, 59)
11710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.second, 59)
11720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.microsecond, 8000)
11730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_roundtrip(self):
11750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for dt in (self.theclass(1, 2, 3, 4, 5, 6, 7),
11760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                   self.theclass.now()):
11770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Verify dt -> string -> datetime identity.
11780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            s = repr(dt)
11790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(s.startswith('datetime.'))
11800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            s = s[9:]
11810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            dt2 = eval(s)
11820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(dt, dt2)
11830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Verify identity via reconstructing from pieces.
11850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            dt2 = self.theclass(dt.year, dt.month, dt.day,
11860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                dt.hour, dt.minute, dt.second,
11870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                dt.microsecond)
11880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(dt, dt2)
11890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_isoformat(self):
11910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(2, 3, 2, 4, 5, 1, 123)
11920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(),    "0002-03-02T04:05:01.000123")
11930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat('T'), "0002-03-02T04:05:01.000123")
11940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(' '), "0002-03-02 04:05:01.000123")
11950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat('\x00'), "0002-03-02\x0004:05:01.000123")
11960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # str is ISO format with the separator forced to a blank.
11970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(str(t), "0002-03-02 04:05:01.000123")
11980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(2, 3, 2)
12000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(),    "0002-03-02T00:00:00")
12010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat('T'), "0002-03-02T00:00:00")
12020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(' '), "0002-03-02 00:00:00")
12030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # str is ISO format with the separator forced to a blank.
12040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(str(t), "0002-03-02 00:00:00")
12050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_format(self):
12070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt = self.theclass(2007, 9, 10, 4, 5, 1, 123)
12080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.__format__(''), str(dt))
12090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # check that a derived class's __str__() gets called
12110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class A(self.theclass):
12120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __str__(self):
12130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return 'A'
12140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a = A(2007, 9, 10, 4, 5, 1, 123)
12150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a.__format__(''), 'A')
12160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # check that a derived class's strftime gets called
12180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class B(self.theclass):
12190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def strftime(self, format_spec):
12200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return 'B'
12210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        b = B(2007, 9, 10, 4, 5, 1, 123)
12220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(b.__format__(''), str(dt))
12230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for fmt in ["m:%m d:%d y:%y",
12250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    "m:%m d:%d y:%y H:%H M:%M S:%S",
12260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    "%z %Z",
12270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    ]:
12280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(dt.__format__(fmt), dt.strftime(fmt))
12290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(a.__format__(fmt), dt.strftime(fmt))
12300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(b.__format__(fmt), 'B')
12310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_more_ctime(self):
12330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test fields that TestDate doesn't touch.
12340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        import time
12350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(2002, 3, 2, 18, 3, 5, 123)
12370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.ctime(), "Sat Mar  2 18:03:05 2002")
12380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Oops!  The next line fails on Win2K under MSVC 6, so it's commented
12390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # out.  The difference is that t.ctime() produces " 2" for the day,
12400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # but platform ctime() produces "02" for the day.  According to
12410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # C99, t.ctime() is correct here.
12420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # self.assertEqual(t.ctime(), time.ctime(time.mktime(t.timetuple())))
12430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # So test a case where that difference doesn't matter.
12450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(2002, 3, 22, 18, 3, 5, 123)
12460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.ctime(), time.ctime(time.mktime(t.timetuple())))
12470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_tz_independent_comparing(self):
12490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt1 = self.theclass(2002, 3, 1, 9, 0, 0)
12500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt2 = self.theclass(2002, 3, 1, 10, 0, 0)
12510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt3 = self.theclass(2002, 3, 1, 9, 0, 0)
12520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt1, dt3)
12530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(dt2 > dt3)
12540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Make sure comparison doesn't forget microseconds, and isn't done
12560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # via comparing a float timestamp (an IEEE double doesn't have enough
12570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # precision to span microsecond resolution across years 1 thru 9999,
12580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # so comparing via timestamp necessarily calls some distinct values
12590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # equal).
12600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt1 = self.theclass(MAXYEAR, 12, 31, 23, 59, 59, 999998)
12610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        us = timedelta(microseconds=1)
12620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt2 = dt1 + us
12630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2 - dt1, us)
12640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(dt1 < dt2)
12650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_strftime_with_bad_tzname_replace(self):
12670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # verify ok if tzinfo.tzname().replace() returns a non-string
12680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class MyTzInfo(FixedOffset):
12690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def tzname(self, dt):
12700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                class MyStr(str):
12710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    def replace(self, *args):
12720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        return None
12730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return MyStr('name')
12740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(2005, 3, 2, 0, 0, 0, 0, MyTzInfo(3, 'name'))
12750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, t.strftime, '%Z')
12760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_bad_constructor_arguments(self):
12780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # bad years
12790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(MINYEAR, 1, 1)  # no exception
12800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(MAXYEAR, 1, 1)  # no exception
12810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, MINYEAR-1, 1, 1)
12820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, MAXYEAR+1, 1, 1)
12830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # bad months
12840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(2000, 1, 1)    # no exception
12850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(2000, 12, 1)   # no exception
12860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 2000, 0, 1)
12870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 2000, 13, 1)
12880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # bad days
12890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(2000, 2, 29)   # no exception
12900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(2004, 2, 29)   # no exception
12910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(2400, 2, 29)   # no exception
12920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 2000, 2, 30)
12930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 2001, 2, 29)
12940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 2100, 2, 29)
12950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 1900, 2, 29)
12960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 2000, 1, 0)
12970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 2000, 1, 32)
12980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # bad hours
12990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(2000, 1, 31, 0)    # no exception
13000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(2000, 1, 31, 23)   # no exception
13010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 2000, 1, 31, -1)
13020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 2000, 1, 31, 24)
13030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # bad minutes
13040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(2000, 1, 31, 23, 0)    # no exception
13050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(2000, 1, 31, 23, 59)   # no exception
13060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 2000, 1, 31, 23, -1)
13070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 2000, 1, 31, 23, 60)
13080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # bad seconds
13090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(2000, 1, 31, 23, 59, 0)    # no exception
13100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(2000, 1, 31, 23, 59, 59)   # no exception
13110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 2000, 1, 31, 23, 59, -1)
13120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 2000, 1, 31, 23, 59, 60)
13130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # bad microseconds
13140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(2000, 1, 31, 23, 59, 59, 0)    # no exception
13150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(2000, 1, 31, 23, 59, 59, 999999)   # no exception
13160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass,
13170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          2000, 1, 31, 23, 59, 59, -1)
13180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass,
13190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          2000, 1, 31, 23, 59, 59,
13200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          1000000)
13210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_hash_equality(self):
13230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d = self.theclass(2000, 12, 31, 23, 30, 17)
13240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        e = self.theclass(2000, 12, 31, 23, 30, 17)
13250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(d, e)
13260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(hash(d), hash(e))
13270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dic = {d: 1}
13290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dic[e] = 2
13300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(len(dic), 1)
13310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dic[d], 2)
13320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dic[e], 2)
13330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d = self.theclass(2001,  1,  1,  0,  5, 17)
13350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        e = self.theclass(2001,  1,  1,  0,  5, 17)
13360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(d, e)
13370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(hash(d), hash(e))
13380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dic = {d: 1}
13400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dic[e] = 2
13410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(len(dic), 1)
13420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dic[d], 2)
13430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dic[e], 2)
13440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_computations(self):
13460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a = self.theclass(2002, 1, 31)
13470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        b = self.theclass(1956, 1, 31)
13480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        diff = a-b
13490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(diff.days, 46*365 + len(range(1956, 2002, 4)))
13500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(diff.seconds, 0)
13510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(diff.microseconds, 0)
13520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a = self.theclass(2002, 3, 2, 17, 6)
13530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        millisec = timedelta(0, 0, 1000)
13540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        hour = timedelta(0, 3600)
13550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        day = timedelta(1)
13560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        week = timedelta(7)
13570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a + hour, self.theclass(2002, 3, 2, 18, 6))
13580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(hour + a, self.theclass(2002, 3, 2, 18, 6))
13590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a + 10*hour, self.theclass(2002, 3, 3, 3, 6))
13600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - hour, self.theclass(2002, 3, 2, 16, 6))
13610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(-hour + a, self.theclass(2002, 3, 2, 16, 6))
13620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - hour, a + -hour)
13630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - 20*hour, self.theclass(2002, 3, 1, 21, 6))
13640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a + day, self.theclass(2002, 3, 3, 17, 6))
13650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - day, self.theclass(2002, 3, 1, 17, 6))
13660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a + week, self.theclass(2002, 3, 9, 17, 6))
13670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - week, self.theclass(2002, 2, 23, 17, 6))
13680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a + 52*week, self.theclass(2003, 3, 1, 17, 6))
13690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - 52*week, self.theclass(2001, 3, 3, 17, 6))
13700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual((a + week) - a, week)
13710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual((a + day) - a, day)
13720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual((a + hour) - a, hour)
13730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual((a + millisec) - a, millisec)
13740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual((a - week) - a, -week)
13750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual((a - day) - a, -day)
13760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual((a - hour) - a, -hour)
13770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual((a - millisec) - a, -millisec)
13780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - (a + week), -week)
13790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - (a + day), -day)
13800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - (a + hour), -hour)
13810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - (a + millisec), -millisec)
13820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - (a - week), week)
13830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - (a - day), day)
13840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - (a - hour), hour)
13850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - (a - millisec), millisec)
13860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a + (week + day + hour + millisec),
13870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         self.theclass(2002, 3, 10, 18, 6, 0, 1000))
13880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a + (week + day + hour + millisec),
13890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         (((a + week) + day) + hour) + millisec)
13900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - (week + day + hour + millisec),
13910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         self.theclass(2002, 2, 22, 16, 5, 59, 999000))
13920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a - (week + day + hour + millisec),
13930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         (((a - week) - day) - hour) - millisec)
13940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Add/sub ints, longs, floats should be illegal
13950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for i in 1, 1L, 1.0:
13960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: a+i)
13970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: a-i)
13980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: i+a)
13990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: i-a)
14000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # delta - datetime is senseless.
14020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: day - a)
14030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # mixing datetime and (delta or datetime) via * or // is senseless
14040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: day * a)
14050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: a * day)
14060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: day // a)
14070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: a // day)
14080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: a * a)
14090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: a // a)
14100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # datetime + datetime is senseless
14110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: a + a)
14120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_pickling(self):
14140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = 6, 7, 23, 20, 59, 1, 64**2
14150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        orig = self.theclass(*args)
14160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for pickler, unpickler, proto in pickle_choices:
14170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            green = pickler.dumps(orig, proto)
14180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            derived = unpickler.loads(green)
14190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(orig, derived)
14200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_more_pickling(self):
14220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a = self.theclass(2003, 2, 7, 16, 48, 37, 444116)
14230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        s = pickle.dumps(a)
14240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        b = pickle.loads(s)
14250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(b.year, 2003)
14260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(b.month, 2)
14270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(b.day, 7)
14280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_pickling_subclass_datetime(self):
14300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = 6, 7, 23, 20, 59, 1, 64**2
14310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        orig = SubclassDatetime(*args)
14320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for pickler, unpickler, proto in pickle_choices:
14330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            green = pickler.dumps(orig, proto)
14340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            derived = unpickler.loads(green)
14350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(orig, derived)
14360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_more_compare(self):
14380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # The test_compare() inherited from TestDate covers the error cases.
14390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # We just want to test lexicographic ordering on the members datetime
14400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # has that date lacks.
14410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = [2000, 11, 29, 20, 58, 16, 999998]
14420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = self.theclass(*args)
14430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = self.theclass(*args)
14440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 == t2)
14450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 <= t2)
14460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 >= t2)
14470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not t1 != t2)
14480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not t1 < t2)
14490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not t1 > t2)
14500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(cmp(t1, t2), 0)
14510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(cmp(t2, t1), 0)
14520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for i in range(len(args)):
14540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            newargs = args[:]
14550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            newargs[i] = args[i] + 1
14560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            t2 = self.theclass(*newargs)   # this is larger than t1
14570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t1 < t2)
14580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t2 > t1)
14590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t1 <= t2)
14600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t2 >= t1)
14610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t1 != t2)
14620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t2 != t1)
14630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t1 == t2)
14640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t2 == t1)
14650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t1 > t2)
14660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t2 < t1)
14670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t1 >= t2)
14680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t2 <= t1)
14690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(cmp(t1, t2), -1)
14700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(cmp(t2, t1), 1)
14710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # A helper for timestamp constructor tests.
14740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def verify_field_equality(self, expected, got):
14750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(expected.tm_year, got.year)
14760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(expected.tm_mon, got.month)
14770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(expected.tm_mday, got.day)
14780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(expected.tm_hour, got.hour)
14790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(expected.tm_min, got.minute)
14800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(expected.tm_sec, got.second)
14810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_fromtimestamp(self):
14830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        import time
14840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        ts = time.time()
14860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected = time.localtime(ts)
14870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        got = self.theclass.fromtimestamp(ts)
14880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.verify_field_equality(expected, got)
14890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_utcfromtimestamp(self):
14910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        import time
14920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        ts = time.time()
14940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected = time.gmtime(ts)
14950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        got = self.theclass.utcfromtimestamp(ts)
14960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.verify_field_equality(expected, got)
14970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_microsecond_rounding(self):
14990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test whether fromtimestamp "rounds up" floats that are less
15000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # than one microsecond smaller than an integer.
15010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(self.theclass.fromtimestamp(0.9999999),
15020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         self.theclass.fromtimestamp(1))
15030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_insane_fromtimestamp(self):
15050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # It's possible that some platform maps time_t to double,
15060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # and that this test will fail there.  This test should
15070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # exempt such platforms (provided they return reasonable
15080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # results!).
15090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for insane in -1e200, 1e200:
15100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(ValueError, self.theclass.fromtimestamp,
15110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                              insane)
15120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_insane_utcfromtimestamp(self):
15140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # It's possible that some platform maps time_t to double,
15150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # and that this test will fail there.  This test should
15160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # exempt such platforms (provided they return reasonable
15170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # results!).
15180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for insane in -1e200, 1e200:
15190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(ValueError, self.theclass.utcfromtimestamp,
15200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                              insane)
15210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @unittest.skipIf(sys.platform == "win32", "Windows doesn't accept negative timestamps")
15220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_negative_float_fromtimestamp(self):
15230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # The result is tz-dependent; at least test that this doesn't
15240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # fail (like it did before bug 1646728 was fixed).
15250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass.fromtimestamp(-1.05)
15260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @unittest.skipIf(sys.platform == "win32", "Windows doesn't accept negative timestamps")
15280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_negative_float_utcfromtimestamp(self):
15290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d = self.theclass.utcfromtimestamp(-1.05)
15300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(d, self.theclass(1969, 12, 31, 23, 59, 58, 950000))
15310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_utcnow(self):
15330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        import time
15340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Call it a success if utcnow() and utcfromtimestamp() are within
15360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # a second of each other.
15370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        tolerance = timedelta(seconds=1)
15380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for dummy in range(3):
15390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            from_now = self.theclass.utcnow()
15400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            from_timestamp = self.theclass.utcfromtimestamp(time.time())
15410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if abs(from_timestamp - from_now) <= tolerance:
15420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                break
15430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Else try again a few times.
15440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(abs(from_timestamp - from_now) <= tolerance)
15450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_strptime(self):
15470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        import _strptime
15480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        string = '2004-12-01 13:02:47.197'
15500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        format = '%Y-%m-%d %H:%M:%S.%f'
15510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        result, frac = _strptime._strptime(string, format)
15520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected = self.theclass(*(result[0:6]+(frac,)))
15530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        got = self.theclass.strptime(string, format)
15540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(expected, got)
15550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_more_timetuple(self):
15570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # This tests fields beyond those tested by the TestDate.test_timetuple.
15580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(2004, 12, 31, 6, 22, 33)
15590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.timetuple(), (2004, 12, 31, 6, 22, 33, 4, 366, -1))
15600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.timetuple(),
15610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         (t.year, t.month, t.day,
15620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          t.hour, t.minute, t.second,
15630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          t.weekday(),
15640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          t.toordinal() - date(t.year, 1, 1).toordinal() + 1,
15650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          -1))
15660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        tt = t.timetuple()
15670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(tt.tm_year, t.year)
15680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(tt.tm_mon, t.month)
15690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(tt.tm_mday, t.day)
15700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(tt.tm_hour, t.hour)
15710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(tt.tm_min, t.minute)
15720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(tt.tm_sec, t.second)
15730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(tt.tm_wday, t.weekday())
15740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(tt.tm_yday, t.toordinal() -
15750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                     date(t.year, 1, 1).toordinal() + 1)
15760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(tt.tm_isdst, -1)
15770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_more_strftime(self):
15790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # This tests fields beyond those tested by the TestDate.test_strftime.
15800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(2004, 12, 31, 6, 22, 33, 47)
15810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.strftime("%m %d %y %f %S %M %H %j"),
15820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                    "12 31 04 000047 33 22 06 366")
15830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_extract(self):
15850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt = self.theclass(2002, 3, 4, 18, 45, 3, 1234)
15860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.date(), date(2002, 3, 4))
15870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.time(), time(18, 45, 3, 1234))
15880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_combine(self):
15900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d = date(2002, 3, 4)
15910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = time(18, 45, 3, 1234)
15920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected = self.theclass(2002, 3, 4, 18, 45, 3, 1234)
15930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        combine = self.theclass.combine
15940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt = combine(d, t)
15950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt, expected)
15960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt = combine(time=t, date=d)
15980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt, expected)
15990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(d, dt.date())
16010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t, dt.time())
16020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt, combine(dt.date(), dt.time()))
16030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, combine) # need an arg
16050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, combine, d) # need two args
16060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, combine, t, d) # args reversed
16070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, combine, d, t, 1) # too many args
16080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, combine, "date", "time") # wrong types
16090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_replace(self):
16110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cls = self.theclass
16120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = [1, 2, 3, 4, 5, 6, 7]
16130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base = cls(*args)
16140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(base, base.replace())
16150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        i = 0
16170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for name, newval in (("year", 2),
16180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("month", 3),
16190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("day", 4),
16200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("hour", 5),
16210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("minute", 6),
16220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("second", 7),
16230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("microsecond", 8)):
16240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            newargs = args[:]
16250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            newargs[i] = newval
16260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            expected = cls(*newargs)
16270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            got = base.replace(**{name: newval})
16280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(expected, got)
16290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            i += 1
16300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Out of bounds.
16320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base = cls(2000, 2, 29)
16330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, base.replace, year=2001)
16340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_astimezone(self):
16360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Pretty boring!  The TZ test is more interesting here.  astimezone()
16370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # simply can't be applied to a naive object.
16380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt = self.theclass.now()
16390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = FixedOffset(44, "")
16400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, dt.astimezone) # not enough args
16410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, dt.astimezone, f, f) # too many args
16420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, dt.astimezone, dt) # arg wrong type
16430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, dt.astimezone, f) # naive
16440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, dt.astimezone, tz=f)  # naive
16450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class Bogus(tzinfo):
16470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def utcoffset(self, dt): return None
16480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def dst(self, dt): return timedelta(0)
16490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        bog = Bogus()
16500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, dt.astimezone, bog)   # naive
16510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class AlsoBogus(tzinfo):
16530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def utcoffset(self, dt): return timedelta(0)
16540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def dst(self, dt): return None
16550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        alsobog = AlsoBogus()
16560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, dt.astimezone, alsobog) # also naive
16570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_subclass_datetime(self):
16590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class C(self.theclass):
16610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            theAnswer = 42
16620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __new__(cls, *args, **kws):
16640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                temp = kws.copy()
16650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                extra = temp.pop('extra')
16660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                result = self.theclass.__new__(cls, *args, **temp)
16670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                result.extra = extra
16680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return result
16690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def newmeth(self, start):
16710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return start + self.year + self.month + self.second
16720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = 2003, 4, 14, 12, 13, 41
16740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt1 = self.theclass(*args)
16760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt2 = C(*args, **{'extra': 7})
16770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2.__class__, C)
16790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2.theAnswer, 42)
16800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2.extra, 7)
16810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt1.toordinal(), dt2.toordinal())
16820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2.newmeth(-7), dt1.year + dt1.month +
16830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                          dt1.second - 7)
16840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16850a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass SubclassTime(time):
16860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    sub_var = 1
16870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16880a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestTime(HarmlessMixedComparison, unittest.TestCase):
16890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    theclass = time
16910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_basic_attributes(self):
16930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(12, 0)
16940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.hour, 12)
16950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.minute, 0)
16960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.second, 0)
16970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.microsecond, 0)
16980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_basic_attributes_nonzero(self):
17000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Make sure all attributes are non-zero so bugs in
17010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # bit-shifting access show up.
17020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(12, 59, 59, 8000)
17030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.hour, 12)
17040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.minute, 59)
17050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.second, 59)
17060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.microsecond, 8000)
17070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
17080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_roundtrip(self):
17090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(1, 2, 3, 4)
17100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
17110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Verify t -> string -> time identity.
17120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        s = repr(t)
17130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(s.startswith('datetime.'))
17140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        s = s[9:]
17150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = eval(s)
17160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t, t2)
17170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
17180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Verify identity via reconstructing from pieces.
17190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = self.theclass(t.hour, t.minute, t.second,
17200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           t.microsecond)
17210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t, t2)
17220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
17230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_comparing(self):
17240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = [1, 2, 3, 4]
17250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = self.theclass(*args)
17260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = self.theclass(*args)
17270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 == t2)
17280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 <= t2)
17290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 >= t2)
17300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not t1 != t2)
17310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not t1 < t2)
17320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not t1 > t2)
17330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(cmp(t1, t2), 0)
17340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(cmp(t2, t1), 0)
17350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
17360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for i in range(len(args)):
17370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            newargs = args[:]
17380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            newargs[i] = args[i] + 1
17390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            t2 = self.theclass(*newargs)   # this is larger than t1
17400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t1 < t2)
17410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t2 > t1)
17420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t1 <= t2)
17430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t2 >= t1)
17440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t1 != t2)
17450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t2 != t1)
17460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t1 == t2)
17470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t2 == t1)
17480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t1 > t2)
17490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t2 < t1)
17500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t1 >= t2)
17510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(not t2 <= t1)
17520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(cmp(t1, t2), -1)
17530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(cmp(t2, t1), 1)
17540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
17550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for badarg in OTHERSTUFF:
17560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t1 == badarg, False)
17570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t1 != badarg, True)
17580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(badarg == t1, False)
17590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(badarg != t1, True)
17600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
17610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: t1 <= badarg)
17620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: t1 < badarg)
17630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: t1 > badarg)
17640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: t1 >= badarg)
17650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: badarg <= t1)
17660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: badarg < t1)
17670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: badarg > t1)
17680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, lambda: badarg >= t1)
17690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
17700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_bad_constructor_arguments(self):
17710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # bad hours
17720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(0, 0)    # no exception
17730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(23, 0)   # no exception
17740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, -1, 0)
17750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 24, 0)
17760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # bad minutes
17770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(23, 0)    # no exception
17780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(23, 59)   # no exception
17790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 23, -1)
17800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 23, 60)
17810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # bad seconds
17820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(23, 59, 0)    # no exception
17830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(23, 59, 59)   # no exception
17840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 23, 59, -1)
17850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 23, 59, 60)
17860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # bad microseconds
17870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(23, 59, 59, 0)        # no exception
17880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.theclass(23, 59, 59, 999999)   # no exception
17890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 23, 59, 59, -1)
17900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, self.theclass, 23, 59, 59, 1000000)
17910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
17920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_hash_equality(self):
17930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d = self.theclass(23, 30, 17)
17940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        e = self.theclass(23, 30, 17)
17950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(d, e)
17960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(hash(d), hash(e))
17970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
17980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dic = {d: 1}
17990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dic[e] = 2
18000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(len(dic), 1)
18010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dic[d], 2)
18020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dic[e], 2)
18030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
18040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d = self.theclass(0,  5, 17)
18050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        e = self.theclass(0,  5, 17)
18060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(d, e)
18070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(hash(d), hash(e))
18080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
18090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dic = {d: 1}
18100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dic[e] = 2
18110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(len(dic), 1)
18120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dic[d], 2)
18130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dic[e], 2)
18140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
18150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_isoformat(self):
18160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(4, 5, 1, 123)
18170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(), "04:05:01.000123")
18180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(), str(t))
18190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
18200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass()
18210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(), "00:00:00")
18220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(), str(t))
18230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
18240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(microsecond=1)
18250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(), "00:00:00.000001")
18260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(), str(t))
18270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
18280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(microsecond=10)
18290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(), "00:00:00.000010")
18300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(), str(t))
18310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
18320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(microsecond=100)
18330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(), "00:00:00.000100")
18340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(), str(t))
18350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
18360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(microsecond=1000)
18370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(), "00:00:00.001000")
18380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(), str(t))
18390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
18400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(microsecond=10000)
18410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(), "00:00:00.010000")
18420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(), str(t))
18430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
18440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(microsecond=100000)
18450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(), "00:00:00.100000")
18460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.isoformat(), str(t))
18470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
18480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_1653736(self):
18490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # verify it doesn't accept extra keyword arguments
18500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(second=1)
18510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, t.isoformat, foo=3)
18520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
18530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_strftime(self):
18540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(1, 2, 3, 4)
18550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.strftime('%H %M %S %f'), "01 02 03 000004")
18560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # A naive object replaces %z and %Z with empty strings.
18570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''")
18580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
18590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_format(self):
18600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(1, 2, 3, 4)
18610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.__format__(''), str(t))
18620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
18630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # check that a derived class's __str__() gets called
18640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class A(self.theclass):
18650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __str__(self):
18660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return 'A'
18670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a = A(1, 2, 3, 4)
18680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(a.__format__(''), 'A')
18690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
18700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # check that a derived class's strftime gets called
18710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class B(self.theclass):
18720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def strftime(self, format_spec):
18730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return 'B'
18740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        b = B(1, 2, 3, 4)
18750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(b.__format__(''), str(t))
18760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
18770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for fmt in ['%H %M %S',
18780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    ]:
18790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(t.__format__(fmt), t.strftime(fmt))
18800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(a.__format__(fmt), t.strftime(fmt))
18810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(b.__format__(fmt), 'B')
18820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
18830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_str(self):
18840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(str(self.theclass(1, 2, 3, 4)), "01:02:03.000004")
18850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(str(self.theclass(10, 2, 3, 4000)), "10:02:03.004000")
18860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(str(self.theclass(0, 2, 3, 400000)), "00:02:03.400000")
18870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(str(self.theclass(12, 2, 3, 0)), "12:02:03")
18880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(str(self.theclass(23, 15, 0, 0)), "23:15:00")
18890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
18900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_repr(self):
18910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        name = 'datetime.' + self.theclass.__name__
18920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(repr(self.theclass(1, 2, 3, 4)),
18930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         "%s(1, 2, 3, 4)" % name)
18940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(repr(self.theclass(10, 2, 3, 4000)),
18950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         "%s(10, 2, 3, 4000)" % name)
18960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(repr(self.theclass(0, 2, 3, 400000)),
18970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         "%s(0, 2, 3, 400000)" % name)
18980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(repr(self.theclass(12, 2, 3, 0)),
18990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         "%s(12, 2, 3)" % name)
19000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(repr(self.theclass(23, 15, 0, 0)),
19010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         "%s(23, 15)" % name)
19020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
19030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_resolution_info(self):
19040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIsInstance(self.theclass.min, self.theclass)
19050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIsInstance(self.theclass.max, self.theclass)
19060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIsInstance(self.theclass.resolution, timedelta)
19070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(self.theclass.max > self.theclass.min)
19080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
19090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_pickling(self):
19100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = 20, 59, 16, 64**2
19110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        orig = self.theclass(*args)
19120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for pickler, unpickler, proto in pickle_choices:
19130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            green = pickler.dumps(orig, proto)
19140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            derived = unpickler.loads(green)
19150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(orig, derived)
19160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
19170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_pickling_subclass_time(self):
19180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = 20, 59, 16, 64**2
19190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        orig = SubclassTime(*args)
19200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for pickler, unpickler, proto in pickle_choices:
19210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            green = pickler.dumps(orig, proto)
19220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            derived = unpickler.loads(green)
19230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(orig, derived)
19240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
19250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_bool(self):
19260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cls = self.theclass
19270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(cls(1))
19280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(cls(0, 1))
19290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(cls(0, 0, 1))
19300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(cls(0, 0, 0, 1))
19310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not cls(0))
19320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not cls())
19330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
19340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_replace(self):
19350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cls = self.theclass
19360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = [1, 2, 3, 4]
19370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base = cls(*args)
19380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(base, base.replace())
19390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
19400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        i = 0
19410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for name, newval in (("hour", 5),
19420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("minute", 6),
19430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("second", 7),
19440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("microsecond", 8)):
19450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            newargs = args[:]
19460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            newargs[i] = newval
19470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            expected = cls(*newargs)
19480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            got = base.replace(**{name: newval})
19490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(expected, got)
19500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            i += 1
19510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
19520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Out of bounds.
19530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base = cls(1)
19540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, base.replace, hour=24)
19550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, base.replace, minute=-1)
19560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, base.replace, second=100)
19570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, base.replace, microsecond=1000000)
19580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
19590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_subclass_time(self):
19600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
19610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class C(self.theclass):
19620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            theAnswer = 42
19630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
19640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __new__(cls, *args, **kws):
19650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                temp = kws.copy()
19660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                extra = temp.pop('extra')
19670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                result = self.theclass.__new__(cls, *args, **temp)
19680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                result.extra = extra
19690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return result
19700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
19710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def newmeth(self, start):
19720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return start + self.hour + self.second
19730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
19740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = 4, 5, 6
19750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
19760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt1 = self.theclass(*args)
19770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt2 = C(*args, **{'extra': 7})
19780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
19790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2.__class__, C)
19800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2.theAnswer, 42)
19810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2.extra, 7)
19820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt1.isoformat(), dt2.isoformat())
19830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2.newmeth(-7), dt1.hour + dt1.second - 7)
19840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
19850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_backdoor_resistance(self):
19860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # see TestDate.test_backdoor_resistance().
19870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base = '2:59.0'
19880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for hour_byte in ' ', '9', chr(24), '\xff':
19890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, self.theclass,
19900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                         hour_byte + base[1:])
19910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
19920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# A mixin for classes with a tzinfo= argument.  Subclasses must define
19930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# theclass as a class atribute, and theclass(1, 1, 1, tzinfo=whatever)
19940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# must be legit (which is true for time and datetime).
19950a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TZInfoBase:
19960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
19970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_argument_passing(self):
19980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cls = self.theclass
19990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # A datetime passes itself on, a time passes None.
20000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class introspective(tzinfo):
20010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def tzname(self, dt):    return dt and "real" or "none"
20020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def utcoffset(self, dt):
20030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return timedelta(minutes = dt and 42 or -42)
20040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            dst = utcoffset
20050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
20060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        obj = cls(1, 2, 3, tzinfo=introspective())
20070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
20080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected = cls is time and "none" or "real"
20090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(obj.tzname(), expected)
20100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
20110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected = timedelta(minutes=(cls is time and -42 or 42))
20120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(obj.utcoffset(), expected)
20130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(obj.dst(), expected)
20140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
20150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_bad_tzinfo_classes(self):
20160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cls = self.theclass
20170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, cls, 1, 1, 1, tzinfo=12)
20180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
20190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class NiceTry(object):
20200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __init__(self): pass
20210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def utcoffset(self, dt): pass
20220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, cls, 1, 1, 1, tzinfo=NiceTry)
20230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
20240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class BetterTry(tzinfo):
20250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __init__(self): pass
20260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def utcoffset(self, dt): pass
20270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        b = BetterTry()
20280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = cls(1, 1, 1, tzinfo=b)
20290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t.tzinfo is b)
20300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
20310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_utc_offset_out_of_bounds(self):
20320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class Edgy(tzinfo):
20330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __init__(self, offset):
20340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.offset = timedelta(minutes=offset)
20350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def utcoffset(self, dt):
20360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return self.offset
20370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
20380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cls = self.theclass
20390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for offset, legit in ((-1440, False),
20400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                              (-1439, True),
20410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                              (1439, True),
20420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                              (1440, False)):
20430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if cls is time:
20440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                t = cls(1, 2, 3, tzinfo=Edgy(offset))
20450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            elif cls is datetime:
20460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                t = cls(6, 6, 6, 1, 2, 3, tzinfo=Edgy(offset))
20470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
20480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                assert 0, "impossible"
20490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if legit:
20500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                aofs = abs(offset)
20510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                h, m = divmod(aofs, 60)
20520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                tag = "%c%02d:%02d" % (offset < 0 and '-' or '+', h, m)
20530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if isinstance(t, datetime):
20540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    t = t.timetz()
20550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(str(t), "01:02:03" + tag)
20560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
20570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertRaises(ValueError, str, t)
20580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
20590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_tzinfo_classes(self):
20600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cls = self.theclass
20610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class C1(tzinfo):
20620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def utcoffset(self, dt): return None
20630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def dst(self, dt): return None
20640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def tzname(self, dt): return None
20650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for t in (cls(1, 1, 1),
20660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                  cls(1, 1, 1, tzinfo=None),
20670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                  cls(1, 1, 1, tzinfo=C1())):
20680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t.utcoffset() is None)
20690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t.dst() is None)
20700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(t.tzname() is None)
20710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
20720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class C3(tzinfo):
20730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def utcoffset(self, dt): return timedelta(minutes=-1439)
20740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def dst(self, dt): return timedelta(minutes=1439)
20750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def tzname(self, dt): return "aname"
20760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = cls(1, 1, 1, tzinfo=C3())
20770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.utcoffset(), timedelta(minutes=-1439))
20780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.dst(), timedelta(minutes=1439))
20790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.tzname(), "aname")
20800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
20810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Wrong types.
20820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class C4(tzinfo):
20830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def utcoffset(self, dt): return "aname"
20840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def dst(self, dt): return 7
20850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def tzname(self, dt): return 0
20860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = cls(1, 1, 1, tzinfo=C4())
20870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, t.utcoffset)
20880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, t.dst)
20890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, t.tzname)
20900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
20910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Offset out of range.
20920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class C6(tzinfo):
20930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def utcoffset(self, dt): return timedelta(hours=-24)
20940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def dst(self, dt): return timedelta(hours=24)
20950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = cls(1, 1, 1, tzinfo=C6())
20960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, t.utcoffset)
20970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, t.dst)
20980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
20990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Not a whole number of minutes.
21000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class C7(tzinfo):
21010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def utcoffset(self, dt): return timedelta(seconds=61)
21020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def dst(self, dt): return timedelta(microseconds=-81)
21030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = cls(1, 1, 1, tzinfo=C7())
21040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, t.utcoffset)
21050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, t.dst)
21060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
21070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_aware_compare(self):
21080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cls = self.theclass
21090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
21100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Ensure that utcoffset() gets ignored if the comparands have
21110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # the same tzinfo member.
21120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class OperandDependentOffset(tzinfo):
21130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def utcoffset(self, t):
21140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if t.minute < 10:
21150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    # d0 and d1 equal after adjustment
21160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    return timedelta(minutes=t.minute)
21170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                else:
21180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    # d2 off in the weeds
21190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    return timedelta(minutes=59)
21200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
21210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base = cls(8, 9, 10, tzinfo=OperandDependentOffset())
21220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d0 = base.replace(minute=3)
21230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d1 = base.replace(minute=9)
21240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d2 = base.replace(minute=11)
21250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for x in d0, d1, d2:
21260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for y in d0, d1, d2:
21270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                got = cmp(x, y)
21280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                expected = cmp(x.minute, y.minute)
21290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(got, expected)
21300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
21310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # However, if they're different members, uctoffset is not ignored.
21320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Note that a time can't actually have an operand-depedent offset,
21330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # though (and time.utcoffset() passes None to tzinfo.utcoffset()),
21340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # so skip this test for time.
21350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if cls is not time:
21360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d0 = base.replace(minute=3, tzinfo=OperandDependentOffset())
21370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d1 = base.replace(minute=9, tzinfo=OperandDependentOffset())
21380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d2 = base.replace(minute=11, tzinfo=OperandDependentOffset())
21390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for x in d0, d1, d2:
21400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                for y in d0, d1, d2:
21410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    got = cmp(x, y)
21420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    if (x is d0 or x is d1) and (y is d0 or y is d1):
21430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        expected = 0
21440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    elif x is y is d2:
21450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        expected = 0
21460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    elif x is d2:
21470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        expected = -1
21480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    else:
21490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        assert y is d2
21500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        expected = 1
21510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.assertEqual(got, expected)
21520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
21530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
21540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Testing time objects with a non-None tzinfo.
21550a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestTimeTZ(TestTime, TZInfoBase, unittest.TestCase):
21560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    theclass = time
21570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
21580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_empty(self):
21590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass()
21600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.hour, 0)
21610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.minute, 0)
21620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.second, 0)
21630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.microsecond, 0)
21640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t.tzinfo is None)
21650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
21660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_zones(self):
21670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        est = FixedOffset(-300, "EST", 1)
21680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        utc = FixedOffset(0, "UTC", -2)
21690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        met = FixedOffset(60, "MET", 3)
21700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = time( 7, 47, tzinfo=est)
21710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = time(12, 47, tzinfo=utc)
21720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t3 = time(13, 47, tzinfo=met)
21730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t4 = time(microsecond=40)
21740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t5 = time(microsecond=40, tzinfo=utc)
21750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
21760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1.tzinfo, est)
21770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t2.tzinfo, utc)
21780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t3.tzinfo, met)
21790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t4.tzinfo is None)
21800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t5.tzinfo, utc)
21810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
21820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1.utcoffset(), timedelta(minutes=-300))
21830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t2.utcoffset(), timedelta(minutes=0))
21840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t3.utcoffset(), timedelta(minutes=60))
21850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t4.utcoffset() is None)
21860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, t1.utcoffset, "no args")
21870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
21880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1.tzname(), "EST")
21890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t2.tzname(), "UTC")
21900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t3.tzname(), "MET")
21910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t4.tzname() is None)
21920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, t1.tzname, "no args")
21930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
21940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1.dst(), timedelta(minutes=1))
21950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t2.dst(), timedelta(minutes=-2))
21960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t3.dst(), timedelta(minutes=3))
21970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t4.dst() is None)
21980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, t1.dst, "no args")
21990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
22000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(hash(t1), hash(t2))
22010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(hash(t1), hash(t3))
22020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(hash(t2), hash(t3))
22030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
22040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1, t2)
22050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1, t3)
22060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t2, t3)
22070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: t4 == t5) # mixed tz-aware & naive
22080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: t4 < t5) # mixed tz-aware & naive
22090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: t5 < t4) # mixed tz-aware & naive
22100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
22110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(str(t1), "07:47:00-05:00")
22120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(str(t2), "12:47:00+00:00")
22130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(str(t3), "13:47:00+01:00")
22140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(str(t4), "00:00:00.000040")
22150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(str(t5), "00:00:00.000040+00:00")
22160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
22170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1.isoformat(), "07:47:00-05:00")
22180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t2.isoformat(), "12:47:00+00:00")
22190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t3.isoformat(), "13:47:00+01:00")
22200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t4.isoformat(), "00:00:00.000040")
22210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t5.isoformat(), "00:00:00.000040+00:00")
22220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
22230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d = 'datetime.time'
22240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(repr(t1), d + "(7, 47, tzinfo=est)")
22250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(repr(t2), d + "(12, 47, tzinfo=utc)")
22260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(repr(t3), d + "(13, 47, tzinfo=met)")
22270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(repr(t4), d + "(0, 0, 0, 40)")
22280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(repr(t5), d + "(0, 0, 0, 40, tzinfo=utc)")
22290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
22300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1.strftime("%H:%M:%S %%Z=%Z %%z=%z"),
22310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                     "07:47:00 %Z=EST %z=-0500")
22320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t2.strftime("%H:%M:%S %Z %z"), "12:47:00 UTC +0000")
22330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t3.strftime("%H:%M:%S %Z %z"), "13:47:00 MET +0100")
22340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
22350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        yuck = FixedOffset(-1439, "%z %Z %%z%%Z")
22360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = time(23, 59, tzinfo=yuck)
22370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1.strftime("%H:%M %%Z='%Z' %%z='%z'"),
22380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                     "23:59 %Z='%z %Z %%z%%Z' %z='-2359'")
22390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
22400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Check that an invalid tzname result raises an exception.
22410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class Badtzname(tzinfo):
22420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def tzname(self, dt): return 42
22430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = time(2, 3, 4, tzinfo=Badtzname())
22440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.strftime("%H:%M:%S"), "02:03:04")
22450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, t.strftime, "%Z")
22460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
22470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_hash_edge_cases(self):
22480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Offsets that overflow a basic time.
22490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = self.theclass(0, 1, 2, 3, tzinfo=FixedOffset(1439, ""))
22500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = self.theclass(0, 0, 2, 3, tzinfo=FixedOffset(1438, ""))
22510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(hash(t1), hash(t2))
22520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
22530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = self.theclass(23, 58, 6, 100, tzinfo=FixedOffset(-1000, ""))
22540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = self.theclass(23, 48, 6, 100, tzinfo=FixedOffset(-1010, ""))
22550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(hash(t1), hash(t2))
22560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
22570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_pickling(self):
22580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Try one without a tzinfo.
22590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = 20, 59, 16, 64**2
22600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        orig = self.theclass(*args)
22610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for pickler, unpickler, proto in pickle_choices:
22620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            green = pickler.dumps(orig, proto)
22630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            derived = unpickler.loads(green)
22640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(orig, derived)
22650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
22660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Try one with a tzinfo.
22670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        tinfo = PicklableFixedOffset(-300, 'cookie')
22680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        orig = self.theclass(5, 6, 7, tzinfo=tinfo)
22690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for pickler, unpickler, proto in pickle_choices:
22700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            green = pickler.dumps(orig, proto)
22710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            derived = unpickler.loads(green)
22720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(orig, derived)
22730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertIsInstance(derived.tzinfo, PicklableFixedOffset)
22740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(derived.utcoffset(), timedelta(minutes=-300))
22750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(derived.tzname(), 'cookie')
22760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
22770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_more_bool(self):
22780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test cases with non-None tzinfo.
22790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cls = self.theclass
22800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
22810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = cls(0, tzinfo=FixedOffset(-300, ""))
22820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t)
22830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
22840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = cls(5, tzinfo=FixedOffset(-300, ""))
22850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t)
22860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
22870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = cls(5, tzinfo=FixedOffset(300, ""))
22880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not t)
22890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
22900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = cls(23, 59, tzinfo=FixedOffset(23*60 + 59, ""))
22910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not t)
22920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
22930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Mostly ensuring this doesn't overflow internally.
22940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = cls(0, tzinfo=FixedOffset(23*60 + 59, ""))
22950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t)
22960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
22970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # But this should yield a value error -- the utcoffset is bogus.
22980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = cls(0, tzinfo=FixedOffset(24*60, ""))
22990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, lambda: bool(t))
23000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
23010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Likewise.
23020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = cls(0, tzinfo=FixedOffset(-24*60, ""))
23030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, lambda: bool(t))
23040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
23050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_replace(self):
23060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cls = self.theclass
23070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        z100 = FixedOffset(100, "+100")
23080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        zm200 = FixedOffset(timedelta(minutes=-200), "-200")
23090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = [1, 2, 3, 4, z100]
23100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base = cls(*args)
23110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(base, base.replace())
23120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
23130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        i = 0
23140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for name, newval in (("hour", 5),
23150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("minute", 6),
23160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("second", 7),
23170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("microsecond", 8),
23180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("tzinfo", zm200)):
23190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            newargs = args[:]
23200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            newargs[i] = newval
23210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            expected = cls(*newargs)
23220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            got = base.replace(**{name: newval})
23230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(expected, got)
23240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            i += 1
23250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
23260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Ensure we can get rid of a tzinfo.
23270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(base.tzname(), "+100")
23280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base2 = base.replace(tzinfo=None)
23290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(base2.tzinfo is None)
23300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(base2.tzname() is None)
23310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
23320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Ensure we can add one.
23330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base3 = base2.replace(tzinfo=z100)
23340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(base, base3)
23350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(base.tzinfo is base3.tzinfo)
23360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
23370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Out of bounds.
23380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base = cls(1)
23390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, base.replace, hour=24)
23400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, base.replace, minute=-1)
23410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, base.replace, second=100)
23420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, base.replace, microsecond=1000000)
23430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
23440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_mixed_compare(self):
23450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = time(1, 2, 3)
23460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = time(1, 2, 3)
23470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1, t2)
23480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = t2.replace(tzinfo=None)
23490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1, t2)
23500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = t2.replace(tzinfo=FixedOffset(None, ""))
23510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1, t2)
23520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = t2.replace(tzinfo=FixedOffset(0, ""))
23530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: t1 == t2)
23540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
23550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # In time w/ identical tzinfo objects, utcoffset is ignored.
23560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class Varies(tzinfo):
23570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __init__(self):
23580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.offset = timedelta(minutes=22)
23590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def utcoffset(self, t):
23600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.offset += timedelta(minutes=1)
23610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return self.offset
23620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
23630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        v = Varies()
23640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = t2.replace(tzinfo=v)
23650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = t2.replace(tzinfo=v)
23660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1.utcoffset(), timedelta(minutes=23))
23670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t2.utcoffset(), timedelta(minutes=24))
23680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1, t2)
23690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
23700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # But if they're not identical, it isn't ignored.
23710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = t2.replace(tzinfo=Varies())
23720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 < t2)  # t1's offset counter still going up
23730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
23740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_subclass_timetz(self):
23750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
23760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class C(self.theclass):
23770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            theAnswer = 42
23780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
23790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __new__(cls, *args, **kws):
23800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                temp = kws.copy()
23810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                extra = temp.pop('extra')
23820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                result = self.theclass.__new__(cls, *args, **temp)
23830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                result.extra = extra
23840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return result
23850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
23860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def newmeth(self, start):
23870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return start + self.hour + self.second
23880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
23890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = 4, 5, 6, 500, FixedOffset(-300, "EST", 1)
23900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
23910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt1 = self.theclass(*args)
23920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt2 = C(*args, **{'extra': 7})
23930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
23940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2.__class__, C)
23950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2.theAnswer, 42)
23960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2.extra, 7)
23970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt1.utcoffset(), dt2.utcoffset())
23980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2.newmeth(-7), dt1.hour + dt1.second - 7)
23990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
24000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
24010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Testing datetime objects with a non-None tzinfo.
24020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
24030a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestDateTimeTZ(TestDateTime, TZInfoBase, unittest.TestCase):
24040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    theclass = datetime
24050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
24060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_trivial(self):
24070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt = self.theclass(1, 2, 3, 4, 5, 6, 7)
24080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.year, 1)
24090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.month, 2)
24100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.day, 3)
24110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.hour, 4)
24120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.minute, 5)
24130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.second, 6)
24140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.microsecond, 7)
24150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.tzinfo, None)
24160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
24170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_even_more_compare(self):
24180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # The test_compare() and test_more_compare() inherited from TestDate
24190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # and TestDateTime covered non-tzinfo cases.
24200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
24210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Smallest possible after UTC adjustment.
24220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = self.theclass(1, 1, 1, tzinfo=FixedOffset(1439, ""))
24230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Largest possible after UTC adjustment.
24240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = self.theclass(MAXYEAR, 12, 31, 23, 59, 59, 999999,
24250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           tzinfo=FixedOffset(-1439, ""))
24260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
24270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Make sure those compare correctly, and w/o overflow.
24280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 < t2)
24290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 != t2)
24300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t2 > t1)
24310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
24320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 == t1)
24330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t2 == t2)
24340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
24350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Equal afer adjustment.
24360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(1, ""))
24370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = self.theclass(2, 1, 1, 3, 13, tzinfo=FixedOffset(3*60+13+2, ""))
24380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1, t2)
24390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
24400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Change t1 not to subtract a minute, and t1 should be larger.
24410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(0, ""))
24420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 > t2)
24430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
24440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Change t1 to subtract 2 minutes, and t1 should be smaller.
24450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(2, ""))
24460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 < t2)
24470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
24480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Back to the original t1, but make seconds resolve it.
24490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(1, ""),
24500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           second=1)
24510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 > t2)
24520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
24530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Likewise, but make microseconds resolve it.
24540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(1, ""),
24550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           microsecond=1)
24560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 > t2)
24570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
24580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Make t2 naive and it should fail.
24590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = self.theclass.min
24600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: t1 == t2)
24610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t2, t2)
24620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
24630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # It's also naive if it has tzinfo but tzinfo.utcoffset() is None.
24640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class Naive(tzinfo):
24650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def utcoffset(self, dt): return None
24660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = self.theclass(5, 6, 7, tzinfo=Naive())
24670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: t1 == t2)
24680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t2, t2)
24690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
24700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # OTOH, it's OK to compare two of these mixing the two ways of being
24710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # naive.
24720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = self.theclass(5, 6, 7)
24730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1, t2)
24740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
24750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Try a bogus uctoffset.
24760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class Bogus(tzinfo):
24770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def utcoffset(self, dt):
24780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return timedelta(minutes=1440) # out of bounds
24790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = self.theclass(2, 2, 2, tzinfo=Bogus())
24800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = self.theclass(2, 2, 2, tzinfo=FixedOffset(0, ""))
24810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, lambda: t1 == t2)
24820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
24830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_pickling(self):
24840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Try one without a tzinfo.
24850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = 6, 7, 23, 20, 59, 1, 64**2
24860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        orig = self.theclass(*args)
24870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for pickler, unpickler, proto in pickle_choices:
24880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            green = pickler.dumps(orig, proto)
24890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            derived = unpickler.loads(green)
24900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(orig, derived)
24910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
24920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Try one with a tzinfo.
24930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        tinfo = PicklableFixedOffset(-300, 'cookie')
24940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        orig = self.theclass(*args, **{'tzinfo': tinfo})
24950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        derived = self.theclass(1, 1, 1, tzinfo=FixedOffset(0, "", 0))
24960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for pickler, unpickler, proto in pickle_choices:
24970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            green = pickler.dumps(orig, proto)
24980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            derived = unpickler.loads(green)
24990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(orig, derived)
25000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertIsInstance(derived.tzinfo, PicklableFixedOffset)
25010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(derived.utcoffset(), timedelta(minutes=-300))
25020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(derived.tzname(), 'cookie')
25030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
25040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_extreme_hashes(self):
25050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # If an attempt is made to hash these via subtracting the offset
25060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # then hashing a datetime object, OverflowError results.  The
25070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Python implementation used to blow up here.
25080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(1, 1, 1, tzinfo=FixedOffset(1439, ""))
25090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        hash(t)
25100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(MAXYEAR, 12, 31, 23, 59, 59, 999999,
25110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          tzinfo=FixedOffset(-1439, ""))
25120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        hash(t)
25130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
25140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # OTOH, an OOB offset should blow up.
25150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = self.theclass(5, 5, 5, tzinfo=FixedOffset(-1440, ""))
25160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, hash, t)
25170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
25180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_zones(self):
25190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        est = FixedOffset(-300, "EST")
25200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        utc = FixedOffset(0, "UTC")
25210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        met = FixedOffset(60, "MET")
25220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = datetime(2002, 3, 19,  7, 47, tzinfo=est)
25230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = datetime(2002, 3, 19, 12, 47, tzinfo=utc)
25240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t3 = datetime(2002, 3, 19, 13, 47, tzinfo=met)
25250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1.tzinfo, est)
25260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t2.tzinfo, utc)
25270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t3.tzinfo, met)
25280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1.utcoffset(), timedelta(minutes=-300))
25290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t2.utcoffset(), timedelta(minutes=0))
25300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t3.utcoffset(), timedelta(minutes=60))
25310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1.tzname(), "EST")
25320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t2.tzname(), "UTC")
25330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t3.tzname(), "MET")
25340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(hash(t1), hash(t2))
25350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(hash(t1), hash(t3))
25360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(hash(t2), hash(t3))
25370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1, t2)
25380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1, t3)
25390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t2, t3)
25400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(str(t1), "2002-03-19 07:47:00-05:00")
25410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(str(t2), "2002-03-19 12:47:00+00:00")
25420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(str(t3), "2002-03-19 13:47:00+01:00")
25430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d = 'datetime.datetime(2002, 3, 19, '
25440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(repr(t1), d + "7, 47, tzinfo=est)")
25450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(repr(t2), d + "12, 47, tzinfo=utc)")
25460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(repr(t3), d + "13, 47, tzinfo=met)")
25470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
25480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_combine(self):
25490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        met = FixedOffset(60, "MET")
25500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d = date(2002, 3, 4)
25510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        tz = time(18, 45, 3, 1234, tzinfo=met)
25520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt = datetime.combine(d, tz)
25530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt, datetime(2002, 3, 4, 18, 45, 3, 1234,
25540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                        tzinfo=met))
25550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
25560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_extract(self):
25570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        met = FixedOffset(60, "MET")
25580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt = self.theclass(2002, 3, 4, 18, 45, 3, 1234, tzinfo=met)
25590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.date(), date(2002, 3, 4))
25600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.time(), time(18, 45, 3, 1234))
25610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.timetz(), time(18, 45, 3, 1234, tzinfo=met))
25620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
25630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_tz_aware_arithmetic(self):
25640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        import random
25650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
25660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        now = self.theclass.now()
25670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        tz55 = FixedOffset(-330, "west 5:30")
25680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        timeaware = now.time().replace(tzinfo=tz55)
25690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        nowaware = self.theclass.combine(now.date(), timeaware)
25700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(nowaware.tzinfo is tz55)
25710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(nowaware.timetz(), timeaware)
25720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
25730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Can't mix aware and non-aware.
25740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: now - nowaware)
25750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: nowaware - now)
25760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
25770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # And adding datetime's doesn't make sense, aware or not.
25780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: now + nowaware)
25790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: nowaware + now)
25800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: nowaware + nowaware)
25810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
25820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Subtracting should yield 0.
25830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(now - now, timedelta(0))
25840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(nowaware - nowaware, timedelta(0))
25850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
25860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Adding a delta should preserve tzinfo.
25870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        delta = timedelta(weeks=1, minutes=12, microseconds=5678)
25880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        nowawareplus = nowaware + delta
25890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(nowaware.tzinfo is tz55)
25900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        nowawareplus2 = delta + nowaware
25910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(nowawareplus2.tzinfo is tz55)
25920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(nowawareplus, nowawareplus2)
25930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
25940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # that - delta should be what we started with, and that - what we
25950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # started with should be delta.
25960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        diff = nowawareplus - delta
25970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(diff.tzinfo is tz55)
25980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(nowaware, diff)
25990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: delta - nowawareplus)
26000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(nowawareplus - nowaware, delta)
26010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
26020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Make up a random timezone.
26030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        tzr = FixedOffset(random.randrange(-1439, 1440), "randomtimezone")
26040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Attach it to nowawareplus.
26050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        nowawareplus = nowawareplus.replace(tzinfo=tzr)
26060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(nowawareplus.tzinfo is tzr)
26070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Make sure the difference takes the timezone adjustments into account.
26080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        got = nowaware - nowawareplus
26090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Expected:  (nowaware base - nowaware offset) -
26100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #            (nowawareplus base - nowawareplus offset) =
26110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #            (nowaware base - nowawareplus base) +
26120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #            (nowawareplus offset - nowaware offset) =
26130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #            -delta + nowawareplus offset - nowaware offset
26140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected = nowawareplus.utcoffset() - nowaware.utcoffset() - delta
26150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(got, expected)
26160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
26170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Try max possible difference.
26180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        min = self.theclass(1, 1, 1, tzinfo=FixedOffset(1439, "min"))
26190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        max = self.theclass(MAXYEAR, 12, 31, 23, 59, 59, 999999,
26200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            tzinfo=FixedOffset(-1439, "max"))
26210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        maxdiff = max - min
26220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(maxdiff, self.theclass.max - self.theclass.min +
26230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                  timedelta(minutes=2*1439))
26240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
26250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_tzinfo_now(self):
26260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        meth = self.theclass.now
26270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Ensure it doesn't require tzinfo (i.e., that this doesn't blow up).
26280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base = meth()
26290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Try with and without naming the keyword.
26300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        off42 = FixedOffset(42, "42")
26310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        another = meth(off42)
26320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        again = meth(tz=off42)
26330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(another.tzinfo is again.tzinfo)
26340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(another.utcoffset(), timedelta(minutes=42))
26350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Bad argument with and w/o naming the keyword.
26360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, meth, 16)
26370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, meth, tzinfo=16)
26380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Bad keyword name.
26390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, meth, tinfo=off42)
26400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Too many args.
26410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, meth, off42, off42)
26420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
26430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # We don't know which time zone we're in, and don't have a tzinfo
26440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # class to represent it, so seeing whether a tz argument actually
26450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # does a conversion is tricky.
26460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        weirdtz = FixedOffset(timedelta(hours=15, minutes=58), "weirdtz", 0)
26470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        utc = FixedOffset(0, "utc", 0)
26480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for dummy in range(3):
26490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            now = datetime.now(weirdtz)
26500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(now.tzinfo is weirdtz)
26510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            utcnow = datetime.utcnow().replace(tzinfo=utc)
26520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            now2 = utcnow.astimezone(weirdtz)
26530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if abs(now - now2) < timedelta(seconds=30):
26540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                break
26550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Else the code is broken, or more than 30 seconds passed between
26560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # calls; assuming the latter, just try again.
26570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
26580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Three strikes and we're out.
26590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fail("utcnow(), now(tz), or astimezone() may be broken")
26600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
26610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_tzinfo_fromtimestamp(self):
26620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        import time
26630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        meth = self.theclass.fromtimestamp
26640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        ts = time.time()
26650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Ensure it doesn't require tzinfo (i.e., that this doesn't blow up).
26660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base = meth(ts)
26670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Try with and without naming the keyword.
26680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        off42 = FixedOffset(42, "42")
26690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        another = meth(ts, off42)
26700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        again = meth(ts, tz=off42)
26710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(another.tzinfo is again.tzinfo)
26720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(another.utcoffset(), timedelta(minutes=42))
26730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Bad argument with and w/o naming the keyword.
26740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, meth, ts, 16)
26750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, meth, ts, tzinfo=16)
26760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Bad keyword name.
26770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, meth, ts, tinfo=off42)
26780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Too many args.
26790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, meth, ts, off42, off42)
26800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Too few args.
26810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, meth)
26820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
26830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Try to make sure tz= actually does some conversion.
26840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        timestamp = 1000000000
26850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        utcdatetime = datetime.utcfromtimestamp(timestamp)
26860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # In POSIX (epoch 1970), that's 2001-09-09 01:46:40 UTC, give or take.
26870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # But on some flavor of Mac, it's nowhere near that.  So we can't have
26880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # any idea here what time that actually is, we can only test that
26890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # relative changes match.
26900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        utcoffset = timedelta(hours=-15, minutes=39) # arbitrary, but not zero
26910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        tz = FixedOffset(utcoffset, "tz", 0)
26920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected = utcdatetime + utcoffset
26930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        got = datetime.fromtimestamp(timestamp, tz)
26940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(expected, got.replace(tzinfo=None))
26950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
26960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_tzinfo_utcnow(self):
26970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        meth = self.theclass.utcnow
26980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Ensure it doesn't require tzinfo (i.e., that this doesn't blow up).
26990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base = meth()
27000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Try with and without naming the keyword; for whatever reason,
27010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # utcnow() doesn't accept a tzinfo argument.
27020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        off42 = FixedOffset(42, "42")
27030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, meth, off42)
27040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, meth, tzinfo=off42)
27050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
27060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_tzinfo_utcfromtimestamp(self):
27070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        import time
27080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        meth = self.theclass.utcfromtimestamp
27090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        ts = time.time()
27100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Ensure it doesn't require tzinfo (i.e., that this doesn't blow up).
27110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base = meth(ts)
27120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Try with and without naming the keyword; for whatever reason,
27130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # utcfromtimestamp() doesn't accept a tzinfo argument.
27140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        off42 = FixedOffset(42, "42")
27150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, meth, ts, off42)
27160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, meth, ts, tzinfo=off42)
27170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
27180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_tzinfo_timetuple(self):
27190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # TestDateTime tested most of this.  datetime adds a twist to the
27200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # DST flag.
27210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class DST(tzinfo):
27220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __init__(self, dstvalue):
27230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if isinstance(dstvalue, int):
27240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    dstvalue = timedelta(minutes=dstvalue)
27250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.dstvalue = dstvalue
27260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def dst(self, dt):
27270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return self.dstvalue
27280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
27290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cls = self.theclass
27300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for dstvalue, flag in (-33, 1), (33, 1), (0, 0), (None, -1):
27310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d = cls(1, 1, 1, 10, 20, 30, 40, tzinfo=DST(dstvalue))
27320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            t = d.timetuple()
27330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(1, t.tm_year)
27340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(1, t.tm_mon)
27350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(1, t.tm_mday)
27360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(10, t.tm_hour)
27370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(20, t.tm_min)
27380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(30, t.tm_sec)
27390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(0, t.tm_wday)
27400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(1, t.tm_yday)
27410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(flag, t.tm_isdst)
27420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
27430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # dst() returns wrong type.
27440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, cls(1, 1, 1, tzinfo=DST("x")).timetuple)
27450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
27460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # dst() at the edge.
27470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(cls(1,1,1, tzinfo=DST(1439)).timetuple().tm_isdst, 1)
27480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(cls(1,1,1, tzinfo=DST(-1439)).timetuple().tm_isdst, 1)
27490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
27500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # dst() out of range.
27510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, cls(1,1,1, tzinfo=DST(1440)).timetuple)
27520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, cls(1,1,1, tzinfo=DST(-1440)).timetuple)
27530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
27540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_utctimetuple(self):
27550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class DST(tzinfo):
27560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __init__(self, dstvalue):
27570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if isinstance(dstvalue, int):
27580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    dstvalue = timedelta(minutes=dstvalue)
27590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.dstvalue = dstvalue
27600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def dst(self, dt):
27610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return self.dstvalue
27620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
27630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cls = self.theclass
27640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # This can't work:  DST didn't implement utcoffset.
27650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(NotImplementedError,
27660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          cls(1, 1, 1, tzinfo=DST(0)).utcoffset)
27670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
27680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class UOFS(DST):
27690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __init__(self, uofs, dofs=None):
27700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                DST.__init__(self, dofs)
27710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.uofs = timedelta(minutes=uofs)
27720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def utcoffset(self, dt):
27730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return self.uofs
27740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
27750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Ensure tm_isdst is 0 regardless of what dst() says:  DST is never
27760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # in effect for a UTC time.
27770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for dstvalue in -33, 33, 0, None:
27780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d = cls(1, 2, 3, 10, 20, 30, 40, tzinfo=UOFS(-53, dstvalue))
27790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            t = d.utctimetuple()
27800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(d.year, t.tm_year)
27810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(d.month, t.tm_mon)
27820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(d.day, t.tm_mday)
27830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(11, t.tm_hour) # 20mm + 53mm = 1hn + 13mm
27840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(13, t.tm_min)
27850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(d.second, t.tm_sec)
27860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(d.weekday(), t.tm_wday)
27870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(d.toordinal() - date(1, 1, 1).toordinal() + 1,
27880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             t.tm_yday)
27890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(0, t.tm_isdst)
27900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
27910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # At the edges, UTC adjustment can normalize into years out-of-range
27920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # for a datetime object.  Ensure that a correct timetuple is
27930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # created anyway.
27940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        tiny = cls(MINYEAR, 1, 1, 0, 0, 37, tzinfo=UOFS(1439))
27950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # That goes back 1 minute less than a full day.
27960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = tiny.utctimetuple()
27970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.tm_year, MINYEAR-1)
27980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.tm_mon, 12)
27990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.tm_mday, 31)
28000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.tm_hour, 0)
28010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.tm_min, 1)
28020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.tm_sec, 37)
28030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.tm_yday, 366)    # "year 0" is a leap year
28040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.tm_isdst, 0)
28050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
28060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        huge = cls(MAXYEAR, 12, 31, 23, 59, 37, 999999, tzinfo=UOFS(-1439))
28070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # That goes forward 1 minute less than a full day.
28080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t = huge.utctimetuple()
28090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.tm_year, MAXYEAR+1)
28100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.tm_mon, 1)
28110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.tm_mday, 1)
28120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.tm_hour, 23)
28130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.tm_min, 58)
28140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.tm_sec, 37)
28150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.tm_yday, 1)
28160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t.tm_isdst, 0)
28170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
28180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_tzinfo_isoformat(self):
28190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        zero = FixedOffset(0, "+00:00")
28200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        plus = FixedOffset(220, "+03:40")
28210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        minus = FixedOffset(-231, "-03:51")
28220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        unknown = FixedOffset(None, "")
28230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
28240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cls = self.theclass
28250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        datestr = '0001-02-03'
28260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for ofs in None, zero, plus, minus, unknown:
28270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for us in 0, 987001:
28280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                d = cls(1, 2, 3, 4, 5, 59, us, tzinfo=ofs)
28290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                timestr = '04:05:59' + (us and '.987001' or '')
28300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ofsstr = ofs is not None and d.tzname() or ''
28310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                tailstr = timestr + ofsstr
28320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                iso = d.isoformat()
28330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(iso, datestr + 'T' + tailstr)
28340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(iso, d.isoformat('T'))
28350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(d.isoformat('k'), datestr + 'k' + tailstr)
28360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(str(d), datestr + ' ' + tailstr)
28370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
28380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_replace(self):
28390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cls = self.theclass
28400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        z100 = FixedOffset(100, "+100")
28410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        zm200 = FixedOffset(timedelta(minutes=-200), "-200")
28420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = [1, 2, 3, 4, 5, 6, 7, z100]
28430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base = cls(*args)
28440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(base, base.replace())
28450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
28460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        i = 0
28470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for name, newval in (("year", 2),
28480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("month", 3),
28490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("day", 4),
28500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("hour", 5),
28510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("minute", 6),
28520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("second", 7),
28530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("microsecond", 8),
28540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             ("tzinfo", zm200)):
28550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            newargs = args[:]
28560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            newargs[i] = newval
28570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            expected = cls(*newargs)
28580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            got = base.replace(**{name: newval})
28590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(expected, got)
28600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            i += 1
28610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
28620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Ensure we can get rid of a tzinfo.
28630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(base.tzname(), "+100")
28640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base2 = base.replace(tzinfo=None)
28650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(base2.tzinfo is None)
28660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(base2.tzname() is None)
28670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
28680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Ensure we can add one.
28690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base3 = base2.replace(tzinfo=z100)
28700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(base, base3)
28710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(base.tzinfo is base3.tzinfo)
28720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
28730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Out of bounds.
28740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base = cls(2000, 2, 29)
28750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, base.replace, year=2001)
28760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
28770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_more_astimezone(self):
28780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # The inherited test_astimezone covered some trivial and error cases.
28790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fnone = FixedOffset(None, "None")
28800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f44m = FixedOffset(44, "44")
28810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fm5h = FixedOffset(-timedelta(hours=5), "m300")
28820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
28830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt = self.theclass.now(tz=f44m)
28840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(dt.tzinfo is f44m)
28850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Replacing with degenerate tzinfo raises an exception.
28860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, dt.astimezone, fnone)
28870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Ditto with None tz.
28880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, dt.astimezone, None)
28890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Replacing with same tzinfo makes no change.
28900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        x = dt.astimezone(dt.tzinfo)
28910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(x.tzinfo is f44m)
28920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(x.date(), dt.date())
28930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(x.time(), dt.time())
28940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
28950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Replacing with different tzinfo does adjust.
28960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        got = dt.astimezone(fm5h)
28970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(got.tzinfo is fm5h)
28980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(got.utcoffset(), timedelta(hours=-5))
28990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected = dt - dt.utcoffset()  # in effect, convert to UTC
29000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected += fm5h.utcoffset(dt)  # and from there to local time
29010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected = expected.replace(tzinfo=fm5h) # and attach new tzinfo
29020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(got.date(), expected.date())
29030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(got.time(), expected.time())
29040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(got.timetz(), expected.timetz())
29050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(got.tzinfo is expected.tzinfo)
29060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(got, expected)
29070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
29080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_aware_subtract(self):
29090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cls = self.theclass
29100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
29110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Ensure that utcoffset() is ignored when the operands have the
29120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # same tzinfo member.
29130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class OperandDependentOffset(tzinfo):
29140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def utcoffset(self, t):
29150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if t.minute < 10:
29160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    # d0 and d1 equal after adjustment
29170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    return timedelta(minutes=t.minute)
29180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                else:
29190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    # d2 off in the weeds
29200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    return timedelta(minutes=59)
29210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
29220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base = cls(8, 9, 10, 11, 12, 13, 14, tzinfo=OperandDependentOffset())
29230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d0 = base.replace(minute=3)
29240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d1 = base.replace(minute=9)
29250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d2 = base.replace(minute=11)
29260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for x in d0, d1, d2:
29270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for y in d0, d1, d2:
29280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                got = x - y
29290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                expected = timedelta(minutes=x.minute - y.minute)
29300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(got, expected)
29310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
29320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # OTOH, if the tzinfo members are distinct, utcoffsets aren't
29330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # ignored.
29340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        base = cls(8, 9, 10, 11, 12, 13, 14)
29350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d0 = base.replace(minute=3, tzinfo=OperandDependentOffset())
29360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d1 = base.replace(minute=9, tzinfo=OperandDependentOffset())
29370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d2 = base.replace(minute=11, tzinfo=OperandDependentOffset())
29380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for x in d0, d1, d2:
29390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for y in d0, d1, d2:
29400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                got = x - y
29410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if (x is d0 or x is d1) and (y is d0 or y is d1):
29420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    expected = timedelta(0)
29430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                elif x is y is d2:
29440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    expected = timedelta(0)
29450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                elif x is d2:
29460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    expected = timedelta(minutes=(11-59)-0)
29470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                else:
29480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    assert y is d2
29490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    expected = timedelta(minutes=0-(11-59))
29500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(got, expected)
29510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
29520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_mixed_compare(self):
29530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = datetime(1, 2, 3, 4, 5, 6, 7)
29540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = datetime(1, 2, 3, 4, 5, 6, 7)
29550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1, t2)
29560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = t2.replace(tzinfo=None)
29570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1, t2)
29580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = t2.replace(tzinfo=FixedOffset(None, ""))
29590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1, t2)
29600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = t2.replace(tzinfo=FixedOffset(0, ""))
29610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: t1 == t2)
29620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
29630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # In datetime w/ identical tzinfo objects, utcoffset is ignored.
29640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class Varies(tzinfo):
29650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __init__(self):
29660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.offset = timedelta(minutes=22)
29670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def utcoffset(self, t):
29680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.offset += timedelta(minutes=1)
29690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return self.offset
29700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
29710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        v = Varies()
29720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t1 = t2.replace(tzinfo=v)
29730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = t2.replace(tzinfo=v)
29740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1.utcoffset(), timedelta(minutes=23))
29750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t2.utcoffset(), timedelta(minutes=24))
29760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(t1, t2)
29770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
29780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # But if they're not identical, it isn't ignored.
29790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        t2 = t2.replace(tzinfo=Varies())
29800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(t1 < t2)  # t1's offset counter still going up
29810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
29820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_subclass_datetimetz(self):
29830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
29840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class C(self.theclass):
29850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            theAnswer = 42
29860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
29870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __new__(cls, *args, **kws):
29880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                temp = kws.copy()
29890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                extra = temp.pop('extra')
29900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                result = self.theclass.__new__(cls, *args, **temp)
29910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                result.extra = extra
29920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return result
29930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
29940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def newmeth(self, start):
29950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return start + self.hour + self.year
29960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
29970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args = 2002, 12, 31, 4, 5, 6, 500, FixedOffset(-300, "EST", 1)
29980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
29990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt1 = self.theclass(*args)
30000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt2 = C(*args, **{'extra': 7})
30010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2.__class__, C)
30030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2.theAnswer, 42)
30040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2.extra, 7)
30050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt1.utcoffset(), dt2.utcoffset())
30060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt2.newmeth(-7), dt1.hour + dt1.year - 7)
30070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Pain to set up DST-aware tzinfo classes.
30090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30100a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef first_sunday_on_or_after(dt):
30110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    days_to_go = 6 - dt.weekday()
30120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if days_to_go:
30130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dt += timedelta(days_to_go)
30140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return dt
30150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30160a8c90248264a8b26970b4473770bcc3df8515fJosh GaoZERO = timedelta(0)
30170a8c90248264a8b26970b4473770bcc3df8515fJosh GaoHOUR = timedelta(hours=1)
30180a8c90248264a8b26970b4473770bcc3df8515fJosh GaoDAY = timedelta(days=1)
30190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# In the US, DST starts at 2am (standard time) on the first Sunday in April.
30200a8c90248264a8b26970b4473770bcc3df8515fJosh GaoDSTSTART = datetime(1, 4, 1, 2)
30210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct,
30220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# which is the first Sunday on or after Oct 25.  Because we view 1:MM as
30230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# being standard time on that day, there is no spelling in local time of
30240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# the last hour of DST (that's 1:MM DST, but 1:MM is taken as standard time).
30250a8c90248264a8b26970b4473770bcc3df8515fJosh GaoDSTEND = datetime(1, 10, 25, 1)
30260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30270a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass USTimeZone(tzinfo):
30280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, hours, reprname, stdname, dstname):
30300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.stdoffset = timedelta(hours=hours)
30310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.reprname = reprname
30320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.stdname = stdname
30330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.dstname = dstname
30340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __repr__(self):
30360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.reprname
30370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def tzname(self, dt):
30390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.dst(dt):
30400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return self.dstname
30410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
30420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return self.stdname
30430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def utcoffset(self, dt):
30450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.stdoffset + self.dst(dt)
30460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def dst(self, dt):
30480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if dt is None or dt.tzinfo is None:
30490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # An exception instead may be sensible here, in one or more of
30500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # the cases.
30510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return ZERO
30520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        assert dt.tzinfo is self
30530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Find first Sunday in April.
30550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        start = first_sunday_on_or_after(DSTSTART.replace(year=dt.year))
30560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        assert start.weekday() == 6 and start.month == 4 and start.day <= 7
30570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Find last Sunday in October.
30590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        end = first_sunday_on_or_after(DSTEND.replace(year=dt.year))
30600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        assert end.weekday() == 6 and end.month == 10 and end.day >= 25
30610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Can't compare naive to aware objects, so strip the timezone from
30630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # dt first.
30640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if start <= dt.replace(tzinfo=None) < end:
30650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return HOUR
30660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
30670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return ZERO
30680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30690a8c90248264a8b26970b4473770bcc3df8515fJosh GaoEastern  = USTimeZone(-5, "Eastern",  "EST", "EDT")
30700a8c90248264a8b26970b4473770bcc3df8515fJosh GaoCentral  = USTimeZone(-6, "Central",  "CST", "CDT")
30710a8c90248264a8b26970b4473770bcc3df8515fJosh GaoMountain = USTimeZone(-7, "Mountain", "MST", "MDT")
30720a8c90248264a8b26970b4473770bcc3df8515fJosh GaoPacific  = USTimeZone(-8, "Pacific",  "PST", "PDT")
30730a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoutc_real = FixedOffset(0, "UTC", 0)
30740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# For better test coverage, we want another flavor of UTC that's west of
30750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# the Eastern and Pacific timezones.
30760a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoutc_fake = FixedOffset(-12*60, "UTCfake", 0)
30770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30780a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestTimezoneConversions(unittest.TestCase):
30790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # The DST switch times for 2002, in std time.
30800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    dston = datetime(2002, 4, 7, 2)
30810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    dstoff = datetime(2002, 10, 27, 1)
30820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    theclass = datetime
30840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Check a time that's inside DST.
30860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def checkinside(self, dt, tz, utc, dston, dstoff):
30870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.dst(), HOUR)
30880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Conversion to our own timezone is always an identity.
30900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.astimezone(tz), dt)
30910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        asutc = dt.astimezone(utc)
30930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        there_and_back = asutc.astimezone(tz)
30940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Conversion to UTC and back isn't always an identity here,
30960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # because there are redundant spellings (in local time) of
30970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # UTC time when DST begins:  the clock jumps from 1:59:59
30980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # to 3:00:00, and a local time of 2:MM:SS doesn't really
30990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # make sense then.  The classes above treat 2:MM:SS as
31000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # daylight time then (it's "after 2am"), really an alias
31010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # for 1:MM:SS standard time.  The latter form is what
31020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # conversion back from UTC produces.
31030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if dt.date() == dston.date() and dt.hour == 2:
31040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # We're in the redundant hour, and coming back from
31050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # UTC gives the 1:MM:SS standard-time spelling.
31060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(there_and_back + HOUR, dt)
31070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Although during was considered to be in daylight
31080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # time, there_and_back is not.
31090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(there_and_back.dst(), ZERO)
31100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # They're the same times in UTC.
31110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(there_and_back.astimezone(utc),
31120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             dt.astimezone(utc))
31130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
31140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # We're not in the redundant hour.
31150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(dt, there_and_back)
31160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
31170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Because we have a redundant spelling when DST begins, there is
31180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # (unfortunately) an hour when DST ends that can't be spelled at all in
31190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # local time.  When DST ends, the clock jumps from 1:59 back to 1:00
31200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # again.  The hour 1:MM DST has no spelling then:  1:MM is taken to be
31210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # standard time.  1:MM DST == 0:MM EST, but 0:MM is taken to be
31220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # daylight time.  The hour 1:MM daylight == 0:MM standard can't be
31230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # expressed in local time.  Nevertheless, we want conversion back
31240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # from UTC to mimic the local clock's "repeat an hour" behavior.
31250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        nexthour_utc = asutc + HOUR
31260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        nexthour_tz = nexthour_utc.astimezone(tz)
31270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if dt.date() == dstoff.date() and dt.hour == 0:
31280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # We're in the hour before the last DST hour.  The last DST hour
31290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # is ineffable.  We want the conversion back to repeat 1:MM.
31300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(nexthour_tz, dt.replace(hour=1))
31310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            nexthour_utc += HOUR
31320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            nexthour_tz = nexthour_utc.astimezone(tz)
31330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(nexthour_tz, dt.replace(hour=1))
31340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
31350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(nexthour_tz - dt, HOUR)
31360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
31370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Check a time that's outside DST.
31380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def checkoutside(self, dt, tz, utc):
31390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.dst(), ZERO)
31400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
31410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Conversion to our own timezone is always an identity.
31420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt.astimezone(tz), dt)
31430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
31440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Converting to UTC and back is an identity too.
31450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        asutc = dt.astimezone(utc)
31460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        there_and_back = asutc.astimezone(tz)
31470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(dt, there_and_back)
31480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
31490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def convert_between_tz_and_utc(self, tz, utc):
31500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dston = self.dston.replace(tzinfo=tz)
31510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Because 1:MM on the day DST ends is taken as being standard time,
31520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # there is no spelling in tz for the last hour of daylight time.
31530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # For purposes of the test, the last hour of DST is 0:MM, which is
31540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # taken as being daylight time (and 1:MM is taken as being standard
31550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # time).
31560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dstoff = self.dstoff.replace(tzinfo=tz)
31570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for delta in (timedelta(weeks=13),
31580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                      DAY,
31590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                      HOUR,
31600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                      timedelta(minutes=1),
31610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                      timedelta(microseconds=1)):
31620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
31630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.checkinside(dston, tz, utc, dston, dstoff)
31640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for during in dston + delta, dstoff - delta:
31650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.checkinside(during, tz, utc, dston, dstoff)
31660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
31670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.checkoutside(dstoff, tz, utc)
31680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for outside in dston - delta, dstoff + delta:
31690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.checkoutside(outside, tz, utc)
31700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
31710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_easy(self):
31720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Despite the name of this test, the endcases are excruciating.
31730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.convert_between_tz_and_utc(Eastern, utc_real)
31740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.convert_between_tz_and_utc(Pacific, utc_real)
31750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.convert_between_tz_and_utc(Eastern, utc_fake)
31760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.convert_between_tz_and_utc(Pacific, utc_fake)
31770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # The next is really dancing near the edge.  It works because
31780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Pacific and Eastern are far enough apart that their "problem
31790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # hours" don't overlap.
31800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.convert_between_tz_and_utc(Eastern, Pacific)
31810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.convert_between_tz_and_utc(Pacific, Eastern)
31820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # OTOH, these fail!  Don't enable them.  The difficulty is that
31830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # the edge case tests assume that every hour is representable in
31840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # the "utc" class.  This is always true for a fixed-offset tzinfo
31850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # class (lke utc_real and utc_fake), but not for Eastern or Central.
31860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # For these adjacent DST-aware time zones, the range of time offsets
31870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # tested ends up creating hours in the one that aren't representable
31880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # in the other.  For the same reason, we would see failures in the
31890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Eastern vs Pacific tests too if we added 3*HOUR to the list of
31900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # offset deltas in convert_between_tz_and_utc().
31910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
31920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # self.convert_between_tz_and_utc(Eastern, Central)  # can't work
31930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # self.convert_between_tz_and_utc(Central, Eastern)  # can't work
31940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
31950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_tricky(self):
31960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # 22:00 on day before daylight starts.
31970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fourback = self.dston - timedelta(hours=4)
31980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        ninewest = FixedOffset(-9*60, "-0900", 0)
31990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fourback = fourback.replace(tzinfo=ninewest)
32000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # 22:00-0900 is 7:00 UTC == 2:00 EST == 3:00 DST.  Since it's "after
32010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # 2", we should get the 3 spelling.
32020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # If we plug 22:00 the day before into Eastern, it "looks like std
32030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # time", so its offset is returned as -5, and -5 - -9 = 4.  Adding 4
32040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # to 22:00 lands on 2:00, which makes no sense in local time (the
32050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # local clock jumps from 1 to 3).  The point here is to make sure we
32060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # get the 3 spelling.
32070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected = self.dston.replace(hour=3)
32080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        got = fourback.astimezone(Eastern).replace(tzinfo=None)
32090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(expected, got)
32100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
32110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Similar, but map to 6:00 UTC == 1:00 EST == 2:00 DST.  In that
32120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # case we want the 1:00 spelling.
32130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sixutc = self.dston.replace(hour=6, tzinfo=utc_real)
32140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Now 6:00 "looks like daylight", so the offset wrt Eastern is -4,
32150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # and adding -4-0 == -4 gives the 2:00 spelling.  We want the 1:00 EST
32160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # spelling.
32170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected = self.dston.replace(hour=1)
32180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        got = sixutc.astimezone(Eastern).replace(tzinfo=None)
32190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(expected, got)
32200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
32210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Now on the day DST ends, we want "repeat an hour" behavior.
32220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #  UTC  4:MM  5:MM  6:MM  7:MM  checking these
32230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #  EST 23:MM  0:MM  1:MM  2:MM
32240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #  EDT  0:MM  1:MM  2:MM  3:MM
32250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # wall  0:MM  1:MM  1:MM  2:MM  against these
32260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for utc in utc_real, utc_fake:
32270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for tz in Eastern, Pacific:
32280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                first_std_hour = self.dstoff - timedelta(hours=2) # 23:MM
32290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # Convert that to UTC.
32300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                first_std_hour -= tz.utcoffset(None)
32310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # Adjust for possibly fake UTC.
32320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                asutc = first_std_hour + utc.utcoffset(None)
32330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # First UTC hour to convert; this is 4:00 when utc=utc_real &
32340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # tz=Eastern.
32350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                asutcbase = asutc.replace(tzinfo=utc)
32360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                for tzhour in (0, 1, 1, 2):
32370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    expectedbase = self.dstoff.replace(hour=tzhour)
32380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    for minute in 0, 30, 59:
32390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        expected = expectedbase.replace(minute=minute)
32400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        asutc = asutcbase.replace(minute=minute)
32410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        astz = asutc.astimezone(tz)
32420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        self.assertEqual(astz.replace(tzinfo=None), expected)
32430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    asutcbase += HOUR
32440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
32450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
32460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_bogus_dst(self):
32470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class ok(tzinfo):
32480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def utcoffset(self, dt): return HOUR
32490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def dst(self, dt): return HOUR
32500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
32510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        now = self.theclass.now().replace(tzinfo=utc_real)
32520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Doesn't blow up.
32530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        now.astimezone(ok())
32540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
32550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Does blow up.
32560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class notok(ok):
32570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def dst(self, dt): return None
32580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, now.astimezone, notok())
32590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
32600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_fromutc(self):
32610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, Eastern.fromutc)   # not enough args
32620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        now = datetime.utcnow().replace(tzinfo=utc_real)
32630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, Eastern.fromutc, now) # wrong tzinfo
32640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        now = now.replace(tzinfo=Eastern)   # insert correct tzinfo
32650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        enow = Eastern.fromutc(now)         # doesn't blow up
32660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(enow.tzinfo, Eastern) # has right tzinfo member
32670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, Eastern.fromutc, now, now) # too many args
32680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, Eastern.fromutc, date.today()) # wrong type
32690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
32700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Always converts UTC to standard time.
32710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class FauxUSTimeZone(USTimeZone):
32720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def fromutc(self, dt):
32730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return dt + self.stdoffset
32740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        FEastern  = FauxUSTimeZone(-5, "FEastern",  "FEST", "FEDT")
32750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
32760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #  UTC  4:MM  5:MM  6:MM  7:MM  8:MM  9:MM
32770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #  EST 23:MM  0:MM  1:MM  2:MM  3:MM  4:MM
32780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #  EDT  0:MM  1:MM  2:MM  3:MM  4:MM  5:MM
32790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
32800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Check around DST start.
32810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        start = self.dston.replace(hour=4, tzinfo=Eastern)
32820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fstart = start.replace(tzinfo=FEastern)
32830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for wall in 23, 0, 1, 3, 4, 5:
32840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            expected = start.replace(hour=wall)
32850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if wall == 23:
32860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                expected -= timedelta(days=1)
32870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            got = Eastern.fromutc(start)
32880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(expected, got)
32890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
32900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            expected = fstart + FEastern.stdoffset
32910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            got = FEastern.fromutc(fstart)
32920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(expected, got)
32930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
32940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Ensure astimezone() calls fromutc() too.
32950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            got = fstart.replace(tzinfo=utc_real).astimezone(FEastern)
32960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(expected, got)
32970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
32980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            start += HOUR
32990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fstart += HOUR
33000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
33010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Check around DST end.
33020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        start = self.dstoff.replace(hour=4, tzinfo=Eastern)
33030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fstart = start.replace(tzinfo=FEastern)
33040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for wall in 0, 1, 1, 2, 3, 4:
33050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            expected = start.replace(hour=wall)
33060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            got = Eastern.fromutc(start)
33070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(expected, got)
33080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
33090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            expected = fstart + FEastern.stdoffset
33100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            got = FEastern.fromutc(fstart)
33110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(expected, got)
33120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
33130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Ensure astimezone() calls fromutc() too.
33140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            got = fstart.replace(tzinfo=utc_real).astimezone(FEastern)
33150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(expected, got)
33160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
33170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            start += HOUR
33180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fstart += HOUR
33190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
33200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
33210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#############################################################################
33220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# oddballs
33230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
33240a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass Oddballs(unittest.TestCase):
33250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
33260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_bug_1028306(self):
33270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Trying to compare a date to a datetime should act like a mixed-
33280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # type comparison, despite that datetime is a subclass of date.
33290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        as_date = date.today()
33300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        as_datetime = datetime.combine(as_date, time())
33310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(as_date != as_datetime)
33320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(as_datetime != as_date)
33330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not as_date == as_datetime)
33340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not as_datetime == as_date)
33350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: as_date < as_datetime)
33360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: as_datetime < as_date)
33370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: as_date <= as_datetime)
33380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: as_datetime <= as_date)
33390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: as_date > as_datetime)
33400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: as_datetime > as_date)
33410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: as_date >= as_datetime)
33420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, lambda: as_datetime >= as_date)
33430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
33440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Neverthelss, comparison should work with the base-class (date)
33450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # projection if use of a date method is forced.
33460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(as_date.__eq__(as_datetime))
33470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        different_day = (as_date.day + 1) % 20 + 1
33480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not as_date.__eq__(as_datetime.replace(day=
33490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                                     different_day)))
33500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
33510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # And date should compare with other subclasses of date.  If a
33520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # subclass wants to stop this, it's up to the subclass to do so.
33530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        date_sc = SubclassDate(as_date.year, as_date.month, as_date.day)
33540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(as_date, date_sc)
33550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(date_sc, as_date)
33560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
33570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Ditto for datetimes.
33580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        datetime_sc = SubclassDatetime(as_datetime.year, as_datetime.month,
33590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                       as_date.day, 0, 0, 0)
33600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(as_datetime, datetime_sc)
33610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(datetime_sc, as_datetime)
33620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
33630a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef test_main():
33640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    test_support.run_unittest(__name__)
33650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
33660a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif __name__ == "__main__":
33670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    test_main()
3368