Beispiel #1
0
    def test_fromisoformat_datetime(self):
        # Test that isoformat() is reversible
        base_dates = [(1, 1, 1), (1900, 1, 1), (2004, 11, 12), (2017, 5, 30)]

        base_times = [
            (0, 0, 0, 0),
            (0, 0, 0, 241000),
            (0, 0, 0, 234567),
            (12, 30, 45, 234567),
        ]

        separators = [" ", "T"]

        tzinfos = [
            None,
            timezone.utc,
            timezone(timedelta(hours=-5)),
            timezone(timedelta(hours=2)),
        ]

        dts = [
            self.theclass(*date_tuple, *time_tuple, tzinfo=tzi)
            for date_tuple in base_dates for time_tuple in base_times
            for tzi in tzinfos
        ]

        for dt in dts:
            for sep in separators:
                dtstr = dt.isoformat(sep=sep)

                with self.subTest(dtstr=dtstr):
                    dt_rt = self.theclass.fromisoformat(dtstr)
                    self.assertEqual(dt, dt_rt)
Beispiel #2
0
    def test_fromisoformat_timespecs(self):
        datetime_bases = [(2009, 12, 4, 8, 17, 45, 123456),
                          (2009, 12, 4, 8, 17, 45, 0)]

        tzinfos = [
            None,
            timezone.utc,
            timezone(timedelta(hours=-5)),
            timezone(timedelta(hours=2)),
            timezone(timedelta(hours=6, minutes=27)),
        ]

        timespecs = [
            "hours", "minutes", "seconds", "milliseconds", "microseconds"
        ]

        for ip, ts in enumerate(timespecs):
            for tzi in tzinfos:
                for dt_tuple in datetime_bases:
                    if ts == "milliseconds":
                        new_microseconds = 1000 * (dt_tuple[6] // 1000)
                        dt_tuple = dt_tuple[0:6] + (new_microseconds, )

                    dt = self.theclass(*(dt_tuple[0:(4 + ip)]), tzinfo=tzi)
                    dtstr = dt.isoformat(timespec=ts)
                    with self.subTest(dtstr=dtstr):
                        dt_rt = self.theclass.fromisoformat(dtstr)
                        self.assertEqual(dt, dt_rt)
Beispiel #3
0
    def test_timestamp_naive(self):
        t = self.theclass(1970, 1, 1)
        self.assertEqual(t.timestamp(), 18000.0)
        t = self.theclass(1970, 1, 1, 1, 2, 3, 4)
        self.assertEqual(t.timestamp(), 18000.0 + 3600 + 2 * 60 + 3 + 4 * 1e-6)
        # Missing hour
        t0 = self.theclass(2012, 3, 11, 2, 30)
        t1 = t0.replace(fold=1)
        self.assertEqual(self.theclass.fromtimestamp(t1.timestamp()),
                         t0 - timedelta(hours=1))
        self.assertEqual(self.theclass.fromtimestamp(t0.timestamp()),
                         t1 + timedelta(hours=1))
        # Ambiguous hour defaults to DST
        t = self.theclass(2012, 11, 4, 1, 30)
        self.assertEqual(self.theclass.fromtimestamp(t.timestamp()), t)

        # Timestamp may raise an overflow error on some platforms
        # XXX: Do we care to support the first and last year?
        for t in [self.theclass(2, 1, 1), self.theclass(9998, 12, 12)]:
            try:
                s = t.timestamp()
            except OverflowError:
                pass
            else:
                self.assertEqual(self.theclass.fromtimestamp(s), t)
Beispiel #4
0
 def __init__(self, offset, name, dstoffset=42):
     if isinstance(offset, int):
         offset = timedelta(minutes=offset)
     if isinstance(dstoffset, int):
         dstoffset = timedelta(minutes=dstoffset)
     self.__offset = offset
     self.__name = name
     self.__dstoffset = dstoffset
Beispiel #5
0
    def test_strptime(self):
        string = '2004-12-01 13:02:47.197'
        format = '%Y-%m-%d %H:%M:%S.%f'
        expected = _strptime._strptime_datetime(self.theclass, string, format)
        got = self.theclass.strptime(string, format)
        self.assertEqual(expected, got)
        self.assertIs(type(expected), self.theclass)
        self.assertIs(type(got), self.theclass)

        # bpo-34482: Check that surrogates are handled properly.
        inputs = [
            ('2004-12-01\ud80013:02:47.197', '%Y-%m-%d\ud800%H:%M:%S.%f'),
            ('2004\ud80012-01 13:02:47.197', '%Y\ud800%m-%d %H:%M:%S.%f'),
            ('2004-12-01 13:02\ud80047.197', '%Y-%m-%d %H:%M\ud800%S.%f'),
        ]
        for string, format in inputs:
            with self.subTest(string=string, format=format):
                expected = _strptime._strptime_datetime(
                    self.theclass, string, format)
                got = self.theclass.strptime(string, format)
                self.assertEqual(expected, got)

        strptime = self.theclass.strptime

        self.assertEqual(strptime("+0002", "%z").utcoffset(), 2 * MINUTE)
        self.assertEqual(strptime("-0002", "%z").utcoffset(), -2 * MINUTE)
        self.assertEqual(
            strptime("-00:02:01.000003", "%z").utcoffset(),
            -timedelta(minutes=2, seconds=1, microseconds=3))
        # Only local timezone and UTC are supported
        for tzseconds, tzname in ((0, 'UTC'), (0, 'GMT'), (-_time.timezone,
                                                           _time.tzname[0])):
            if tzseconds < 0:
                sign = '-'
                seconds = -tzseconds
            else:
                sign = '+'
                seconds = tzseconds
            hours, minutes = divmod(seconds // 60, 60)
            dtstr = "{}{:02d}{:02d} {}".format(sign, hours, minutes, tzname)
            dt = strptime(dtstr, "%z %Z")
            self.assertEqual(dt.utcoffset(), timedelta(seconds=tzseconds))
            self.assertEqual(dt.tzname(), tzname)
        # Can produce inconsistent datetime
        dtstr, fmt = "+1234 UTC", "%z %Z"
        dt = strptime(dtstr, fmt)
        self.assertEqual(dt.utcoffset(), 12 * HOUR + 34 * MINUTE)
        self.assertEqual(dt.tzname(), 'UTC')
        # yet will roundtrip
        self.assertEqual(dt.strftime(fmt), dtstr)

        # Produce naive datetime if no %z is provided
        self.assertEqual(strptime("UTC", "%Z").tzinfo, None)

        with self.assertRaises(ValueError):
            strptime("-2400", "%z")
        with self.assertRaises(ValueError):
            strptime("-000", "%z")
Beispiel #6
0
    def test_subclass_now(self):
        # Test that alternate constructors call the constructor
        class DateTimeSubclass(self.theclass):
            def __new__(cls, *args, **kwargs):
                result = self.theclass.__new__(cls, *args, **kwargs)
                result.extra = 7

                return result

        test_cases = [
            ("now", "now", {}),
            ("utcnow", "utcnow", {}),
            ("now_utc", "now", {
                "tz": timezone.utc
            }),
            ("now_fixed", "now", {
                "tz": timezone(timedelta(hours=-5), "EST")
            }),
        ]

        for name, meth_name, kwargs in test_cases:
            with self.subTest(name):
                constr = getattr(DateTimeSubclass, meth_name)
                dt = constr(**kwargs)

                self.assertIsInstance(dt, DateTimeSubclass)
                self.assertEqual(dt.extra, 7)
Beispiel #7
0
    def test_astimezone(self):
        dt = self.theclass.now()
        f = FixedOffset(44, "0044")
        dt_utc = dt.replace(tzinfo=timezone(timedelta(hours=-4), "EDT"))
        self.assertEqual(dt.astimezone(), dt_utc)  # naive
        self.assertRaises(TypeError, dt.astimezone, f, f)  # too many args
        self.assertRaises(TypeError, dt.astimezone, dt)  # arg wrong type
        dt_f = dt.replace(tzinfo=f) + timedelta(hours=4, minutes=44)
        self.assertEqual(dt.astimezone(f), dt_f)  # naive
        self.assertEqual(dt.astimezone(tz=f), dt_f)  # naive

        class Bogus(tzinfo):
            def utcoffset(self, dt):
                return None

            def dst(self, dt):
                return timedelta(0)

        bog = Bogus()
        self.assertRaises(ValueError, dt.astimezone, bog)  # naive
        self.assertEqual(dt.replace(tzinfo=bog).astimezone(f), dt_f)

        class AlsoBogus(tzinfo):
            def utcoffset(self, dt):
                return timedelta(0)

            def dst(self, dt):
                return None

        alsobog = AlsoBogus()
        self.assertRaises(ValueError, dt.astimezone, alsobog)  # also naive

        class Broken(tzinfo):
            def utcoffset(self, dt):
                return 1

            def dst(self, dt):
                return 1

        broken = Broken()
        dt_broken = dt.replace(tzinfo=broken)
        with self.assertRaises(TypeError):
            dt_broken.astimezone()
Beispiel #8
0
    def test_isoformat_timezone(self):
        tzoffsets = [
            ("05:00", timedelta(hours=5)),
            ("02:00", timedelta(hours=2)),
            ("06:27", timedelta(hours=6, minutes=27)),
            ("12:32:30", timedelta(hours=12, minutes=32, seconds=30)),
            (
                "02:04:09.123456",
                timedelta(hours=2, minutes=4, seconds=9, microseconds=123456),
            ),
        ]

        tzinfos = [
            ("", None),
            ("+00:00", timezone.utc),
            ("+00:00", timezone(timedelta(0))),
        ]

        tzinfos += [(prefix + expected, timezone(sign * td))
                    for expected, td in tzoffsets
                    for prefix, sign in [("-", -1), ("+", 1)]]

        dt_base = self.theclass(2016, 4, 1, 12, 37, 9)
        exp_base = "2016-04-01T12:37:09"

        for exp_tz, tzi in tzinfos:
            dt = dt_base.replace(tzinfo=tzi)
            exp = exp_base + exp_tz
            with self.subTest(tzi=tzi):
                assert dt.isoformat() == exp
Beispiel #9
0
    def test_isoformat(self):
        t = self.theclass(1, 2, 3, 4, 5, 1, 123)
        self.assertEqual(t.isoformat(), "0001-02-03T04:05:01.000123")
        self.assertEqual(t.isoformat("T"), "0001-02-03T04:05:01.000123")
        self.assertEqual(t.isoformat(" "), "0001-02-03 04:05:01.000123")
        self.assertEqual(t.isoformat("\x00"), "0001-02-03\x0004:05:01.000123")
        # bpo-34482: Check that surrogates are handled properly.
        self.assertEqual(t.isoformat("\ud800"),
                         "0001-02-03\ud80004:05:01.000123")
        self.assertEqual(t.isoformat(timespec="hours"), "0001-02-03T04")
        self.assertEqual(t.isoformat(timespec="minutes"), "0001-02-03T04:05")
        self.assertEqual(t.isoformat(timespec="seconds"),
                         "0001-02-03T04:05:01")
        self.assertEqual(t.isoformat(timespec="milliseconds"),
                         "0001-02-03T04:05:01.000")
        self.assertEqual(t.isoformat(timespec="microseconds"),
                         "0001-02-03T04:05:01.000123")
        self.assertEqual(t.isoformat(timespec="auto"),
                         "0001-02-03T04:05:01.000123")
        self.assertEqual(t.isoformat(sep=" ", timespec="minutes"),
                         "0001-02-03 04:05")
        self.assertRaises(ValueError, t.isoformat, timespec="foo")
        # bpo-34482: Check that surrogates are handled properly.
        self.assertRaises(ValueError, t.isoformat, timespec="\ud800")
        # str is ISO format with the separator forced to a blank.
        self.assertEqual(str(t), "0001-02-03 04:05:01.000123")

        t = self.theclass(1, 2, 3, 4, 5, 1, 999500, tzinfo=timezone.utc)
        self.assertEqual(t.isoformat(timespec="milliseconds"),
                         "0001-02-03T04:05:01.999+00:00")

        t = self.theclass(1, 2, 3, 4, 5, 1, 999500)
        self.assertEqual(t.isoformat(timespec="milliseconds"),
                         "0001-02-03T04:05:01.999")

        t = self.theclass(1, 2, 3, 4, 5, 1)
        self.assertEqual(t.isoformat(timespec="auto"), "0001-02-03T04:05:01")
        self.assertEqual(t.isoformat(timespec="milliseconds"),
                         "0001-02-03T04:05:01.000")
        self.assertEqual(t.isoformat(timespec="microseconds"),
                         "0001-02-03T04:05:01.000000")

        t = self.theclass(2, 3, 2)
        self.assertEqual(t.isoformat(), "0002-03-02T00:00:00")
        self.assertEqual(t.isoformat("T"), "0002-03-02T00:00:00")
        self.assertEqual(t.isoformat(" "), "0002-03-02 00:00:00")
        # str is ISO format with the separator forced to a blank.
        self.assertEqual(str(t), "0002-03-02 00:00:00")
        # ISO format with timezone
        tz = FixedOffset(timedelta(seconds=16), "XXX")
        t = self.theclass(2, 3, 2, tzinfo=tz)
        self.assertEqual(t.isoformat(), "0002-03-02T00:00:00+00:00:16")
Beispiel #10
0
    def test_utcnow(self):
        import time

        # Call it a success if utcnow() and utcfromtimestamp() are within
        # a second of each other.
        tolerance = timedelta(seconds=1)
        for dummy in range(3):
            from_now = self.theclass.utcnow()
            from_timestamp = self.theclass.utcfromtimestamp(time.time())
            if abs(from_timestamp - from_now) <= tolerance:
                break
            # Else try again a few times.
        self.assertLessEqual(abs(from_timestamp - from_now), tolerance)
Beispiel #11
0
 def test_timestamp_aware(self):
     t = self.theclass(1970, 1, 1, tzinfo=timezone.utc)
     self.assertEqual(t.timestamp(), 0.0)
     t = self.theclass(1970, 1, 1, 1, 2, 3, 4, tzinfo=timezone.utc)
     self.assertEqual(t.timestamp(), 3600 + 2 * 60 + 3 + 4 * 1e-6)
     t = self.theclass(1970,
                       1,
                       1,
                       1,
                       2,
                       3,
                       4,
                       tzinfo=timezone(timedelta(hours=-5), "EST"))
     self.assertEqual(t.timestamp(), 18000 + 3600 + 2 * 60 + 3 + 4 * 1e-6)
Beispiel #12
0
    def test_tz_independent_comparing(self):
        dt1 = self.theclass(2002, 3, 1, 9, 0, 0)
        dt2 = self.theclass(2002, 3, 1, 10, 0, 0)
        dt3 = self.theclass(2002, 3, 1, 9, 0, 0)
        self.assertEqual(dt1, dt3)
        self.assertTrue(dt2 > dt3)

        # Make sure comparison doesn't forget microseconds, and isn't done
        # via comparing a float timestamp (an IEEE double doesn't have enough
        # precision to span microsecond resolution across years 1 through 9999,
        # so comparing via timestamp necessarily calls some distinct values
        # equal).
        dt1 = self.theclass(MAXYEAR, 12, 31, 23, 59, 59, 999998)
        us = timedelta(microseconds=1)
        dt2 = dt1 + us
        self.assertEqual(dt2 - dt1, us)
        self.assertTrue(dt1 < dt2)
Beispiel #13
0
    def test_fromisoformat_subclass(self):
        class DateTimeSubclass(self.theclass):
            pass

        dt = DateTimeSubclass(2014,
                              12,
                              14,
                              9,
                              30,
                              45,
                              457390,
                              tzinfo=timezone(timedelta(hours=10, minutes=45)))

        dt_rt = DateTimeSubclass.fromisoformat(dt.isoformat())

        self.assertEqual(dt, dt_rt)
        self.assertIsInstance(dt_rt, DateTimeSubclass)
Beispiel #14
0
    def test_more_strftime(self):
        # This tests fields beyond those tested by the TestDate.test_strftime.
        t = self.theclass(2004, 12, 31, 6, 22, 33, 47)
        self.assertEqual(t.strftime("%m %d %y %f %S %M %H %j"),
                         "12 31 04 000047 33 22 06 366")
        for (s, us), z in [
            ((33, 123), "33.000123"),
            ((33, 0), "33"),
        ]:
            tz = timezone(-timedelta(hours=2, seconds=s, microseconds=us))
            t = t.replace(tzinfo=tz)
            self.assertEqual(t.strftime("%z"), "-0200" + z)

        # bpo-34482: Check that surrogates don't cause a crash.
        try:
            t.strftime("%y\ud800%m %H\ud800%M")
        except UnicodeEncodeError:
            pass
def format_date(iso_formatted_date):
    if iso_formatted_date is None:
        return "When: Unavailable"
    date = datetime.fromisoformat(iso_formatted_date[:-1])
    date += timedelta(hours=TIME_ZONE_OFFSET)

    if USE_24HR_TIME:
        timestring = "%d:%02d %s" % (date.hour, date.minute, TIME_ZONE_NAME)
    elif date.hour > 12:
        timestring = "%d:%02d pm %s" % (
            abs((date.hour - 12) % 12),
            date.minute,
            TIME_ZONE_NAME,
        )
    else:
        timestring = "%d:%02d am %s" % (date.hour, date.minute, TIME_ZONE_NAME)

    return "%s %d, %s" % (months[date.month - 1], date.day, timestring)
def on_iso(client, feed_id, payload):
    timezone = adafruit_datetime.timezone.utc
    timezone._offset = adafruit_datetime.timedelta(seconds=UTC_OFFSET * 3600)
    datetime = adafruit_datetime.datetime.fromisoformat(
        payload[:-1]).replace(tzinfo=timezone)
    local_datetime = datetime.tzinfo.fromutc(datetime)
    print(local_datetime)
    dt_hour = local_datetime.hour
    dt_minute = local_datetime.minute
    if not local_datetime.second % 10:
        theta = (dt_hour / 6 + dt_minute / 360) - 0.5
        y_1 = int((72 * math.sin(math.pi * theta)) + 128)
        x_1 = int((72 * math.cos(math.pi * theta)) + 114)
        new_hour = Line(114, 128, x_1, y_1, 0xFFFFFF)
        splash[-3] = new_hour

        theta = (dt_minute / 30) - 0.5
        y_1 = int((96 * math.sin(math.pi * theta)) + 128)
        x_1 = int((96 * math.cos(math.pi * theta)) + 114)
        dt_minute = Line(114, 128, x_1, y_1, 0xFFFFFF)
        splash[-2] = dt_minute

    theta = (local_datetime.second / 30) - 0.5
    y_1 = int((96 * math.sin(math.pi * theta)) + 128)
    x_1 = int((96 * math.cos(math.pi * theta)) + 114)
    new_second = Line(114, 128, x_1, y_1, 0x808080)
    splash[-1] = new_second

    day = days[local_datetime.weekday()]
    alarm_hour, alarm_minute = TIMES[day].split(":")
    if dt_hour == int(alarm_hour):
        if (dt_minute == int(alarm_minute) and ENABLED[day] and not ALARM
                and WAIT < time.monotonic()):
            mqtt_client.publish(
                f"{secrets['aio_username']}/feeds/alarm-clock.alarm", "True")
            get("alarm-clock.alarm")
    gc.collect()
Beispiel #17
0
    def test_fromisoformat_timezone(self):
        base_dt = self.theclass(2014, 12, 30, 12, 30, 45, 217456)

        tzoffsets = [
            timedelta(hours=5),
            timedelta(hours=2),
            timedelta(hours=6, minutes=27),
            timedelta(hours=12, minutes=32, seconds=30),
            timedelta(hours=2, minutes=4, seconds=9, microseconds=123456),
        ]

        tzoffsets += [-1 * td for td in tzoffsets]

        tzinfos = [None, timezone.utc, timezone(timedelta(hours=0))]

        tzinfos += [timezone(td) for td in tzoffsets]

        for tzi in tzinfos:
            dt = base_dt.replace(tzinfo=tzi)
            dtstr = dt.isoformat()

            with self.subTest(tstr=dtstr):
                dt_rt = self.theclass.fromisoformat(dtstr)
                assert dt == dt_rt, dt_rt
Beispiel #18
0
 def utcoffset(self, dt):
     return timedelta(0)
Beispiel #19
0
 def dst(self, dt):
     return timedelta(0)
Beispiel #20
0
    def _schedule_next_run(self) -> None:
        """
        Compute the instant when this job should run next.
        """
        if self.unit not in ("seconds", "minutes", "hours", "days", "weeks"):
            raise ScheduleValueError(
                "Invalid unit (valid units are `seconds`, `minutes`, `hours`, "
                "`days`, and `weeks`)")

        if self.latest is not None:
            if not self.latest >= self.interval:
                raise ScheduleError("`latest` is greater than `interval`")
            interval = random.randint(self.interval, self.latest)
        else:
            interval = self.interval

        self.period = datetime.timedelta(**{self.unit: interval})
        self.next_run = datetime.datetime.now() + self.period
        if self.start_day is not None:
            if self.unit != "weeks":
                raise ScheduleValueError("`unit` should be 'weeks'")
            weekdays = (
                "monday",
                "tuesday",
                "wednesday",
                "thursday",
                "friday",
                "saturday",
                "sunday",
            )
            if self.start_day not in weekdays:
                raise ScheduleValueError(
                    "Invalid start day (valid start days are {})".format(
                        weekdays))
            weekday = weekdays.index(self.start_day)
            days_ahead = weekday - self.next_run.weekday()
            if days_ahead <= 0:  # Target day already happened this week
                days_ahead += 7
            self.next_run += datetime.timedelta(days_ahead) - self.period
        if self.at_time is not None:
            if self.unit not in ("days", "hours",
                                 "minutes") and self.start_day is None:
                raise ScheduleValueError(
                    "Invalid unit without specifying start day")
            kwargs = {"second": self.at_time.second, "microsecond": 0}
            if self.unit == "days" or self.start_day is not None:
                kwargs["hour"] = self.at_time.hour
            if self.unit in ["days", "hours"] or self.start_day is not None:
                kwargs["minute"] = self.at_time.minute
            self.next_run = self.next_run.replace(**kwargs)  # type: ignore
            # Make sure we run at the specified time *today* (or *this hour*)
            # as well. This accounts for when a job takes so long it finished
            # in the next period.
            if not self.last_run or (self.next_run -
                                     self.last_run) > self.period:
                now = datetime.datetime.now()
                if (self.unit == "days" and self.at_time > now.time()
                        and self.interval == 1):
                    self.next_run = self.next_run - datetime.timedelta(days=1)
                elif self.unit == "hours" and (
                        self.at_time.minute > now.minute or
                    (self.at_time.minute == now.minute
                     and self.at_time.second > now.second)):
                    self.next_run = self.next_run - datetime.timedelta(hours=1)
                elif self.unit == "minutes" and self.at_time.second > now.second:
                    self.next_run = self.next_run - datetime.timedelta(
                        minutes=1)
        if self.start_day is not None and self.at_time is not None:
            # Let's see if we will still make that time we specified today
            if (self.next_run - datetime.datetime.now()).days >= 7:
                self.next_run -= self.period
# SPDX-FileCopyrightText: 2001-2021 Python Software Foundation.All rights reserved.
# SPDX-FileCopyrightText: 2000 BeOpen.com. All rights reserved.
# SPDX-FileCopyrightText: 1995-2001 Corporation for National Research Initiatives.
#                         All rights reserved.
# SPDX-FileCopyrightText: 1995-2001 Corporation for National Research Initiatives.
#                         All rights reserved.
# SPDX-FileCopyrightText: 1991-1995 Stichting Mathematisch Centrum. All rights reserved.
# SPDX-FileCopyrightText: 2021 Brent Rubell for Adafruit Industries
# SPDX-License-Identifier: Python-2.0

# Example of working with a `timedelta` object
# from https://docs.python.org/3/library/datetime.html#examples-of-usage-timedelta
from adafruit_datetime import timedelta

# Example of normalization
year = timedelta(days=365)
another_year = timedelta(weeks=40, days=84, hours=23, minutes=50, seconds=600)
print("Total seconds in the year: ", year.total_seconds())

# Example of timedelta arithmetic
year = timedelta(days=365)
ten_years = 10 * year
print("Days in ten years:", ten_years)

nine_years = ten_years - year
print("Days in nine years:", nine_years)

three_years = nine_years // 3
print("Days in three years:", three_years, three_years.days // 365)
Beispiel #22
0
    def test_computations(self):
        a = self.theclass(2002, 1, 31)
        b = self.theclass(1956, 1, 31)
        diff = a - b
        self.assertEqual(diff.days, 46 * 365 + len(range(1956, 2002, 4)))
        self.assertEqual(diff.seconds, 0)
        self.assertEqual(diff.microseconds, 0)
        a = self.theclass(2002, 3, 2, 17, 6)
        millisec = timedelta(0, 0, 1000)
        hour = timedelta(0, 3600)
        day = timedelta(1)
        week = timedelta(7)
        self.assertEqual(a + hour, self.theclass(2002, 3, 2, 18, 6))
        self.assertEqual(hour + a, self.theclass(2002, 3, 2, 18, 6))
        self.assertEqual(a + 10 * hour, self.theclass(2002, 3, 3, 3, 6))
        self.assertEqual(a - hour, self.theclass(2002, 3, 2, 16, 6))
        self.assertEqual(-hour + a, self.theclass(2002, 3, 2, 16, 6))
        self.assertEqual(a - hour, a + -hour)
        self.assertEqual(a - 20 * hour, self.theclass(2002, 3, 1, 21, 6))
        self.assertEqual(a + day, self.theclass(2002, 3, 3, 17, 6))
        self.assertEqual(a - day, self.theclass(2002, 3, 1, 17, 6))
        self.assertEqual(a + week, self.theclass(2002, 3, 9, 17, 6))
        self.assertEqual(a - week, self.theclass(2002, 2, 23, 17, 6))
        self.assertEqual(a + 52 * week, self.theclass(2003, 3, 1, 17, 6))
        self.assertEqual(a - 52 * week, self.theclass(2001, 3, 3, 17, 6))
        self.assertEqual((a + week) - a, week)
        self.assertEqual((a + day) - a, day)
        self.assertEqual((a + hour) - a, hour)
        self.assertEqual((a + millisec) - a, millisec)
        self.assertEqual((a - week) - a, -week)
        self.assertEqual((a - day) - a, -day)
        self.assertEqual((a - hour) - a, -hour)
        self.assertEqual((a - millisec) - a, -millisec)
        self.assertEqual(a - (a + week), -week)
        self.assertEqual(a - (a + day), -day)
        self.assertEqual(a - (a + hour), -hour)
        self.assertEqual(a - (a + millisec), -millisec)
        self.assertEqual(a - (a - week), week)
        self.assertEqual(a - (a - day), day)
        self.assertEqual(a - (a - hour), hour)
        self.assertEqual(a - (a - millisec), millisec)
        self.assertEqual(
            a + (week + day + hour + millisec),
            self.theclass(2002, 3, 10, 18, 6, 0, 1000),
        )
        self.assertEqual(a + (week + day + hour + millisec),
                         (((a + week) + day) + hour) + millisec)
        self.assertEqual(
            a - (week + day + hour + millisec),
            self.theclass(2002, 2, 22, 16, 5, 59, 999000),
        )
        self.assertEqual(a - (week + day + hour + millisec),
                         (((a - week) - day) - hour) - millisec)
        # Add/sub ints or floats should be illegal
        for i in 1, 1.0:
            self.assertRaises(TypeError, lambda: a + i)
            self.assertRaises(TypeError, lambda: a - i)
            self.assertRaises(TypeError, lambda: i + a)
            self.assertRaises(TypeError, lambda: i - a)

        # delta - datetime is senseless.
        self.assertRaises(TypeError, lambda: day - a)
        # mixing datetime and (delta or datetime) via * or // is senseless
        self.assertRaises(TypeError, lambda: day * a)
        self.assertRaises(TypeError, lambda: a * day)
        self.assertRaises(TypeError, lambda: day // a)
        self.assertRaises(TypeError, lambda: a // day)
        self.assertRaises(TypeError, lambda: a * a)
        self.assertRaises(TypeError, lambda: a // a)
        # datetime + datetime is senseless
        self.assertRaises(TypeError, lambda: a + a)