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