codon/test/stdlib/datetime_test.codon

1995 lines
74 KiB
Python

from datetime import *
from unittest import TestCase
from operator import lt, le, gt, ge, eq, ne, truediv, floordiv, mod
class TestTimeDelta(Static[TestCase]):
def test_constructor(self):
eq = self.assertEqual
td = timedelta
# Check keyword args to constructor
eq(
td(),
td(
weeks=0,
days=0,
hours=0,
minutes=0,
seconds=0,
milliseconds=0,
microseconds=0,
),
)
eq(td(1), td(days=1))
eq(td(0, 1), td(seconds=1))
eq(td(0, 0, 1), td(microseconds=1))
eq(td(weeks=1), td(days=7))
eq(td(days=1), td(hours=24))
eq(td(hours=1), td(minutes=60))
eq(td(minutes=1), td(seconds=60))
eq(td(seconds=1), td(milliseconds=1000))
eq(td(milliseconds=1), td(microseconds=1000))
# Check float args to constructor
eq(td(weeks=1.0 / 7), td(days=1))
eq(td(days=1.0 / 24), td(hours=1))
eq(td(hours=1.0 / 60), td(minutes=1))
eq(td(minutes=1.0 / 60), td(seconds=1))
eq(td(seconds=0.001), td(milliseconds=1))
eq(td(milliseconds=0.001), td(microseconds=1))
def test_computations(self):
eq = self.assertEqual
td = timedelta
a = td(7) # One week
b = td(0, 60) # One minute
c = td(0, 0, 1000) # One millisecond
eq(a + b + c, td(7, 60, 1000))
eq(a - b, td(6, 24 * 3600 - 60))
# eq(b.__rsub__(a), td(6, 24*3600 - 60))
eq(-a, td(-7))
eq(+a, td(7))
eq(-b, td(-1, 24 * 3600 - 60))
eq(-c, td(-1, 24 * 3600 - 1, 999000))
eq(abs(a), a)
eq(abs(-a), a)
eq(td(6, 24 * 3600), a)
eq(td(0, 0, 60 * 1000000), b)
eq(a * 10, td(70))
eq(a * 10, 10 * a)
eq(a * 10, 10 * a)
eq(b * 10, td(0, 600))
eq(10 * b, td(0, 600))
eq(b * 10, td(0, 600))
eq(c * 10, td(0, 0, 10000))
eq(10 * c, td(0, 0, 10000))
eq(c * 10, td(0, 0, 10000))
eq(a * -1, -a)
eq(b * -2, -b - b)
eq(c * -2, -c + -c)
eq(b * (60 * 24), (b * 60) * 24)
eq(b * (60 * 24), (60 * b) * 24)
eq(c * 1000, td(0, 1))
eq(1000 * c, td(0, 1))
eq(a // 7, td(1))
eq(b // 10, td(0, 6))
eq(c // 1000, td(0, 0, 1))
eq(a // 10, td(0, 7 * 24 * 360))
eq(a // 3600000, td(0, 0, 7 * 24 * 1000))
eq(a / 0.5, td(14))
eq(b / 0.5, td(0, 120))
eq(a / 7, td(1))
eq(b / 10, td(0, 6))
eq(c / 1000, td(0, 0, 1))
eq(a / 10, td(0, 7 * 24 * 360))
eq(a / 3600000, td(0, 0, 7 * 24 * 1000))
# Multiplication by float
us = td(microseconds=1)
eq((3 * us) * 0.5, 2 * us)
eq((5 * us) * 0.5, 2 * us)
eq(0.5 * (3 * us), 2 * us)
eq(0.5 * (5 * us), 2 * us)
eq((-3 * us) * 0.5, -2 * us)
eq((-5 * us) * 0.5, -2 * us)
# TODO: check Python's Issue #23521 and possibly
# incorporate the same fix here. For now a couple
# tests are disabled.
# Issue #23521
eq(td(seconds=1) * 0.123456, td(microseconds=123456))
# eq(td(seconds=1) * 0.6112295, td(microseconds=611229))
# Division by int and float
eq((3 * us) / 2, 2 * us)
eq((5 * us) / 2, 2 * us)
eq((-3 * us) / 2.0, -2 * us)
eq((-5 * us) / 2.0, -2 * us)
eq((3 * us) / -2, -2 * us)
eq((5 * us) / -2, -2 * us)
eq((3 * us) / -2.0, -2 * us)
eq((5 * us) / -2.0, -2 * us)
for i in range(-10, 10):
eq((i * us / 3) // us, round(i / 3))
for i in range(-10, 10):
eq((i * us / -3) // us, round(i / -3))
# Issue #23521
# eq(td(seconds=1) / (1 / 0.6112295), td(microseconds=611229))
# Issue #11576
eq(td(999999999, 86399, 999999) - td(999999999, 86399, 999998), td(0, 0, 1))
eq(td(999999999, 1, 1) - td(999999999, 1, 0), td(0, 0, 1))
"""
def test_disallowed_special(self):
a = timedelta(42)
NAN = 0. / 0.
self.assertRaises(ValueError, a.__mul__, NAN)
self.assertRaises(ValueError, a.__truediv__, NAN)
"""
def test_basic_attributes(self):
days, seconds, us = 1, 7, 31
td = timedelta(days, seconds, us)
self.assertEqual(td.days, days)
self.assertEqual(td.seconds, seconds)
self.assertEqual(td.microseconds, us)
def test_total_seconds(self):
td = timedelta(days=365)
self.assertEqual(td.total_seconds(), 31536000.0)
for total_seconds in [123456.789012, -123456.789012, 0.123456, 0, 1e6]:
td = timedelta(seconds=total_seconds)
self.assertEqual(td.total_seconds(), total_seconds)
# Issue8644: Test that td.total_seconds() has the same
# accuracy as td / timedelta(seconds=1).
for ms in [-1, -2, -123]:
td = timedelta(microseconds=ms)
self.assertEqual(td.total_seconds(), td / timedelta(seconds=1))
def test_carries(self):
t1 = timedelta(
days=100,
weeks=-7,
hours=-24 * (100 - 49),
minutes=-3,
seconds=12,
microseconds=(3 * 60 - 12) * 1e6 + 1,
)
t2 = timedelta(microseconds=1)
self.assertEqual(t1, t2)
def test_hash_equality(self):
t1 = timedelta(
days=100,
weeks=-7,
hours=-24 * (100 - 49),
minutes=-3,
seconds=12,
microseconds=(3 * 60 - 12) * 1000000,
)
t2 = timedelta()
self.assertEqual(hash(t1), hash(t2))
t1 += timedelta(weeks=7)
t2 += timedelta(days=7 * 7)
self.assertEqual(t1, t2)
self.assertEqual(hash(t1), hash(t2))
d = {t1: 1}
d[t2] = 2
self.assertEqual(len(d), 1)
self.assertEqual(d[t1], 2)
def test_compare(self):
t1 = timedelta(2, 3, 4)
t2 = timedelta(2, 3, 4)
self.assertEqual(t1, t2)
self.assertTrue(t1 <= t2)
self.assertTrue(t1 >= t2)
self.assertFalse(t1 != t2)
self.assertFalse(t1 < t2)
self.assertFalse(t1 > t2)
for args in (3, 3, 3), (2, 4, 4), (2, 3, 5):
t2 = timedelta(*args) # this is larger than t1
self.assertTrue(t1 < t2)
self.assertTrue(t2 > t1)
self.assertTrue(t1 <= t2)
self.assertTrue(t2 >= t1)
self.assertTrue(t1 != t2)
self.assertTrue(t2 != t1)
self.assertFalse(t1 == t2)
self.assertFalse(t2 == t1)
self.assertFalse(t1 > t2)
self.assertFalse(t2 < t1)
self.assertFalse(t1 >= t2)
self.assertFalse(t2 <= t1)
def test_str(self):
td = timedelta
eq = self.assertEqual
eq(str(td(1)), "1 day, 0:00:00")
eq(str(td(-1)), "-1 day, 0:00:00")
eq(str(td(2)), "2 days, 0:00:00")
eq(str(td(-2)), "-2 days, 0:00:00")
eq(str(td(hours=12, minutes=58, seconds=59)), "12:58:59")
eq(str(td(hours=2, minutes=3, seconds=4)), "2:03:04")
eq(str(td(weeks=-30, hours=23, minutes=12, seconds=34)), "-210 days, 23:12:34")
eq(str(td(milliseconds=1)), "0:00:00.001000")
eq(str(td(microseconds=3)), "0:00:00.000003")
# Codon's timedelta has a smaller range than Python's
# since it uses a pure microseconds representation, so
# below case is not supported.
"""
eq(str(td(days=999999999, hours=23, minutes=59, seconds=59,
microseconds=999999)),
"999999999 days, 23:59:59.999999")
"""
def test_repr(self):
td = timedelta
self.assertEqual(repr(td(1)), "timedelta(days=1)")
self.assertEqual(repr(td(10, 2)), "timedelta(days=10, seconds=2)")
self.assertEqual(
repr(td(-10, 2, 400000)),
"timedelta(days=-10, seconds=2, microseconds=400000)",
)
self.assertEqual(repr(td(seconds=60)), "timedelta(seconds=60)")
self.assertEqual(repr(td()), "timedelta(0)")
self.assertEqual(repr(td(microseconds=100)), "timedelta(microseconds=100)")
self.assertEqual(
repr(td(days=1, microseconds=100)), "timedelta(days=1, microseconds=100)"
)
self.assertEqual(
repr(td(seconds=1, microseconds=100)),
"timedelta(seconds=1, microseconds=100)",
)
def test_resolution_info(self):
self.assertTrue(timedelta.max > timedelta.min)
#self.assertEqual(timedelta.min, timedelta(-999999999))
#self.assertEqual(timedelta.max, timedelta(999999999, 24*3600-1, 1e6-1))
self.assertEqual(timedelta.resolution, timedelta(0, 0, 1))
"""
def test_overflow(self):
tiny = timedelta(microseconds=1) # timedelta.resolution
td = timedelta.min + tiny
td -= tiny # no problem
self.assertRaises(OverflowError, td.__sub__, tiny)
self.assertRaises(OverflowError, td.__add__, -tiny)
td = timedelta.max - tiny
td += tiny # no problem
self.assertRaises(OverflowError, td.__add__, tiny)
self.assertRaises(OverflowError, td.__sub__, -tiny)
self.assertRaises(OverflowError, lambda: -timedelta.max)
day = timedelta(1)
self.assertRaises(OverflowError, day.__mul__, 10**9)
self.assertRaises(OverflowError, day.__mul__, 1e9)
self.assertRaises(OverflowError, day.__truediv__, 1e-20)
self.assertRaises(OverflowError, day.__truediv__, 1e-10)
self.assertRaises(OverflowError, day.__truediv__, 9e-10)
def _test_overflow_special(self):
day = timedelta(1)
INF = 1. / 0.
self.assertRaises(OverflowError, day.__mul__, INF)
self.assertRaises(OverflowError, day.__mul__, -INF)
"""
def test_microsecond_rounding(self):
td = timedelta
eq = self.assertEqual
# Single-field rounding.
eq(td(milliseconds=0.4 / 1000), td(0)) # rounds to 0
eq(td(milliseconds=-0.4 / 1000), td(0)) # rounds to 0
eq(td(milliseconds=0.5 / 1000), td(microseconds=0))
eq(td(milliseconds=-0.5 / 1000), td(microseconds=-0))
eq(td(milliseconds=0.6 / 1000), td(microseconds=1))
eq(td(milliseconds=-0.6 / 1000), td(microseconds=-1))
eq(td(milliseconds=1.5 / 1000), td(microseconds=2))
eq(td(milliseconds=-1.5 / 1000), td(microseconds=-2))
eq(td(seconds=0.5 / 10 ** 6), td(microseconds=0))
eq(td(seconds=-0.5 / 10 ** 6), td(microseconds=-0))
eq(td(seconds=1 / 2 ** 7), td(microseconds=7812))
eq(td(seconds=-1 / 2 ** 7), td(microseconds=-7812))
# Rounding due to contributions from more than one field.
us_per_hour = 3600e6
us_per_day = us_per_hour * 24
eq(td(days=0.4 / us_per_day), td(0))
eq(td(hours=0.2 / us_per_hour), td(0))
eq(td(days=0.4 / us_per_day, hours=0.2 / us_per_hour), td(microseconds=1))
eq(td(days=-0.4 / us_per_day), td(0))
eq(td(hours=-0.2 / us_per_hour), td(0))
eq(td(days=-0.4 / us_per_day, hours=-0.2 / us_per_hour), td(microseconds=-1))
# Test for a patch in Issue 8860
eq(td(microseconds=0.5), 0.5 * td(microseconds=1.0))
resolution = td(microseconds=1) # td.resolution
eq(td(microseconds=0.5) // resolution, 0.5 * resolution // resolution)
def test_massive_normalization(self):
td = timedelta(microseconds=-1)
self.assertEqual(
(td.days, td.seconds, td.microseconds), (-1, 24 * 3600 - 1, 999999)
)
def test_bool(self):
self.assertTrue(timedelta(1))
self.assertTrue(timedelta(0, 1))
self.assertTrue(timedelta(0, 0, 1))
self.assertTrue(timedelta(microseconds=1))
self.assertFalse(timedelta(0))
def test_division(self):
t = timedelta(hours=1, minutes=24, seconds=19)
second = timedelta(seconds=1)
self.assertEqual(t / second, 5059.0)
self.assertEqual(t // second, 5059)
t = timedelta(minutes=2, seconds=30)
minute = timedelta(minutes=1)
self.assertEqual(t / minute, 2.5)
self.assertEqual(t // minute, 2)
zerotd = timedelta(0)
# self.assertRaises(ZeroDivisionError, truediv, t, zerotd)
# self.assertRaises(ZeroDivisionError, floordiv, t, zerotd)
def test_remainder(self):
t = timedelta(minutes=2, seconds=30)
minute = timedelta(minutes=1)
r = t % minute
self.assertEqual(r, timedelta(seconds=30))
t = timedelta(minutes=-2, seconds=30)
r = t % minute
self.assertEqual(r, timedelta(seconds=30))
zerotd = timedelta(0)
# self.assertRaises(ZeroDivisionError, mod, t, zerotd)
def test_divmod(self):
t = timedelta(minutes=2, seconds=30)
minute = timedelta(minutes=1)
q, r = divmod(t, minute)
self.assertEqual(q, 2)
self.assertEqual(r, timedelta(seconds=30))
t = timedelta(minutes=-2, seconds=30)
q, r = divmod(t, minute)
self.assertEqual(q, -2)
self.assertEqual(r, timedelta(seconds=30))
zerotd = timedelta(0)
# self.assertRaises(ZeroDivisionError, divmod, t, zerotd)
class TestDateOnly(Static[TestCase]):
def test_delta_non_days_ignored(self):
dt = date(2000, 1, 2)
delta = timedelta(days=1, hours=2, minutes=3, seconds=4, microseconds=5)
days = timedelta(delta.days)
self.assertEqual(days, timedelta(1))
dt2 = dt + delta
self.assertEqual(dt2, dt + days)
dt2 = delta + dt
self.assertEqual(dt2, dt + days)
dt2 = dt - delta
self.assertEqual(dt2, dt - days)
delta = -delta
days = timedelta(delta.days)
self.assertEqual(days, timedelta(-2))
dt2 = dt + delta
self.assertEqual(dt2, dt + days)
dt2 = delta + dt
self.assertEqual(dt2, dt + days)
dt2 = dt - delta
self.assertEqual(dt2, dt - days)
class TestDate(Static[TestCase]):
theclass: type
def test_basic_attributes(self):
dt = self.theclass(2002, 3, 1)
self.assertEqual(dt.year, 2002)
self.assertEqual(dt.month, 3)
self.assertEqual(dt.day, 1)
def test_ordinal_conversions(self):
# Check some fixed values.
for y, m, d, n in [
(1, 1, 1, 1), # calendar origin
(1, 12, 31, 365),
(2, 1, 1, 366),
# first example from "Calendrical Calculations"
(1945, 11, 12, 710347),
]:
dt = self.theclass(y, m, d)
self.assertEqual(n, dt.toordinal())
fromord = self.theclass.fromordinal(n)
self.assertEqual(dt, fromord)
if hasattr(fromord, "hour"):
# if we're checking something fancier than a date, verify
# the extra fields have been zeroed out
self.assertEqual(fromord.hour, 0)
self.assertEqual(fromord.minute, 0)
self.assertEqual(fromord.second, 0)
self.assertEqual(fromord.microsecond, 0)
# Check first and last days of year spottily across the whole
# range of years supported.
for year in range(MINYEAR, MAXYEAR + 1, 7):
# Verify (year, 1, 1) -> ordinal -> y, m, d is identity.
d = self.theclass(year, 1, 1)
n = d.toordinal()
d2 = self.theclass.fromordinal(n)
self.assertEqual(d, d2)
# Verify that moving back a day gets to the end of year-1.
if year > 1:
d = self.theclass.fromordinal(n - 1)
d2 = self.theclass(year - 1, 12, 31)
self.assertEqual(d, d2)
self.assertEqual(d2.toordinal(), n - 1)
# Test every day in a leap-year and a non-leap year.
dim = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
for year, isleap in (2000, True), (2002, False):
n = self.theclass(year, 1, 1).toordinal()
for month, maxday in zip(range(1, 13), dim):
if month == 2 and isleap:
maxday += 1
for day in range(1, maxday + 1):
d = self.theclass(year, month, day)
self.assertEqual(d.toordinal(), n)
self.assertEqual(d, self.theclass.fromordinal(n))
n += 1
"""
def test_extreme_ordinals(self):
a = self.theclass.min
a = self.theclass(a.year, a.month, a.day) # get rid of time parts
aord = a.toordinal()
b = a.fromordinal(aord)
self.assertEqual(a, b)
self.assertRaises(ValueError, lambda: a.fromordinal(aord - 1))
b = a + timedelta(days=1)
self.assertEqual(b.toordinal(), aord + 1)
self.assertEqual(b, self.theclass.fromordinal(aord + 1))
a = self.theclass.max
a = self.theclass(a.year, a.month, a.day) # get rid of time parts
aord = a.toordinal()
b = a.fromordinal(aord)
self.assertEqual(a, b)
self.assertRaises(ValueError, lambda: a.fromordinal(aord + 1))
b = a - timedelta(days=1)
self.assertEqual(b.toordinal(), aord - 1)
self.assertEqual(b, self.theclass.fromordinal(aord - 1))
"""
def test_bad_constructor_arguments(self):
# bad years
self.theclass(MINYEAR, 1, 1) # no exception
self.theclass(MAXYEAR, 1, 1) # no exception
def make(theclass, a, b, c):
return self.theclass(a, b, c)
self.assertRaises(ValueError, make(self.theclass, ...), MINYEAR - 1, 1, 1)
self.assertRaises(ValueError, make(self.theclass, ...), MAXYEAR + 1, 1, 1)
# bad months
self.theclass(2000, 1, 1) # no exception
self.theclass(2000, 12, 1) # no exception
self.assertRaises(ValueError, make(self.theclass, ...), 2000, 0, 1)
self.assertRaises(ValueError, make(self.theclass, ...), 2000, 13, 1)
# bad days
self.theclass(2000, 2, 29) # no exception
self.theclass(2004, 2, 29) # no exception
self.theclass(2400, 2, 29) # no exception
self.assertRaises(ValueError, make(self.theclass, ...), 2000, 2, 30)
self.assertRaises(ValueError, make(self.theclass, ...), 2001, 2, 29)
self.assertRaises(ValueError, make(self.theclass, ...), 2100, 2, 29)
self.assertRaises(ValueError, make(self.theclass, ...), 1900, 2, 29)
self.assertRaises(ValueError, make(self.theclass, ...), 2000, 1, 0)
self.assertRaises(ValueError, make(self.theclass, ...), 2000, 1, 32)
def test_hash_equality(self):
d = self.theclass(2000, 12, 31)
# same thing
e = self.theclass(2000, 12, 31)
self.assertEqual(d, e)
self.assertEqual(hash(d), hash(e))
dic = {d: 1}
dic[e] = 2
self.assertEqual(len(dic), 1)
self.assertEqual(dic[d], 2)
self.assertEqual(dic[e], 2)
d = self.theclass(2001, 1, 1)
# same thing
e = self.theclass(2001, 1, 1)
self.assertEqual(d, e)
self.assertEqual(hash(d), hash(e))
dic = {d: 1}
dic[e] = 2
self.assertEqual(len(dic), 1)
self.assertEqual(dic[d], 2)
self.assertEqual(dic[e], 2)
def test_computations(self):
a = self.theclass(2002, 1, 31)
b = self.theclass(1956, 1, 31)
c = self.theclass(2001, 2, 1)
diff = a - b
self.assertEqual(diff.days, 46 * 365 + len(range(1956, 2002, 4)))
self.assertEqual(diff.seconds, 0)
self.assertEqual(diff.microseconds, 0)
day = timedelta(1)
week = timedelta(7)
a = self.theclass(2002, 3, 2)
self.assertEqual(a + day, self.theclass(2002, 3, 3))
self.assertEqual(day + a, self.theclass(2002, 3, 3))
self.assertEqual(a - day, self.theclass(2002, 3, 1))
self.assertEqual(-day + a, self.theclass(2002, 3, 1))
self.assertEqual(a + week, self.theclass(2002, 3, 9))
self.assertEqual(a - week, self.theclass(2002, 2, 23))
self.assertEqual(a + 52 * week, self.theclass(2003, 3, 1))
self.assertEqual(a - 52 * week, self.theclass(2001, 3, 3))
self.assertEqual((a + week) - a, week)
self.assertEqual((a + day) - a, day)
self.assertEqual((a - week) - a, -week)
self.assertEqual((a - day) - a, -day)
self.assertEqual(a - (a + week), -week)
self.assertEqual(a - (a + day), -day)
self.assertEqual(a - (a - week), week)
self.assertEqual(a - (a - day), day)
self.assertEqual(c - (c - day), day)
"""
# 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 - date is senseless.
self.assertRaises(TypeError, lambda: day - a)
# mixing date and (delta or date) 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)
# date + date is senseless
self.assertRaises(TypeError, lambda: a + a)
"""
"""
def test_overflow(self):
tiny = self.theclass.resolution
for delta in [tiny, timedelta(1), timedelta(2)]:
dt = self.theclass.min + delta
dt -= delta # no problem
self.assertRaises(OverflowError, dt.__sub__, delta)
self.assertRaises(OverflowError, dt.__add__, -delta)
dt = self.theclass.max - delta
dt += delta # no problem
self.assertRaises(OverflowError, dt.__add__, delta)
self.assertRaises(OverflowError, dt.__sub__, -delta)
"""
def test_fromtimestamp(self):
import time
# Try an arbitrary fixed value.
year, month, day = 1999, 9, 19
ts = time.mktime((year, month, day, 0, 0, 0, 0, 0, -1))
d = self.theclass.fromtimestamp(ts)
self.assertEqual(d.year, year)
self.assertEqual(d.month, month)
self.assertEqual(d.day, day)
def test_today(self):
import time
# We claim that today() is like fromtimestamp(time.time()), so
# prove it.
today = self.theclass.today()
todayagain = today
for dummy in range(3):
today = self.theclass.today()
ts = time.time()
todayagain = self.theclass.fromtimestamp(ts)
if today == todayagain:
break
# There are several legit reasons that could fail:
# 1. It recently became midnight, between the today() and the
# time() calls.
# 2. The platform time() has such fine resolution that we'll
# never get the same value twice.
# 3. The platform time() has poor resolution, and we just
# happened to call today() right before a resolution quantum
# boundary.
# 4. The system clock got fiddled between calls.
# In any case, wait a little while and try again.
time.sleep(0.1)
# It worked or it didn't. If it didn't, assume it's reason #2, and
# let the test pass if they're within half a second of each other.
if today != todayagain:
self.assertAlmostEqual(todayagain, today, delta=timedelta(seconds=0.5))
def test_weekday(self):
for i in range(7):
# March 4, 2002 is a Monday
self.assertEqual(self.theclass(2002, 3, 4 + i).weekday(), i)
self.assertEqual(self.theclass(2002, 3, 4 + i).isoweekday(), i + 1)
# January 2, 1956 is a Monday
self.assertEqual(self.theclass(1956, 1, 2 + i).weekday(), i)
self.assertEqual(self.theclass(1956, 1, 2 + i).isoweekday(), i + 1)
def test_isocalendar(self):
# Check examples from
# http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm
week_mondays = [
((2003, 12, 22), (2003, 52, 1)),
((2003, 12, 29), (2004, 1, 1)),
((2004, 1, 5), (2004, 2, 1)),
((2009, 12, 21), (2009, 52, 1)),
((2009, 12, 28), (2009, 53, 1)),
((2010, 1, 4), (2010, 1, 1)),
]
test_cases = []
for cal_date, iso_date in week_mondays:
base_date = self.theclass(*cal_date)
# Adds one test case for every day of the specified weeks
for i in range(7):
new_date = base_date + timedelta(i)
new_iso = iso_date[0:2] + (iso_date[2] + i,)
test_cases.append((new_date, new_iso))
for d, exp_iso in test_cases:
self.assertEqual(d.isocalendar(), exp_iso)
# Check that the tuple contents are accessible by field name
t = d.isocalendar()
self.assertEqual((t.year, t.week, t.weekday), exp_iso)
def test_iso_long_years(self):
# Calculate long ISO years and compare to table from
# http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm
ISO_LONG_YEARS_TABLE = """
4 32 60 88
9 37 65 93
15 43 71 99
20 48 76
26 54 82
105 133 161 189
111 139 167 195
116 144 172
122 150 178
128 156 184
201 229 257 285
207 235 263 291
212 240 268 296
218 246 274
224 252 280
303 331 359 387
308 336 364 392
314 342 370 398
320 348 376
325 353 381
"""
iso_long_years = sorted(map(int, ISO_LONG_YEARS_TABLE.split()))
L = []
for i in range(400):
d = self.theclass(2000 + i, 12, 31).isocalendar()
d1 = self.theclass(1600 + i, 12, 31).isocalendar()
self.assertEqual((d.week, d.weekday), (d1.week, d1.weekday))
if d.week == 53:
L.append(i)
self.assertEqual(L, iso_long_years)
def test_isoformat(self):
t = self.theclass(2, 3, 2)
self.assertEqual(t.isoformat(), "0002-03-02")
def test_ctime(self):
t = self.theclass(2002, 3, 2)
self.assertEqual(t.ctime(), "Sat Mar 2 00:00:00 2002")
def test_resolution_info(self):
self.assertTrue(self.theclass.max > self.theclass.min)
"""
def test_extreme_timedelta(self):
big = self.theclass.max - self.theclass.min
# 3652058 days, 23 hours, 59 minutes, 59 seconds, 999999 microseconds
n = (big.days*24*3600 + big.seconds)*1000000 + big.microseconds
# n == 315537897599999999 ~= 2**58.13
justasbig = timedelta(0, 0, n)
self.assertEqual(big, justasbig)
self.assertEqual(self.theclass.min + big, self.theclass.max)
self.assertEqual(self.theclass.max - big, self.theclass.min)
"""
def test_timetuple(self):
from time import struct_time
for i in range(7):
# January 2, 1956 is a Monday (0)
d = self.theclass(1956, 1, 2 + i)
t = d.timetuple()
self.assertEqual(t, struct_time(1956, 1, 2 + i, 0, 0, 0, i, 2 + i, -1))
# February 1, 1956 is a Wednesday (2)
d = self.theclass(1956, 2, 1 + i)
t = d.timetuple()
self.assertEqual(
t, struct_time(1956, 2, 1 + i, 0, 0, 0, (2 + i) % 7, 32 + i, -1)
)
# March 1, 1956 is a Thursday (3), and is the 31+29+1 = 61st day
# of the year.
d = self.theclass(1956, 3, 1 + i)
t = d.timetuple()
self.assertEqual(
t, struct_time(1956, 3, 1 + i, 0, 0, 0, (3 + i) % 7, 61 + i, -1)
)
self.assertEqual(t.tm_year, 1956)
self.assertEqual(t.tm_mon, 3)
self.assertEqual(t.tm_mday, 1 + i)
self.assertEqual(t.tm_hour, 0)
self.assertEqual(t.tm_min, 0)
self.assertEqual(t.tm_sec, 0)
self.assertEqual(t.tm_wday, (3 + i) % 7)
self.assertEqual(t.tm_yday, 61 + i)
self.assertEqual(t.tm_isdst, -1)
def test_compare(self):
t1 = self.theclass(2, 3, 4)
t2 = self.theclass(2, 3, 4)
self.assertEqual(t1, t2)
self.assertTrue(t1 <= t2)
self.assertTrue(t1 >= t2)
self.assertFalse(t1 != t2)
self.assertFalse(t1 < t2)
self.assertFalse(t1 > t2)
for args in (3, 3, 3), (2, 4, 4), (2, 3, 5):
t2 = self.theclass(*args) # this is larger than t1
self.assertTrue(t1 < t2)
self.assertTrue(t2 > t1)
self.assertTrue(t1 <= t2)
self.assertTrue(t2 >= t1)
self.assertTrue(t1 != t2)
self.assertTrue(t2 != t1)
self.assertFalse(t1 == t2)
self.assertFalse(t2 == t1)
self.assertFalse(t1 > t2)
self.assertFalse(t2 < t1)
self.assertFalse(t1 >= t2)
self.assertFalse(t2 <= t1)
"""
for badarg in OTHERSTUFF:
self.assertEqual(t1 == badarg, False)
self.assertEqual(t1 != badarg, True)
self.assertEqual(badarg == t1, False)
self.assertEqual(badarg != t1, True)
self.assertRaises(TypeError, lambda: t1 < badarg)
self.assertRaises(TypeError, lambda: t1 > badarg)
self.assertRaises(TypeError, lambda: t1 >= badarg)
self.assertRaises(TypeError, lambda: badarg <= t1)
self.assertRaises(TypeError, lambda: badarg < t1)
self.assertRaises(TypeError, lambda: badarg > t1)
self.assertRaises(TypeError, lambda: badarg >= t1)
"""
def test_bool(self):
# All dates are considered true.
# self.assertTrue(self.theclass.min)
# self.assertTrue(self.theclass.max)
self.assertTrue(self.theclass(1, 1, 1))
def test_replace(self):
cls = self.theclass
args = (1, 2, 3)
base = cls(*args)
self.assertEqual(base, base.replace())
self.assertEqual(base.replace(year=2), cls(2, 2, 3))
self.assertEqual(base.replace(month=3), cls(1, 3, 3))
self.assertEqual(base.replace(day=4), cls(1, 2, 4))
# Out of bounds.
base = cls(2000, 2, 29)
self.assertRaises(ValueError, base.replace, year=2001)
def test_fromisoformat(self):
# Test that isoformat() is reversible
base_dates = [
(1, 1, 1),
(1000, 2, 14),
(1900, 1, 1),
(2000, 2, 29),
(2004, 11, 12),
(2004, 4, 3),
(2017, 5, 30),
]
for dt_tuple in base_dates:
dt = self.theclass(*dt_tuple)
dt_str = dt.isoformat()
dt_rt = self.theclass.fromisoformat(dt.isoformat())
self.assertEqual(dt, dt_rt)
def test_fromisoformat_fails(self):
# Test that fromisoformat() fails on invalid values
bad_strs = [
"", # Empty string
"\ud800", # bpo-34454: Surrogate code point
"009-03-04", # Not 10 characters
"123456789", # Not a date
"200a-12-04", # Invalid character in year
"2009-1a-04", # Invalid character in month
"2009-12-0a", # Invalid character in day
"2009-01-32", # Invalid day
"2009-02-29", # Invalid leap day
"20090228", # Valid ISO8601 output not from isoformat()
"2009\ud80002\ud80028", # Separators are surrogate codepoints
]
for bad_str in bad_strs:
self.assertRaises(ValueError, self.theclass.fromisoformat, bad_str)
def test_fromisocalendar(self):
# For each test case, assert that fromisocalendar is the
# inverse of the isocalendar function
dates = [
(2016, 4, 3),
(2005, 1, 2), # (2004, 53, 7)
(2008, 12, 30), # (2009, 1, 2)
(2010, 1, 2), # (2009, 53, 6)
(2009, 12, 31), # (2009, 53, 4)
(1900, 1, 1), # Unusual non-leap year (year % 100 == 0)
(1900, 12, 31),
(2000, 1, 1), # Unusual leap year (year % 400 == 0)
(2000, 12, 31),
(2004, 1, 1), # Leap year
(2004, 12, 31),
(1, 1, 1),
(9999, 12, 31),
(MINYEAR, 1, 1),
(MAXYEAR, 12, 31),
]
for datecomps in dates:
dobj = self.theclass(*datecomps)
isocal = dobj.isocalendar()
d_roundtrip = self.theclass.fromisocalendar(*isocal)
self.assertEqual(dobj, d_roundtrip)
def test_fromisocalendar_value_errors(self):
isocals = [
(2019, 0, 1),
(2019, -1, 1),
(2019, 54, 1),
(2019, 1, 0),
(2019, 1, -1),
(2019, 1, 8),
(2019, 53, 1),
(10000, 1, 1),
(0, 1, 1),
(9999999, 1, 1),
(2 << 32, 1, 1),
(2019, 2 << 32, 1),
(2019, 1, 2 << 32),
]
for isocal in isocals:
self.assertRaises(ValueError, self.theclass.fromisocalendar, *isocal)
class TestDateTime(Static[TestDate[theclass]]):
theclass: type
def test_basic_attributes(self):
dt = self.theclass(2002, 3, 1, 12, 0)
self.assertEqual(dt.year, 2002)
self.assertEqual(dt.month, 3)
self.assertEqual(dt.day, 1)
self.assertEqual(dt.hour, 12)
self.assertEqual(dt.minute, 0)
self.assertEqual(dt.second, 0)
self.assertEqual(dt.microsecond, 0)
def test_basic_attributes_nonzero(self):
# Make sure all attributes are non-zero so bugs in
# bit-shifting access show up.
dt = self.theclass(2002, 3, 1, 12, 59, 59, 8000)
self.assertEqual(dt.year, 2002)
self.assertEqual(dt.month, 3)
self.assertEqual(dt.day, 1)
self.assertEqual(dt.hour, 12)
self.assertEqual(dt.minute, 59)
self.assertEqual(dt.second, 59)
self.assertEqual(dt.microsecond, 8000)
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")
# 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_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_more_ctime(self):
# Test fields that TestDate doesn't touch.
import time
t = self.theclass(2002, 3, 2, 18, 3, 5, 123)
self.assertEqual(t.ctime(), "Sat Mar 2 18:03:05 2002")
# Oops! The next line fails on Win2K under MSVC 6, so it's commented
# out. The difference is that t.ctime() produces " 2" for the day,
# but platform ctime() produces "02" for the day. According to
# C99, t.ctime() is correct here.
# self.assertEqual(t.ctime(), time.ctime(time.mktime(t.timetuple())))
# So test a case where that difference doesn't matter.
t = self.theclass(2002, 3, 22, 18, 3, 5, 123)
self.assertEqual(t.ctime(), time.ctime(time.mktime(t.timetuple())))
"""
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_bad_constructor_arguments(self):
# bad years
self.theclass(MINYEAR, 1, 1) # no exception
self.theclass(MAXYEAR, 1, 1) # no exception
make_dt1 = lambda a, b, c: self.theclass(a, b, c)
make_dt2 = lambda a, b, c, d: self.theclass(a, b, c, d)
make_dt3 = lambda a, b, c, d, e: self.theclass(a, b, c, d, e)
make_dt4 = lambda a, b, c, d, e, f: self.theclass(a, b, c, d, e, f)
make_dt5 = lambda a, b, c, d, e, f, g: self.theclass(a, b, c, d, e, f, g)
self.assertRaises(ValueError, make_dt1, MINYEAR - 1, 1, 1)
self.assertRaises(ValueError, make_dt1, MAXYEAR + 1, 1, 1)
# bad months
self.theclass(2000, 1, 1) # no exception
self.theclass(2000, 12, 1) # no exception
self.assertRaises(ValueError, make_dt1, 2000, 0, 1)
self.assertRaises(ValueError, make_dt1, 2000, 13, 1)
# bad days
self.theclass(2000, 2, 29) # no exception
self.theclass(2004, 2, 29) # no exception
self.theclass(2400, 2, 29) # no exception
self.assertRaises(ValueError, make_dt1, 2000, 2, 30)
self.assertRaises(ValueError, make_dt1, 2001, 2, 29)
self.assertRaises(ValueError, make_dt1, 2100, 2, 29)
self.assertRaises(ValueError, make_dt1, 1900, 2, 29)
self.assertRaises(ValueError, make_dt1, 2000, 1, 0)
self.assertRaises(ValueError, make_dt1, 2000, 1, 32)
# bad hours
self.theclass(2000, 1, 31, 0) # no exception
self.theclass(2000, 1, 31, 23) # no exception
self.assertRaises(ValueError, make_dt2, 2000, 1, 31, -1)
self.assertRaises(ValueError, make_dt2, 2000, 1, 31, 24)
# bad minutes
self.theclass(2000, 1, 31, 23, 0) # no exception
self.theclass(2000, 1, 31, 23, 59) # no exception
self.assertRaises(ValueError, make_dt3, 2000, 1, 31, 23, -1)
self.assertRaises(ValueError, make_dt3, 2000, 1, 31, 23, 60)
# bad seconds
self.theclass(2000, 1, 31, 23, 59, 0) # no exception
self.theclass(2000, 1, 31, 23, 59, 59) # no exception
self.assertRaises(ValueError, make_dt4, 2000, 1, 31, 23, 59, -1)
self.assertRaises(ValueError, make_dt4, 2000, 1, 31, 23, 59, 60)
# bad microseconds
self.theclass(2000, 1, 31, 23, 59, 59, 0) # no exception
self.theclass(2000, 1, 31, 23, 59, 59, 999999) # no exception
self.assertRaises(ValueError, make_dt5, 2000, 1, 31, 23, 59, 59, -1)
self.assertRaises(ValueError, make_dt5, 2000, 1, 31, 23, 59, 59, 1000000)
"""
# bad fold
self.assertRaises(ValueError, self.theclass,
2000, 1, 31, fold=-1)
self.assertRaises(ValueError, self.theclass,
2000, 1, 31, fold=2)
# Positional fold:
self.assertRaises(TypeError, self.theclass,
2000, 1, 31, 23, 59, 59, 0, None, 1)
"""
def test_hash_equality(self):
d = self.theclass(2000, 12, 31, 23, 30, 17)
e = self.theclass(2000, 12, 31, 23, 30, 17)
self.assertEqual(d, e)
self.assertEqual(hash(d), hash(e))
dic = {d: 1}
dic[e] = 2
self.assertEqual(len(dic), 1)
self.assertEqual(dic[d], 2)
self.assertEqual(dic[e], 2)
d = self.theclass(2001, 1, 1, 0, 5, 17)
e = self.theclass(2001, 1, 1, 0, 5, 17)
self.assertEqual(d, e)
self.assertEqual(hash(d), hash(e))
dic = {d: 1}
dic[e] = 2
self.assertEqual(len(dic), 1)
self.assertEqual(dic[d], 2)
self.assertEqual(dic[e], 2)
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)
"""
def test_more_compare(self):
# The test_compare() inherited from TestDate covers the error cases.
# We just want to test lexicographic ordering on the members datetime
# has that date lacks.
args = (2000, 11, 29, 20, 58, 16, 999998)
newargsx = [
(2001, 11, 29, 20, 58, 16, 999998),
(2000, 12, 29, 20, 58, 16, 999998),
(2000, 11, 30, 20, 58, 16, 999998),
(2000, 11, 29, 21, 58, 16, 999998),
(2000, 11, 29, 20, 59, 16, 999998),
(2000, 11, 29, 20, 58, 17, 999998),
(2000, 11, 29, 20, 58, 16, 999999),
]
t1 = self.theclass(*args)
t2 = self.theclass(*args)
self.assertEqual(t1, t2)
self.assertTrue(t1 <= t2)
self.assertTrue(t1 >= t2)
self.assertFalse(t1 != t2)
self.assertFalse(t1 < t2)
self.assertFalse(t1 > t2)
for i in range(len(args)):
newargs = newargsx[i]
t2 = self.theclass(*newargs) # this is larger than t1
self.assertTrue(t1 < t2)
self.assertTrue(t2 > t1)
self.assertTrue(t1 <= t2)
self.assertTrue(t2 >= t1)
self.assertTrue(t1 != t2)
self.assertTrue(t2 != t1)
self.assertFalse(t1 == t2)
self.assertFalse(t2 == t1)
self.assertFalse(t1 > t2)
self.assertFalse(t2 < t1)
self.assertFalse(t1 >= t2)
self.assertFalse(t2 <= t1)
# A helper for timestamp constructor tests.
def verify_field_equality(self, expected, got):
self.assertEqual(expected.tm_year, got.year)
self.assertEqual(expected.tm_mon, got.month)
self.assertEqual(expected.tm_mday, got.day)
self.assertEqual(expected.tm_hour, got.hour)
self.assertEqual(expected.tm_min, got.minute)
self.assertEqual(expected.tm_sec, got.second)
def test_fromtimestamp(self):
import time
ts = time.time()
expected = time.localtime(int(ts))
got = self.theclass.fromtimestamp(ts)
self.verify_field_equality(expected, got)
"""
def test_utcfromtimestamp(self):
import time
ts = time.time()
expected = time.gmtime(int(ts))
got = self.theclass.utcfromtimestamp(ts)
self.verify_field_equality(expected, got)
"""
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)
"""
t = self.theclass(1970, 1, 1)
self.assertEqual(t.timestamp(), 0)
t = self.theclass(1970, 1, 1, 1, 2, 3, 4)
self.assertEqual(t.timestamp(), 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)]:
s = None
try:
s = t.timestamp()
except OverflowError:
continue
self.assertEqual(self.theclass.fromtimestamp(s), t)
"""
"""
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_microsecond_rounding(self):
for fts in (self.theclass.fromtimestamp,
self.theclass.utcfromtimestamp):
zero = fts(0)
self.assertEqual(zero.second, 0)
self.assertEqual(zero.microsecond, 0)
one = fts(1e-6)
minus_one = fts(-1e-6)
self.assertEqual(minus_one.second, 59)
self.assertEqual(minus_one.microsecond, 999999)
t = fts(-1e-8)
self.assertEqual(t, zero)
t = fts(-9e-7)
self.assertEqual(t, minus_one)
t = fts(-1e-7)
self.assertEqual(t, zero)
t = fts(-1/2**7)
self.assertEqual(t.second, 59)
self.assertEqual(t.microsecond, 992188)
t = fts(1e-7)
self.assertEqual(t, zero)
t = fts(9e-7)
self.assertEqual(t, one)
t = fts(0.99999949)
self.assertEqual(t.second, 0)
self.assertEqual(t.microsecond, 999999)
t = fts(0.9999999)
self.assertEqual(t.second, 1)
self.assertEqual(t.microsecond, 0)
t = fts(1/2**7)
self.assertEqual(t.second, 0)
self.assertEqual(t.microsecond, 7812)
"""
"""
def test_timestamp_limits(self):
# minimum timestamp
min_dt = self.theclass.min.replace(tzinfo=timezone.utc)
min_ts = min_dt.timestamp()
try:
# date 0001-01-01 00:00:00+00:00: timestamp=-62135596800
self.assertEqual(self.theclass.fromtimestamp(min_ts, tz=timezone.utc),
min_dt)
except (OverflowError, OSError) as exc:
# the date 0001-01-01 doesn't fit into 32-bit time_t,
# or platform doesn't support such very old date
self.skipTest(str(exc))
# maximum timestamp: set seconds to zero to avoid rounding issues
max_dt = self.theclass.max.replace(tzinfo=timezone.utc,
second=0, microsecond=0)
max_ts = max_dt.timestamp()
# date 9999-12-31 23:59:00+00:00: timestamp 253402300740
self.assertEqual(self.theclass.fromtimestamp(max_ts, tz=timezone.utc),
max_dt)
# number of seconds greater than 1 year: make sure that the new date
# is not valid in datetime.datetime limits
delta = 3600 * 24 * 400
# too small
ts = min_ts - delta
# converting a Python int to C time_t can raise a OverflowError,
# especially on 32-bit platforms.
self.assertRaises(ValueError, self.theclass.fromtimestamp, ts)
self.assertRaises(ValueError, self.theclass.utcfromtimestamp, ts)
# too big
ts = max_dt.timestamp() + delta
self.assertRaises(ValueError, self.theclass.fromtimestamp, ts)
self.assertRaises(ValueError, self.theclass.utcfromtimestamp, ts)
"""
def test_negative_float_fromtimestamp(self):
# The result is tz-dependent; at least test that this doesn't
# fail (like it did before bug 1646728 was fixed).
self.theclass.fromtimestamp(-1.05)
"""
def test_negative_float_utcfromtimestamp(self):
d = self.theclass.utcfromtimestamp(-1.05)
self.assertEqual(d, self.theclass(1969, 12, 31, 23, 59, 58, 950000))
"""
def test_utcnow(self):
import time
# Call it a success if utcnow() and utcfromtimestamp() are within
# a second of each other.
from_timestamp = None
from_now = None
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.__val__() - from_now.__val__()) <= tolerance:
break
# Else try again a few times.
self.assertLessEqual(abs(from_timestamp.__val__() - from_now.__val__()), tolerance)
def test_extract(self):
dt = self.theclass(2002, 3, 4, 18, 45, 3, 1234)
self.assertEqual(dt.date(), date(2002, 3, 4))
self.assertEqual(dt.time(), time(18, 45, 3, 1234))
def test_combine(self):
d = date(2002, 3, 4)
t = time(18, 45, 3, 1234)
expected = self.theclass(2002, 3, 4, 18, 45, 3, 1234)
combine = self.theclass.combine
dt = combine(d, t)
self.assertEqual(dt, expected)
dt = combine(time=t, date=d)
self.assertEqual(dt, expected)
self.assertEqual(d, dt.date())
self.assertEqual(t, dt.time())
self.assertEqual(dt, combine(dt.date(), dt.time()))
"""
self.assertRaises(TypeError, combine) # need an arg
self.assertRaises(TypeError, combine, d) # need two args
self.assertRaises(TypeError, combine, t, d) # args reversed
self.assertRaises(TypeError, combine, d, t, 1) # wrong tzinfo type
self.assertRaises(TypeError, combine, d, t, 1, 2) # too many args
self.assertRaises(TypeError, combine, "date", "time") # wrong types
self.assertRaises(TypeError, combine, d, "time") # wrong type
self.assertRaises(TypeError, combine, "date", t) # wrong type
# tzinfo= argument
dt = combine(d, t, timezone.utc)
self.assertIs(dt.tzinfo, timezone.utc)
dt = combine(d, t, tzinfo=timezone.utc)
self.assertIs(dt.tzinfo, timezone.utc)
t = time()
dt = combine(dt, t)
self.assertEqual(dt.date(), d)
self.assertEqual(dt.time(), t)
"""
def test_replace(self):
cls = self.theclass
args = (1, 2, 3, 4, 5, 6, 7)
base = cls(*args)
self.assertEqual(base, base.replace())
self.assertEqual(base.replace(year=2), cls(2, 2, 3, 4, 5, 6, 7))
self.assertEqual(base.replace(month=3), cls(1, 3, 3, 4, 5, 6, 7))
self.assertEqual(base.replace(day=4), cls(1, 2, 4, 4, 5, 6, 7))
self.assertEqual(base.replace(hour=5), cls(1, 2, 3, 5, 5, 6, 7))
self.assertEqual(base.replace(minute=6), cls(1, 2, 3, 4, 6, 6, 7))
self.assertEqual(base.replace(second=7), cls(1, 2, 3, 4, 5, 7, 7))
self.assertEqual(base.replace(microsecond=8), cls(1, 2, 3, 4, 5, 6, 8))
# Out of bounds.
base = cls(2000, 2, 29)
self.assertRaises(ValueError, lambda: base.replace(year=2001))
"""
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_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"]
dts = [
self.theclass(*date_tuple, *time_tuple)
for date_tuple in base_dates
for time_tuple in base_times
]
for dt in dts:
for sep in separators:
dtstr = dt.isoformat(sep=sep)
dt_rt = self.theclass.fromisoformat(dtstr)
self.assertEqual(dt, dt_rt)
def test_fromisoformat_separators(self):
separators = [" ", "T"]
for sep in separators:
dt = self.theclass(2018, 1, 31, 23, 59, 47, 124789)
dtstr = dt.isoformat(sep=sep)
dt_rt = self.theclass.fromisoformat(dtstr)
self.assertEqual(dt, dt_rt)
def test_fromisoformat_ambiguous(self):
# Test strings like 2018-01-31+12:15 (where +12:15 is not a time zone)
separators = ["+", "-"]
for sep in separators:
dt = self.theclass(2018, 1, 31, 12, 15)
dtstr = dt.isoformat(sep=sep)
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)]
timespecs = ["hours", "minutes", "seconds", "milliseconds", "microseconds"]
for dt_tuple in datetime_bases:
dt = self.theclass(*(dt_tuple[0:4]))
dtstr = dt.isoformat(timespec="hours")
dt_rt = self.theclass.fromisoformat(dtstr)
self.assertEqual(dt, dt_rt)
dt = self.theclass(*(dt_tuple[0:5]))
dtstr = dt.isoformat(timespec="minutes")
dt_rt = self.theclass.fromisoformat(dtstr)
self.assertEqual(dt, dt_rt)
dt = self.theclass(*(dt_tuple[0:6]))
dtstr = dt.isoformat(timespec="seconds")
dt_rt = self.theclass.fromisoformat(dtstr)
self.assertEqual(dt, dt_rt)
new_microseconds = 1000 * (dt_tuple[6] // 1000)
dt_tuple2 = (*dt_tuple[0:6], new_microseconds)
dt = self.theclass(*(dt_tuple2[0:7]))
dtstr = dt.isoformat(timespec="milliseconds")
dt_rt = self.theclass.fromisoformat(dtstr)
self.assertEqual(dt, dt_rt)
dt = self.theclass(*(dt_tuple[0:8]))
dtstr = dt.isoformat(timespec="microseconds")
dt_rt = self.theclass.fromisoformat(dtstr)
self.assertEqual(dt, dt_rt)
def test_fromisoformat_fails_datetime(self):
# Test that fromisoformat() fails on invalid values
bad_strs = [
"", # Empty string
"\ud800", # bpo-34454: Surrogate code point
"2009.04-19T03", # Wrong first separator
"2009-04.19T03", # Wrong second separator
"2009-04-19T0a", # Invalid hours
"2009-04-19T03:1a:45", # Invalid minutes
"2009-04-19T03:15:4a", # Invalid seconds
"2009-04-19T03;15:45", # Bad first time separator
"2009-04-19T03:15;45", # Bad second time separator
"2009-04-19T03:15:4500:00", # Bad time zone separator
"2009-04-19T03:15:45.2345", # Too many digits for milliseconds
"2009-04-19T03:15:45.1234567", # Too many digits for microseconds
"2009-04-19T03:15:45.123456+24:30", # Invalid time zone offset
"2009-04-19T03:15:45.123456-24:30", # Invalid negative offset
"2009-04-10ᛇᛇᛇᛇᛇ12:15", # Too many unicode separators
"2009-04\ud80010T12:15", # Surrogate char in date
"2009-04-10T12\ud80015", # Surrogate char in time
"2009-04-19T1", # Incomplete hours
"2009-04-19T12:3", # Incomplete minutes
"2009-04-19T12:30:4", # Incomplete seconds
"2009-04-19T12:", # Ends with time separator
"2009-04-19T12:30:", # Ends with time separator
"2009-04-19T12:30:45.", # Ends with time separator
"2009-04-19T12:30:45.123456+", # Ends with timzone separator
"2009-04-19T12:30:45.123456-", # Ends with timzone separator
"2009-04-19T12:30:45.123456-05:00a", # Extra text
"2009-04-19T12:30:45.123-05:00a", # Extra text
"2009-04-19T12:30:45-05:00a", # Extra text
]
for bad_str in bad_strs:
self.assertRaises(ValueError, self.theclass.fromisoformat, bad_str)
class TestTime(Static[TestCase]):
theclass: type = time
def test_basic_attributes(self):
t = self.theclass(12, 0)
self.assertEqual(t.hour, 12)
self.assertEqual(t.minute, 0)
self.assertEqual(t.second, 0)
self.assertEqual(t.microsecond, 0)
def test_basic_attributes_nonzero(self):
# Make sure all attributes are non-zero so bugs in
# bit-shifting access show up.
t = self.theclass(12, 59, 59, 8000)
self.assertEqual(t.hour, 12)
self.assertEqual(t.minute, 59)
self.assertEqual(t.second, 59)
self.assertEqual(t.microsecond, 8000)
def test_comparing(self):
args = (1, 2, 3, 4)
newargsx = [(2, 2, 3, 4), (1, 3, 3, 4), (1, 2, 4, 4), (1, 2, 3, 5)]
t1 = self.theclass(*args)
t2 = self.theclass(*args)
self.assertEqual(t1, t2)
self.assertTrue(t1 <= t2)
self.assertTrue(t1 >= t2)
self.assertFalse(t1 != t2)
self.assertFalse(t1 < t2)
self.assertFalse(t1 > t2)
for i in range(len(args)):
newargs = newargsx[i]
t2 = self.theclass(*newargs) # this is larger than t1
self.assertTrue(t1 < t2)
self.assertTrue(t2 > t1)
self.assertTrue(t1 <= t2)
self.assertTrue(t2 >= t1)
self.assertTrue(t1 != t2)
self.assertTrue(t2 != t1)
self.assertFalse(t1 == t2)
self.assertFalse(t2 == t1)
self.assertFalse(t1 > t2)
self.assertFalse(t2 < t1)
self.assertFalse(t1 >= t2)
self.assertFalse(t2 <= t1)
"""
for badarg in OTHERSTUFF:
self.assertEqual(t1 == badarg, False)
self.assertEqual(t1 != badarg, True)
self.assertEqual(badarg == t1, False)
self.assertEqual(badarg != t1, True)
self.assertRaises(TypeError, lambda: t1 <= badarg)
self.assertRaises(TypeError, lambda: t1 < badarg)
self.assertRaises(TypeError, lambda: t1 > badarg)
self.assertRaises(TypeError, lambda: t1 >= badarg)
self.assertRaises(TypeError, lambda: badarg <= t1)
self.assertRaises(TypeError, lambda: badarg < t1)
self.assertRaises(TypeError, lambda: badarg > t1)
self.assertRaises(TypeError, lambda: badarg >= t1)
"""
def test_bad_constructor_arguments(self):
# bad hours
self.theclass(0, 0) # no exception
self.theclass(23, 0) # no exception
make_time1 = lambda a, b: self.theclass(a, b)
make_time2 = lambda a, b, c: self.theclass(a, b, c)
make_time3 = lambda a, b, c, d: self.theclass(a, b, c, d)
self.assertRaises(ValueError, make_time1, -1, 0)
self.assertRaises(ValueError, make_time1, 24, 0)
# bad minutes
self.theclass(23, 0) # no exception
self.theclass(23, 59) # no exception
self.assertRaises(ValueError, make_time1, 23, -1)
self.assertRaises(ValueError, make_time1, 23, 60)
# bad seconds
self.theclass(23, 59, 0) # no exception
self.theclass(23, 59, 59) # no exception
self.assertRaises(ValueError, make_time2, 23, 59, -1)
self.assertRaises(ValueError, make_time2, 23, 59, 60)
# bad microseconds
self.theclass(23, 59, 59, 0) # no exception
self.theclass(23, 59, 59, 999999) # no exception
self.assertRaises(ValueError, make_time3, 23, 59, 59, -1)
self.assertRaises(ValueError, make_time3, 23, 59, 59, 1000000)
def test_hash_equality(self):
d = self.theclass(23, 30, 17)
e = self.theclass(23, 30, 17)
self.assertEqual(d, e)
self.assertEqual(hash(d), hash(e))
dic = {d: 1}
dic[e] = 2
self.assertEqual(len(dic), 1)
self.assertEqual(dic[d], 2)
self.assertEqual(dic[e], 2)
d = self.theclass(0, 5, 17)
e = self.theclass(0, 5, 17)
self.assertEqual(d, e)
self.assertEqual(hash(d), hash(e))
dic = {d: 1}
dic[e] = 2
self.assertEqual(len(dic), 1)
self.assertEqual(dic[d], 2)
self.assertEqual(dic[e], 2)
def test_isoformat(self):
t = self.theclass(4, 5, 1, 123)
self.assertEqual(t.isoformat(), "04:05:01.000123")
self.assertEqual(t.isoformat(), str(t))
t = self.theclass()
self.assertEqual(t.isoformat(), "00:00:00")
self.assertEqual(t.isoformat(), str(t))
t = self.theclass(microsecond=1)
self.assertEqual(t.isoformat(), "00:00:00.000001")
self.assertEqual(t.isoformat(), str(t))
t = self.theclass(microsecond=10)
self.assertEqual(t.isoformat(), "00:00:00.000010")
self.assertEqual(t.isoformat(), str(t))
t = self.theclass(microsecond=100)
self.assertEqual(t.isoformat(), "00:00:00.000100")
self.assertEqual(t.isoformat(), str(t))
t = self.theclass(microsecond=1000)
self.assertEqual(t.isoformat(), "00:00:00.001000")
self.assertEqual(t.isoformat(), str(t))
t = self.theclass(microsecond=10000)
self.assertEqual(t.isoformat(), "00:00:00.010000")
self.assertEqual(t.isoformat(), str(t))
t = self.theclass(microsecond=100000)
self.assertEqual(t.isoformat(), "00:00:00.100000")
self.assertEqual(t.isoformat(), str(t))
t = self.theclass(hour=12, minute=34, second=56, microsecond=123456)
self.assertEqual(t.isoformat(timespec="hours"), "12")
self.assertEqual(t.isoformat(timespec="minutes"), "12:34")
self.assertEqual(t.isoformat(timespec="seconds"), "12:34:56")
self.assertEqual(t.isoformat(timespec="milliseconds"), "12:34:56.123")
self.assertEqual(t.isoformat(timespec="microseconds"), "12:34:56.123456")
self.assertEqual(t.isoformat(timespec="auto"), "12:34:56.123456")
t = self.theclass(hour=12, minute=34, second=56, microsecond=999500)
self.assertEqual(t.isoformat(timespec="milliseconds"), "12:34:56.999")
t = self.theclass(hour=12, minute=34, second=56, microsecond=0)
self.assertEqual(t.isoformat(timespec="milliseconds"), "12:34:56.000")
self.assertEqual(t.isoformat(timespec="microseconds"), "12:34:56.000000")
self.assertEqual(t.isoformat(timespec="auto"), "12:34:56")
def test_str(self):
self.assertEqual(str(self.theclass(1, 2, 3, 4)), "01:02:03.000004")
self.assertEqual(str(self.theclass(10, 2, 3, 4000)), "10:02:03.004000")
self.assertEqual(str(self.theclass(0, 2, 3, 400000)), "00:02:03.400000")
self.assertEqual(str(self.theclass(12, 2, 3, 0)), "12:02:03")
self.assertEqual(str(self.theclass(23, 15, 0, 0)), "23:15:00")
def test_repr(self):
self.assertEqual(
repr(self.theclass(1, 2, 3, 4)),
"time(hour=1, minute=2, second=3, microsecond=4)",
)
self.assertEqual(
repr(self.theclass(10, 2, 3, 4000)),
"time(hour=10, minute=2, second=3, microsecond=4000)",
)
self.assertEqual(
repr(self.theclass(0, 2, 3, 400000)),
"time(hour=0, minute=2, second=3, microsecond=400000)",
)
self.assertEqual(
repr(self.theclass(12, 2, 3, 0)), "time(hour=12, minute=2, second=3)"
)
self.assertEqual(repr(self.theclass(23, 15, 0, 0)), "time(hour=23, minute=15)")
def test_resolution_info(self):
self.assertTrue(self.theclass.max > self.theclass.min)
def test_bool(self):
# time is always True.
cls = self.theclass
self.assertTrue(cls(1))
self.assertTrue(cls(0, 1))
self.assertTrue(cls(0, 0, 1))
self.assertTrue(cls(0, 0, 0, 1))
self.assertTrue(cls(0))
self.assertTrue(cls())
def test_replace(self):
cls = self.theclass
args = (1, 2, 3, 4)
base = cls(*args)
self.assertEqual(base, base.replace())
self.assertEqual(base.replace(hour=5), cls(5, 2, 3, 4))
self.assertEqual(base.replace(minute=6), cls(1, 6, 3, 4))
self.assertEqual(base.replace(second=7), cls(1, 2, 7, 4))
self.assertEqual(base.replace(microsecond=8), cls(1, 2, 3, 8))
# Out of bounds.
base = cls(1)
self.assertRaises(ValueError, lambda: base.replace(hour=24))
self.assertRaises(
ValueError, lambda: base.replace(minute=-2)
) # minute=-1 indicates default; changed to -2 for test
self.assertRaises(ValueError, lambda: base.replace(second=100))
self.assertRaises(ValueError, lambda: base.replace(microsecond=1000000))
case_td = TestTimeDelta()
case_td.test_computations()
case_td.test_constructor()
case_td.test_resolution_info()
case_td.test_basic_attributes()
case_td.test_total_seconds()
case_td.test_carries()
case_td.test_hash_equality()
case_td.test_compare()
case_td.test_str()
case_td.test_repr()
case_td.test_microsecond_rounding()
case_td.test_massive_normalization()
case_td.test_bool()
case_td.test_division()
case_td.test_remainder()
case_td.test_divmod()
case_do = TestDateOnly()
case_do.test_delta_non_days_ignored()
case_dx = TestDate[date]()
case_dx.test_basic_attributes()
case_dx.test_ordinal_conversions()
# case_dx.test_extreme_ordinals()
case_dx.test_bad_constructor_arguments()
case_dx.test_hash_equality()
case_dx.test_computations()
case_dx.test_fromtimestamp()
case_dx.test_today()
case_dx.test_weekday()
case_dx.test_isocalendar()
case_dx.test_iso_long_years()
case_dx.test_isoformat()
case_dx.test_ctime()
case_dx.test_timetuple()
case_dx.test_compare()
case_dx.test_replace()
case_dx.test_fromisoformat()
case_dx.test_fromisoformat_fails()
case_dx.test_fromisocalendar()
case_dx.test_fromisocalendar_value_errors()
case_dt = TestDateTime[datetime]()
case_dt.test_ordinal_conversions()
case_dt.test_today()
case_dt.test_weekday()
case_dt.test_isocalendar()
case_dt.test_iso_long_years()
case_dt.test_ctime()
case_dt.test_timetuple()
case_dt.test_compare()
case_dt.test_fromisoformat()
case_dt.test_fromisoformat_fails()
case_dt.test_fromisocalendar_value_errors()
# ---
case_dt.test_basic_attributes()
case_dt.test_basic_attributes_nonzero()
case_dt.test_isoformat()
# case_dt.test_more_ctime()
case_dt.test_tz_independent_comparing()
case_dt.test_bad_constructor_arguments()
case_dt.test_hash_equality()
case_dt.test_computations()
case_dt.test_more_compare()
case_dt.test_fromtimestamp()
# case_dt.test_utcfromtimestamp()
case_dt.test_timestamp_naive()
# case_dt.test_microsecond_rounding()
# case_dt.test_timestamp_limits()
case_dt.test_negative_float_fromtimestamp()
# case_dt.test_negative_float_utcfromtimestamp()
case_dt.test_utcnow()
case_dt.test_extract()
case_dt.test_combine()
case_dt.test_replace()
case_dt.test_fromisoformat_datetime()
case_dt.test_fromisoformat_separators()
case_dt.test_fromisoformat_ambiguous()
case_dt.test_fromisoformat_timespecs()
case_dt.test_fromisoformat_fails_datetime()
case_tx = TestTime()
case_tx.test_basic_attributes()
case_tx.test_basic_attributes_nonzero()
case_tx.test_comparing()
case_tx.test_bad_constructor_arguments()
case_tx.test_hash_equality()
case_tx.test_isoformat()
case_tx.test_str()
case_tx.test_repr()
case_tx.test_resolution_info()
case_tx.test_bool()
case_tx.test_replace()
@test
def test_constants():
assert str(timedelta.min) == '-106751992 days, 19:59:05.224192' # note: diff w/ Python
assert str(timedelta.max) == '106751991 days, 4:00:54.775807' # note: diff w/ Python
assert str(timedelta.resolution) == '0:00:00.000001'
assert str(date.min) == '0001-01-01'
assert str(date.max) == '9999-12-31'
assert str(date.resolution) == '1 day, 0:00:00'
assert str(time.min) == '00:00:00'
assert str(time.max) == '23:59:59.999999'
assert str(time.resolution) == '0:00:00.000001'
assert str(datetime.min) == '0001-01-01 00:00:00'
assert str(datetime.max) == '9999-12-31 23:59:59.999999'
assert str(datetime.resolution) == '0:00:00.000001'
test_constants()