import datetime
import sys
_monty = 'Monty' in sys.version
today = datetime.date.today()
assert isinstance(today, datetime.date)
now_local = datetime.datetime.now()
assert isinstance(now_local, datetime.datetime)
assert now_local.tzinfo is None
assert str(now_local).startswith(str(today))
now_utc = datetime.datetime.now(datetime.timezone.utc)
assert now_utc.tzinfo is datetime.timezone.utc
plus_two = datetime.timezone(datetime.timedelta(hours=2))
now_plus_two = datetime.datetime.now(plus_two)
assert now_plus_two.tzinfo == plus_two
named_plus_two = datetime.timezone(datetime.timedelta(hours=2), 'PLUS2')
now_named_plus_two = datetime.datetime.now(named_plus_two)
assert now_named_plus_two.tzinfo == named_plus_two
assert repr(datetime.date(2024, 1, 15)) == 'datetime.date(2024, 1, 15)'
assert str(datetime.date(2024, 1, 15)) == '2024-01-15'
assert repr(datetime.datetime(2024, 1, 15, 10, 30)) == 'datetime.datetime(2024, 1, 15, 10, 30)'
assert str(datetime.datetime(2024, 1, 15, 10, 30)) == '2024-01-15 10:30:00'
assert repr(datetime.timedelta(days=1, seconds=3600)) == 'datetime.timedelta(days=1, seconds=3600)'
assert str(datetime.timedelta(days=1, seconds=3600)) == '1 day, 1:00:00'
assert repr(datetime.timezone.utc) == 'datetime.timezone.utc'
assert datetime.timezone.utc is datetime.timezone.utc
assert datetime.timezone(datetime.timedelta(0)) is datetime.timezone.utc
try:
datetime.timezone(datetime.timedelta(0), None)
assert False, 'timezone(td, None) should raise TypeError'
except TypeError as e:
assert str(e) == 'timezone() argument 2 must be str, not None', f'timezone explicit None name: {e}'
assert (
repr(datetime.timezone(datetime.timedelta(seconds=3600))) == 'datetime.timezone(datetime.timedelta(seconds=3600))'
)
assert str(datetime.timezone(datetime.timedelta(seconds=61))) == 'UTC+00:01:01'
assert (
repr(datetime.timezone(datetime.timedelta(seconds=-1)))
== 'datetime.timezone(datetime.timedelta(days=-1, seconds=86399))'
)
assert (
repr(datetime.timezone(datetime.timedelta(hours=1), 'A'))
== "datetime.timezone(datetime.timedelta(seconds=3600), 'A')"
)
assert str(datetime.datetime(2024, 1, 1, tzinfo=datetime.timezone(datetime.timedelta(seconds=61)))) == (
'2024-01-01 00:00:00+00:01:01'
)
assert repr(datetime.datetime(2024, 1, 1, tzinfo=datetime.timezone(datetime.timedelta(seconds=-1)))) == (
'datetime.datetime(2024, 1, 1, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=86399)))'
)
named_tz = datetime.timezone(datetime.timedelta(hours=1), 'X')
named_dt = datetime.datetime(2024, 1, 1, tzinfo=named_tz)
assert repr(named_dt) == (
"datetime.datetime(2024, 1, 1, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600), 'X'))"
)
assert repr(named_dt.tzinfo) == "datetime.timezone(datetime.timedelta(seconds=3600), 'X')"
identity_tz = datetime.timezone(datetime.timedelta(hours=1), 'IDENTITY')
identity_dt = datetime.datetime(2024, 1, 1, 12, 0, 0, tzinfo=identity_tz)
assert identity_dt.tzinfo is identity_tz
assert identity_dt.tzinfo is identity_dt.tzinfo
assert (identity_dt + datetime.timedelta(seconds=1)).tzinfo is identity_tz
assert datetime.date(2024, 1, 10) + datetime.timedelta(days=5) == datetime.date(2024, 1, 15)
assert datetime.date(2024, 1, 10) - datetime.timedelta(days=5) == datetime.date(2024, 1, 5)
assert datetime.date(2024, 1, 10) - datetime.date(2024, 1, 1) == datetime.timedelta(days=9)
base_dt = datetime.datetime(2024, 1, 10, 12, 0, 0)
assert base_dt + datetime.timedelta(hours=2) == datetime.datetime(2024, 1, 10, 14, 0, 0)
assert base_dt - datetime.timedelta(hours=2) == datetime.datetime(2024, 1, 10, 10, 0, 0)
assert datetime.datetime(2024, 1, 10, 12, 0, 0) - datetime.datetime(2024, 1, 10, 11, 0, 0) == datetime.timedelta(
hours=1
)
assert datetime.timedelta(days=1, seconds=10) + datetime.timedelta(seconds=5) == datetime.timedelta(days=1, seconds=15)
assert datetime.timedelta(days=1, seconds=10) - datetime.timedelta(seconds=5) == datetime.timedelta(days=1, seconds=5)
assert -datetime.timedelta(days=1, seconds=30) == datetime.timedelta(days=-2, seconds=86370)
assert -datetime.timedelta(0) == datetime.timedelta(0)
assert -datetime.timedelta(days=-1) == datetime.timedelta(days=1)
assert datetime.timedelta(hours=1, minutes=30).total_seconds() == 5400.0
aware = datetime.datetime(2024, 1, 1, 12, 0, 0, tzinfo=datetime.timezone.utc)
naive = datetime.datetime(2024, 1, 1, 12, 0, 0)
assert (aware == naive) is False
assert (aware != naive) is True
assert datetime.datetime(2024, 1, 1, 12, 0, tzinfo=datetime.timezone.utc) == datetime.datetime(
2024, 1, 1, 13, 0, tzinfo=datetime.timezone(datetime.timedelta(hours=1))
)
assert datetime.timezone.utc == datetime.timezone(datetime.timedelta(0))
assert datetime.timezone(offset=datetime.timedelta(hours=1)) == datetime.timezone(datetime.timedelta(hours=1))
assert datetime.timezone(datetime.timedelta(hours=1), name='A') == datetime.timezone(datetime.timedelta(hours=1), 'A')
assert datetime.timezone(datetime.timedelta(hours=1), 'A') == datetime.timezone(datetime.timedelta(hours=1), 'B')
assert hash(datetime.timezone(datetime.timedelta(hours=1), 'A')) == hash(
datetime.timezone(datetime.timedelta(hours=1), 'B')
)
assert repr(datetime.timezone(datetime.timedelta(seconds=1))) == 'datetime.timezone(datetime.timedelta(seconds=1))'
try:
datetime.timezone(datetime.timedelta(hours=24))
assert False, 'timezone offset at 24 hours should raise ValueError'
except ValueError as e:
assert str(e) == (
'offset must be a timedelta strictly between -timedelta(hours=24) and timedelta(hours=24), '
'not datetime.timedelta(days=1)'
)
try:
datetime.datetime(2024, 1, 1, 1, hour=2)
assert False, 'datetime constructor should reject positional+keyword duplicate hour'
except TypeError as e:
assert str(e) == "argument for function given by name ('hour') and position (4)"
try:
datetime.datetime(2024, 1, 1, 0, 0, 0, 0, datetime.timezone.utc, tzinfo=datetime.timezone.utc)
assert False, 'datetime constructor should reject positional+keyword duplicate tzinfo'
except TypeError as e:
assert str(e) == "argument for function given by name ('tzinfo') and position (8)"
try:
datetime.timezone(datetime.timedelta(hours=1), offset=datetime.timedelta(hours=1))
assert False, 'timezone constructor should reject positional+keyword duplicate offset'
except TypeError as e:
assert str(e) == "argument for timezone() given by name ('offset') and position (1)"
try:
datetime.timezone(datetime.timedelta(hours=1), 'A', name='B')
assert False, 'timezone constructor should reject 3 arguments even when name is also provided by keyword'
except TypeError as e:
assert str(e) == 'timezone() takes at most 2 arguments (3 given)', f'timezone 3-arg error: {e}'
if sys.platform != 'win32':
try:
datetime.date(2**40, 1, 1)
assert False, 'date year above C int range should raise OverflowError'
except OverflowError as e:
assert str(e) == 'signed integer is greater than maximum', f'date year overflow: {e}'
try:
datetime.date(-(2**40), 1, 1)
assert False, 'date year below C int range should raise OverflowError'
except OverflowError as e:
assert str(e) == 'signed integer is less than minimum', f'date year underflow: {e}'
try:
datetime.date(2**100, 1, 1)
assert False, 'date year beyond C long should raise OverflowError'
except OverflowError as e:
assert str(e) == 'Python int too large to convert to C long', f'date year big-int: {e}'
try:
datetime.datetime(2**100, 1, 1)
assert False, 'datetime year beyond C long should raise OverflowError'
except OverflowError as e:
assert str(e) == 'Python int too large to convert to C long', f'datetime year big-int: {e}'
try:
datetime.timedelta(days=2**70)
assert False, 'timedelta days beyond i64 should raise OverflowError'
except OverflowError as e:
assert str(e) == 'Python int too large to convert to C int', f'timedelta days big-int: {e}'
try:
datetime.timedelta(weeks=2**100)
assert False, 'timedelta weeks beyond i64 should raise OverflowError'
except OverflowError as e:
assert str(e) == 'Python int too large to convert to C int', f'timedelta weeks big-int: {e}'
d = datetime.date(2024, 2, 29)
assert d.year == 2024
assert d.month == 2
assert d.day == 29
d_boundary = datetime.date(1, 1, 1)
assert d_boundary.year == 1
assert d_boundary.month == 1
assert d_boundary.day == 1
d_max = datetime.date(9999, 12, 31)
assert d_max.year == 9999
assert d_max.month == 12
assert d_max.day == 31
dt = datetime.datetime(2024, 6, 15, 14, 30, 45, 123456)
assert dt.year == 2024
assert dt.month == 6
assert dt.day == 15
assert dt.hour == 14
assert dt.minute == 30
assert dt.second == 45
assert dt.microsecond == 123456
dt_zero = datetime.datetime(2024, 1, 1, 0, 0, 0, 0)
assert dt_zero.hour == 0
assert dt_zero.microsecond == 0
td = datetime.timedelta(days=5, seconds=3600, microseconds=500)
assert td.days == 5
assert td.seconds == 3600
assert td.microseconds == 500
td_zero = datetime.timedelta(0)
assert td_zero.days == 0
assert td_zero.seconds == 0
assert td_zero.microseconds == 0
td_neg = datetime.timedelta(days=-1)
assert td_neg.days == -1
assert td_neg.seconds == 0
assert td_neg.microseconds == 0
td_mixed_neg = datetime.timedelta(seconds=-1)
assert td_mixed_neg.days == -1
assert td_mixed_neg.seconds == 86399
assert td_mixed_neg.microseconds == 0
assert repr(datetime.timedelta(0)) == 'datetime.timedelta(0)'
assert str(datetime.timedelta(0)) == '0:00:00'
assert str(datetime.timedelta(days=-1)) == '-1 day, 0:00:00'
assert str(datetime.timedelta(days=1)) == '1 day, 0:00:00'
assert str(datetime.timedelta(days=2)) == '2 days, 0:00:00'
assert repr(datetime.date(2024, 2, 29)) == 'datetime.date(2024, 2, 29)'
assert str(datetime.date(1, 1, 1)) == '0001-01-01'
assert str(datetime.date(9999, 12, 31)) == '9999-12-31'
try:
datetime.date(10000, 1, 1)
assert False, 'year OOB should raise ValueError'
except ValueError as e:
assert str(e) == 'year must be in 1..9999, not 10000', f'year OOB message: {e}'
try:
datetime.date(0, 1, 1)
assert False, 'year 0 should raise ValueError'
except ValueError as e:
assert str(e) == 'year must be in 1..9999, not 0', f'year 0 message: {e}'
try:
datetime.date(2024, 13, 1)
assert False, 'month OOB should raise ValueError'
except ValueError as e:
assert str(e) == 'month must be in 1..12, not 13', f'month OOB message: {e}'
try:
datetime.date(2024, 0, 1)
assert False, 'month 0 should raise ValueError'
except ValueError as e:
assert str(e) == 'month must be in 1..12, not 0', f'month 0 message: {e}'
try:
datetime.date(2024, 2, 30)
assert False, 'day OOB should raise ValueError'
except ValueError as e:
assert str(e) == 'day 30 must be in range 1..29 for month 2 in year 2024', f'day OOB message: {e}'
try:
datetime.date(2024, 1, 0)
assert False, 'day 0 should raise ValueError'
except ValueError as e:
assert str(e) == 'day 0 must be in range 1..31 for month 1 in year 2024', f'day 0 message: {e}'
try:
datetime.datetime(2024, 1, 1, 25)
assert False, 'hour OOB should raise ValueError'
except ValueError as e:
assert str(e) == 'hour must be in 0..23, not 25', f'hour OOB message: {e}'
try:
datetime.datetime(2024, 1, 1, 0, 60)
assert False, 'minute OOB should raise ValueError'
except ValueError as e:
assert str(e) == 'minute must be in 0..59, not 60', f'minute OOB message: {e}'
try:
datetime.datetime(2024, 1, 1, 0, 0, 60)
assert False, 'second OOB should raise ValueError'
except ValueError as e:
assert str(e) == 'second must be in 0..59, not 60', f'second OOB message: {e}'
try:
datetime.datetime(2024, 1, 1, 0, 0, 0, 1000000)
assert False, 'microsecond OOB should raise ValueError'
except ValueError as e:
assert str(e) == 'microsecond must be in 0..999999, not 1000000', f'microsecond OOB message: {e}'
assert not datetime.timedelta(0), 'timedelta(0) should be falsy'
assert datetime.timedelta(seconds=1)
assert datetime.timedelta(days=-1)
assert isinstance(datetime.datetime(2024, 1, 1, 0, 0), datetime.date)
assert not isinstance(datetime.date(2024, 1, 1), datetime.datetime), 'date should NOT be instance of datetime'
assert datetime.date(2024, 1, 15).isoformat() == '2024-01-15'
assert datetime.datetime(2024, 1, 15, 10, 30).isoformat() == '2024-01-15T10:30:00'
assert datetime.datetime(2024, 1, 15, 10, 30, 0, 123456).isoformat() == '2024-01-15T10:30:00.123456'
utc_iso = datetime.datetime(2024, 1, 15, 10, 30, tzinfo=datetime.timezone.utc)
assert utc_iso.isoformat() == '2024-01-15T10:30:00+00:00'
assert datetime.date(2024, 6, 15).replace(month=1) == datetime.date(2024, 1, 15)
assert datetime.date(2024, 6, 15).replace(year=2025, day=1) == datetime.date(2025, 6, 1)
assert datetime.datetime(2024, 6, 15, 10, 30).replace(hour=0, minute=0) == datetime.datetime(2024, 6, 15, 0, 0)
assert datetime.datetime(2024, 6, 15, 10, 30).replace(tzinfo=datetime.timezone.utc) == datetime.datetime(
2024, 6, 15, 10, 30, tzinfo=datetime.timezone.utc
)
assert datetime.date(2024, 6, 15).weekday() == 5
assert datetime.date(2024, 6, 15).isoweekday() == 6
assert datetime.date(2024, 6, 10).weekday() == 0
assert datetime.date(2024, 6, 10).isoweekday() == 1
assert datetime.datetime(2024, 6, 15, 12, 0).weekday() == 5
assert datetime.datetime(2024, 6, 15, 10, 30).date() == datetime.date(2024, 6, 15)
assert datetime.datetime(2024, 6, 15, 10, 30, 0, tzinfo=datetime.timezone.utc).timestamp() == 1718447400.0
assert datetime.timedelta(days=1) * 7 == datetime.timedelta(days=7)
assert 3 * datetime.timedelta(days=1) == datetime.timedelta(days=3)
assert datetime.timedelta(hours=2) * 0 == datetime.timedelta(0)
assert abs(datetime.timedelta(days=-3)) == datetime.timedelta(days=3)
assert abs(datetime.timedelta(0)) == datetime.timedelta(0)
assert abs(datetime.timedelta(days=5)) == datetime.timedelta(days=5)
assert datetime.timedelta(days=1) // 2 == datetime.timedelta(hours=12)
assert datetime.timedelta(days=1) / 2 == datetime.timedelta(hours=12)
assert datetime.timedelta(microseconds=3) / 2 == datetime.timedelta(microseconds=2)
assert datetime.date.fromisoformat('2024-06-15') == datetime.date(2024, 6, 15)
try:
datetime.date.fromisoformat('not-a-date')
assert False, 'date.fromisoformat should reject invalid strings'
except ValueError as e:
assert str(e) == "Invalid isoformat string: 'not-a-date'", f'date.fromisoformat error message: {e}'
assert datetime.datetime.fromisoformat('2024-06-15') == datetime.datetime(2024, 6, 15, 0, 0)
assert datetime.datetime.fromisoformat('2024-06-15T10:30:00') == datetime.datetime(2024, 6, 15, 10, 30)
assert datetime.datetime.fromisoformat('2024-06-15 10:30:00') == datetime.datetime(2024, 6, 15, 10, 30)
assert datetime.datetime.fromisoformat('2024-06-15T10:30') == datetime.datetime(2024, 6, 15, 10, 30)
assert datetime.datetime.fromisoformat('2024-06-15T10:30:00.123456') == datetime.datetime(
2024, 6, 15, 10, 30, 0, 123456
)
iso_utc = datetime.datetime.fromisoformat('2024-06-15T10:30:00+00:00')
assert iso_utc == datetime.datetime(2024, 6, 15, 10, 30, tzinfo=datetime.timezone.utc)
assert datetime.datetime.strptime('2024-06-15', '%Y-%m-%d') == datetime.datetime(2024, 6, 15, 0, 0)
assert datetime.datetime.strptime('2024-06-15 10:30:45', '%Y-%m-%d %H:%M:%S') == datetime.datetime(
2024, 6, 15, 10, 30, 45
)
assert datetime.datetime.strptime('15/06/2024', '%d/%m/%Y') == datetime.datetime(2024, 6, 15, 0, 0)
try:
datetime.datetime.strptime('2024-06-15', '%d/%m/%Y')
assert False, 'strptime should reject mismatched format'
except ValueError as e:
assert str(e) == "time data '2024-06-15' does not match format '%d/%m/%Y'", f'strptime error message: {e}'
assert datetime.date(year=2024, month=6, day=15) == datetime.date(2024, 6, 15)
assert datetime.date(2024, month=6, day=15) == datetime.date(2024, 6, 15)
try:
datetime.date(2024, 1, 1, 1)
assert False, 'date should reject too many positional args'
except TypeError as e:
assert str(e) == 'function takes at most 3 arguments (4 given)', f'date too many args message: {e}'
try:
datetime.date(2024, 1, 1, foo=1)
assert False, 'date should reject unknown keyword arg'
except TypeError as e:
assert str(e) == 'function takes at most 3 arguments (4 given)', f'date unknown kwarg message: {e}'
try:
datetime.date()
assert False, 'date() with no args should raise TypeError'
except TypeError as e:
assert str(e) == "function missing required argument 'year' (pos 1)", f'date() no args message: {e}'
try:
datetime.date(2024)
assert False, 'date() with 1 arg should raise TypeError'
except TypeError as e:
assert str(e) == "function missing required argument 'month' (pos 2)", f'date(year) message: {e}'
try:
datetime.date(2024, 1)
assert False, 'date() with 2 args should raise TypeError'
except TypeError as e:
assert str(e) == "function missing required argument 'day' (pos 3)", f'date(year, month) message: {e}'
assert datetime.datetime(year=2024, month=1, day=1, hour=12) == datetime.datetime(2024, 1, 1, 12)
try:
datetime.datetime(2024, 1, 1, foo=1)
assert False, 'datetime should reject unknown keyword arg'
except TypeError as e:
assert str(e) == "this function got an unexpected keyword argument 'foo'", f'datetime unknown kwarg message: {e}'
try:
datetime.datetime()
assert False, 'datetime() with no args should raise TypeError'
except TypeError as e:
assert str(e) == "function missing required argument 'year' (pos 1)", f'datetime() no args message: {e}'
try:
datetime.datetime(2024)
assert False, 'datetime() with 1 arg should raise TypeError'
except TypeError as e:
assert str(e) == "function missing required argument 'month' (pos 2)", f'datetime(year) message: {e}'
try:
datetime.datetime(2024, 1)
assert False, 'datetime() with 2 args should raise TypeError'
except TypeError as e:
assert str(e) == "function missing required argument 'day' (pos 3)", f'datetime(year, month) message: {e}'
utc = datetime.timezone.utc
aware_base = datetime.datetime(2024, 6, 15, 12, 0, 0, tzinfo=utc)
td_2h = datetime.timedelta(hours=2)
aware_add = aware_base + td_2h
assert aware_add == datetime.datetime(2024, 6, 15, 14, 0, 0, tzinfo=utc)
assert aware_add.tzinfo is utc
aware_sub = aware_base - td_2h
assert aware_sub == datetime.datetime(2024, 6, 15, 10, 0, 0, tzinfo=utc)
assert aware_sub.tzinfo is utc
aware_diff = aware_base - datetime.datetime(2024, 6, 15, 10, 0, 0, tzinfo=utc)
assert aware_diff == datetime.timedelta(hours=2)
plus5 = datetime.timezone(datetime.timedelta(hours=5))
aware_plus5 = datetime.datetime(2024, 6, 15, 17, 0, 0, tzinfo=plus5)
diff_tz = aware_base - aware_plus5
assert diff_tz == datetime.timedelta(0)
aware_a = datetime.datetime(2024, 1, 1, 12, 0, 0, tzinfo=utc)
aware_b = datetime.datetime(2024, 1, 1, 14, 0, 0, tzinfo=utc)
assert aware_a < aware_b
assert aware_b > aware_a
assert aware_a <= aware_a
assert aware_a >= aware_a
assert not (aware_a > aware_b), 'aware datetime not >'
naive_a = datetime.datetime(2024, 1, 1, 10, 0, 0)
naive_b = datetime.datetime(2024, 1, 1, 12, 0, 0)
assert naive_a < naive_b
assert naive_b > naive_a
assert naive_a == naive_a
assert not (naive_a == naive_b), 'naive datetime inequality'
td_a = datetime.timedelta(days=1)
td_b = datetime.timedelta(days=2)
assert td_a < td_b
assert td_b > td_a
assert td_a <= td_a
assert td_a >= td_a
assert td_a == td_a
assert not (td_a == td_b), 'timedelta inequality'
assert repr(datetime.timedelta(microseconds=500)) == 'datetime.timedelta(microseconds=500)'
assert repr(datetime.timedelta(seconds=1, microseconds=500)) == ('datetime.timedelta(seconds=1, microseconds=500)')
assert repr(datetime.datetime(2024, 1, 1, 0, 0, 30)) == 'datetime.datetime(2024, 1, 1, 0, 0, 30)'
assert repr(datetime.datetime(2024, 1, 1, 0, 0, 0, 123456)) == 'datetime.datetime(2024, 1, 1, 0, 0, 0, 123456)'
assert repr(datetime.datetime(2024, 1, 1, 0, 0, 30, 123456)) == ('datetime.datetime(2024, 1, 1, 0, 0, 30, 123456)')
assert str(datetime.datetime(2024, 1, 1, 10, 30, 0, 123456)) == '2024-01-01 10:30:00.123456'
assert repr(datetime.datetime(2024, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)) == (
'datetime.datetime(2024, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)'
)
dt_rep = datetime.datetime(2024, 6, 15, 10, 30, 45, 123456)
assert dt_rep.replace(second=0) == datetime.datetime(2024, 6, 15, 10, 30, 0, 123456)
assert dt_rep.replace(microsecond=0) == datetime.datetime(2024, 6, 15, 10, 30, 45, 0)
assert dt_rep.replace(year=2025, month=1, day=1, hour=0, minute=0, second=0, microsecond=0) == (
datetime.datetime(2025, 1, 1, 0, 0)
)
d_rep = datetime.date(2024, 6, 15)
assert d_rep.replace(year=2025) == datetime.date(2025, 6, 15)
assert d_rep.replace(month=1) == datetime.date(2024, 1, 15)
assert d_rep.replace(day=1) == datetime.date(2024, 6, 1)
assert datetime.date(1, 1, 1).isoformat() == '0001-01-01'
assert datetime.date(9999, 12, 31).isoformat() == '9999-12-31'
plus1 = datetime.timezone(datetime.timedelta(hours=1))
assert datetime.datetime(2024, 1, 15, 10, 30, tzinfo=plus1).isoformat() == '2024-01-15T10:30:00+01:00'
minus5 = datetime.timezone(datetime.timedelta(hours=-5))
assert datetime.datetime(2024, 1, 15, 10, 30, tzinfo=minus5).isoformat() == '2024-01-15T10:30:00-05:00'
assert datetime.datetime(2024, 1, 15, 10, 30, 45).isoformat() == '2024-01-15T10:30:45'
assert datetime.date(2024, 3, 1) - datetime.date(2024, 2, 1) == datetime.timedelta(days=29)
d_a = datetime.date(2024, 1, 1)
d_b = datetime.date(2024, 12, 31)
assert d_a < d_b
assert d_b > d_a
assert d_a <= d_a
assert d_a >= d_a
d_attr = datetime.date(2024, 6, 15)
assert d_attr.year == 2024
assert d_attr.month == 6
assert d_attr.day == 15
assert datetime.timedelta(milliseconds=1500) == datetime.timedelta(seconds=1, microseconds=500000)
assert datetime.timedelta(minutes=90) == datetime.timedelta(seconds=5400)
assert datetime.timedelta(hours=2) == datetime.timedelta(seconds=7200)
assert datetime.timedelta(weeks=1) == datetime.timedelta(days=7)
td_attrs = datetime.timedelta(days=3, seconds=7200, microseconds=500)
assert td_attrs.days == 3
assert td_attrs.seconds == 7200
assert td_attrs.microseconds == 500
try:
datetime.timezone(datetime.timedelta(hours=-24))
assert False, 'timezone offset at -24 hours should raise ValueError'
except ValueError as e:
assert str(e) == (
'offset must be a timedelta strictly between -timedelta(hours=24) and timedelta(hours=24), '
'not datetime.timedelta(days=-1)'
), f'timezone -24h range validation: {e}'
try:
datetime.timezone()
assert False, 'timezone() with no args should raise TypeError'
except TypeError as e:
assert str(e) == "timezone() missing required argument 'offset' (pos 1)", f'timezone() no args message: {e}'
assert str(datetime.timezone.utc) == 'UTC'
assert str(datetime.timezone(datetime.timedelta(hours=5))) == 'UTC+05:00'
assert str(datetime.timezone(datetime.timedelta(hours=-5))) == 'UTC-05:00'
assert str(datetime.timezone(datetime.timedelta(hours=5, minutes=30))) == 'UTC+05:30'
assert str(datetime.timezone(datetime.timedelta(hours=0), 'MyTZ')) == 'MyTZ'
now_kw = datetime.datetime.now(tz=datetime.timezone.utc)
assert now_kw.tzinfo is not None
assert hash(datetime.date(2024, 1, 1)) == hash(datetime.date(2024, 1, 1))
assert hash(datetime.datetime(2024, 1, 1, 12, 0)) == hash(datetime.datetime(2024, 1, 1, 12, 0))
assert hash(datetime.timedelta(days=1)) == hash(datetime.timedelta(days=1))
ts_naive = datetime.datetime(2024, 6, 15, 12, 0, 0).timestamp()
assert isinstance(ts_naive, float)
ts_aware = datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc).timestamp()
assert ts_aware == 0.0, f'epoch aware timestamp should be 0.0, got {ts_aware}'
try:
datetime.datetime(2024, 1, 1, 0, 0, 0, 0, datetime.timezone.utc, 'extra')
assert False, 'datetime with 9 positional args should raise TypeError'
except TypeError as e:
assert str(e) == 'function takes at most 8 positional arguments (9 given)', f'datetime too many args: {e}'
try:
datetime.datetime(2024, 1, 1, year=2024)
assert False, 'positional+keyword year should raise TypeError'
except TypeError as e:
assert str(e) == "argument for function given by name ('year') and position (1)", f'dup year: {e}'
try:
datetime.datetime(2024, 1, 1, day=1)
assert False, 'positional+keyword day should raise TypeError'
except TypeError as e:
assert str(e) == "argument for function given by name ('day') and position (3)", f'dup day: {e}'
try:
datetime.datetime(2024, 1, 1, 0, 30, minute=30)
assert False, 'positional+keyword minute should raise TypeError'
except TypeError as e:
assert str(e) == "argument for function given by name ('minute') and position (5)", f'dup minute: {e}'
try:
datetime.datetime(2024, 1, 1, 0, 0, 30, second=30)
assert False, 'positional+keyword second should raise TypeError'
except TypeError as e:
assert str(e) == "argument for function given by name ('second') and position (6)", f'dup second: {e}'
try:
datetime.datetime(2024, 1, 1, 0, 0, 0, 500, microsecond=500)
assert False, 'positional+keyword microsecond should raise TypeError'
except TypeError as e:
assert str(e) == "argument for function given by name ('microsecond') and position (7)", f'dup microsecond: {e}'
try:
datetime.datetime(2024, 1, 1, 0, 0, 0, 0, datetime.timezone.utc, tzinfo=datetime.timezone.utc)
assert False, 'positional+keyword tzinfo should raise TypeError'
except TypeError as e:
assert str(e) == "argument for function given by name ('tzinfo') and position (8)", f'dup tzinfo: {e}'
try:
datetime.datetime.now(datetime.timezone.utc, datetime.timezone.utc)
assert False, 'datetime.now() with 2 args should raise TypeError'
except TypeError as e:
assert str(e) == 'now() takes at most 1 argument (2 given)', f'datetime.now too many args: {e}'
try:
datetime.datetime.now(123, 456)
assert False, 'datetime.now(123, 456) should raise TypeError'
except TypeError as e:
assert str(e) == 'now() takes at most 1 argument (2 given)'
try:
datetime.datetime.now(datetime.timezone.utc, badkw=1)
assert False, 'datetime.now(utc, badkw=1) should raise TypeError'
except TypeError as e:
assert str(e) == 'now() takes at most 1 argument (2 given)'
try:
datetime.datetime.now(badkw=1)
assert False, 'datetime.now(badkw=1) should raise TypeError'
except TypeError as e:
assert str(e) == "now() got an unexpected keyword argument 'badkw'", f'datetime.now bad kwarg: {e}'
try:
datetime.datetime.now(tz=123)
assert False, 'datetime.now(tz=123) should raise TypeError'
except TypeError as e:
assert str(e) == "tzinfo argument must be None or of a tzinfo subclass, not type 'int'", f'now bad tz: {e}'
try:
datetime.datetime.now(datetime.timezone.utc, tz=datetime.timezone.utc)
assert False, 'datetime.now(utc, tz=utc) should raise TypeError for duplicate tz'
except TypeError as e:
assert str(e) == 'now() takes at most 1 argument (2 given)', f'datetime.now dup tz message: {e}'
now_tz_none = datetime.datetime.now(tz=None)
assert now_tz_none.tzinfo is None
utc = datetime.timezone.utc
aware_dt = datetime.datetime(2024, 6, 15, 12, 0, tzinfo=utc)
td = datetime.timedelta(hours=5)
result_add = aware_dt + td
assert repr(result_add) == 'datetime.datetime(2024, 6, 15, 17, 0, tzinfo=datetime.timezone.utc)', (
f'aware datetime + timedelta: {result_add!r}'
)
result_sub = aware_dt - td
assert repr(result_sub) == 'datetime.datetime(2024, 6, 15, 7, 0, tzinfo=datetime.timezone.utc)', (
f'aware datetime - timedelta: {result_sub!r}'
)
aware_a = datetime.datetime(2024, 6, 15, 12, 0, tzinfo=utc)
aware_b = datetime.datetime(2024, 6, 14, 10, 0, tzinfo=utc)
diff_aware = aware_a - aware_b
assert repr(diff_aware) == 'datetime.timedelta(days=1, seconds=7200)', f'aware sub: {diff_aware!r}'
naive_a = datetime.datetime(2024, 6, 15, 12, 0)
naive_b = datetime.datetime(2024, 6, 14, 10, 0)
diff_naive = naive_a - naive_b
assert repr(diff_naive) == 'datetime.timedelta(days=1, seconds=7200)', f'naive sub: {diff_naive!r}'
naive_dt = datetime.datetime(2024, 1, 1, 12, 0)
aware_dt2 = datetime.datetime(2024, 1, 1, 12, 0, tzinfo=utc)
assert not (naive_dt == aware_dt2), 'naive != aware should be False'
assert not (aware_dt2 == naive_dt), 'aware != naive should be False'
aware_early = datetime.datetime(2024, 1, 1, 10, 0, tzinfo=utc)
aware_late = datetime.datetime(2024, 1, 1, 14, 0, tzinfo=utc)
assert aware_early < aware_late
assert aware_late > aware_early
assert aware_early <= aware_late
assert aware_late >= aware_early
assert aware_early <= aware_early
assert aware_early >= aware_early
hash_a = hash(datetime.datetime(2024, 1, 1, 12, 0, tzinfo=utc))
hash_b = hash(datetime.datetime(2024, 1, 1, 12, 0, tzinfo=utc))
assert hash_a == hash_b
monday_dt = datetime.datetime(2024, 1, 1, 12, 0) assert monday_dt.isoweekday() == 1, f'Monday isoweekday should be 1, got {monday_dt.isoweekday()}'
saturday_dt = datetime.datetime(2024, 1, 6, 12, 0) assert saturday_dt.isoweekday() == 6, f'Saturday isoweekday should be 6, got {saturday_dt.isoweekday()}'
sunday_dt = datetime.datetime(2024, 1, 7, 12, 0) assert sunday_dt.isoweekday() == 7, f'Sunday isoweekday should be 7, got {sunday_dt.isoweekday()}'
dt_with_time = datetime.datetime(2024, 6, 15, 12, 30, 45, 123456)
d = dt_with_time.date()
assert repr(d) == 'datetime.date(2024, 6, 15)', f'datetime.date() method: {d!r}'
assert isinstance(d, datetime.date)
try:
datetime.datetime(2024, 1, 1).nosuchattr
assert False, 'accessing unknown attribute should raise AttributeError'
except AttributeError as e:
assert str(e) == "'datetime.datetime' object has no attribute 'nosuchattr'", f'datetime attr error: {e}'
dt_rep = datetime.datetime(2024, 6, 15, 12, 30, 45, 123456)
r_all = dt_rep.replace(year=2025, month=3, day=20, hour=8, minute=15, second=30, microsecond=999)
assert repr(r_all) == 'datetime.datetime(2025, 3, 20, 8, 15, 30, 999)', f'replace all fields: {r_all!r}'
try:
dt_rep.replace(badkw=1)
assert False, 'datetime.replace(badkw=1) should raise TypeError'
except TypeError as e:
assert str(e) == "replace() got an unexpected keyword argument 'badkw'", f'datetime.replace bad kwarg: {e}'
dt_strptime_date = datetime.datetime.strptime('2024-01-15', '%Y-%m-%d')
assert repr(dt_strptime_date) == 'datetime.datetime(2024, 1, 15, 0, 0)', f'strptime date-only: {dt_strptime_date!r}'
dt_strptime_micro = datetime.datetime.strptime('2024-01-15 10:30:45.123456', '%Y-%m-%d %H:%M:%S.%f')
assert repr(dt_strptime_micro) == 'datetime.datetime(2024, 1, 15, 10, 30, 45, 123456)', (
f'strptime with microseconds: {dt_strptime_micro!r}'
)
try:
datetime.datetime.strptime('not-a-date', '%Y-%m-%d')
assert False, 'strptime with non-matching format should raise ValueError'
except ValueError as e:
assert str(e) == "time data 'not-a-date' does not match format '%Y-%m-%d'", f'strptime bad format: {e}'
assert bool(datetime.datetime(2024, 1, 1))
assert bool(datetime.datetime(1, 1, 1, 0, 0, 0, 0))
iso_plain = datetime.datetime(2024, 1, 1, 12, 30, 45, 123456).isoformat()
assert iso_plain == '2024-01-01T12:30:45.123456', f'isoformat plain: {iso_plain}'
iso_no_micro = datetime.datetime(2024, 1, 1, 12, 30, 45).isoformat()
assert iso_no_micro == '2024-01-01T12:30:45', f'isoformat no micro: {iso_no_micro}'
iso_aware = datetime.datetime(2024, 1, 1, 12, 0, tzinfo=utc).isoformat()
assert iso_aware == '2024-01-01T12:00:00+00:00', f'isoformat aware: {iso_aware}'
dt_fmt = datetime.datetime(2024, 6, 15, 12, 30)
formatted = dt_fmt.strftime('%Y/%m/%d %H:%M')
assert formatted == '2024/06/15 12:30', f'strftime: {formatted}'
aware_rep = datetime.datetime(2024, 6, 15, 12, 30, tzinfo=utc)
aware_rep_result = aware_rep.replace(year=2025)
assert aware_rep_result.tzinfo is not None
assert repr(aware_rep_result) == 'datetime.datetime(2025, 6, 15, 12, 30, tzinfo=datetime.timezone.utc)', (
f'aware replace: {aware_rep_result!r}'
)
assert bool(datetime.date(2024, 1, 1))
assert bool(datetime.date(1, 1, 1))
assert datetime.date(2024, 1, 1) < datetime.date(2024, 1, 2)
assert datetime.date(2024, 1, 2) > datetime.date(2024, 1, 1)
assert datetime.date(2024, 1, 1) <= datetime.date(2024, 1, 1)
assert datetime.date(2024, 1, 1) >= datetime.date(2024, 1, 1)
assert datetime.date(2024, 1, 1) <= datetime.date(2024, 1, 2)
assert datetime.date(2024, 6, 15) >= datetime.date(2024, 6, 14)
try:
datetime.date(2024, 1, -1)
assert False, 'date(day=-1) should raise ValueError'
except ValueError as e:
assert str(e) == 'day -1 must be in range 1..31 for month 1 in year 2024', f'date neg day: {e}'
try:
datetime.date(2024, 1, 1, foo=1)
assert False, 'date with extra kwarg should raise TypeError'
except TypeError as e:
assert str(e) == 'function takes at most 3 arguments (4 given)', f'date too many args: {e}'
try:
datetime.date(2024, year=2024)
assert False, 'date with duplicate year should raise TypeError'
except TypeError as e:
assert str(e) == "function missing required argument 'month' (pos 2)", f'date dup year: {e}'
try:
datetime.date(2024, 1, month=1)
assert False, 'date with duplicate month should raise TypeError'
except TypeError as e:
assert str(e) == "function missing required argument 'day' (pos 3)", f'date dup month: {e}'
try:
datetime.date(2024, 1, 1).replace(foo=1)
assert False, 'date.replace(foo=1) should raise TypeError'
except TypeError as e:
assert str(e) == "replace() got an unexpected keyword argument 'foo'", f'date.replace bad kwarg: {e}'
try:
datetime.timedelta(days=1000000000)
assert False, 'timedelta with 1e9 days should raise OverflowError'
except OverflowError as e:
assert str(e) == 'days=1000000000; must have magnitude <= 999999999', f'td overflow: {e}'
try:
datetime.timedelta(days=-1000000000)
assert False, 'timedelta with -1e9 days should raise OverflowError'
except OverflowError as e:
assert str(e) == 'days=-1000000000; must have magnitude <= 999999999', f'td neg overflow: {e}'
try:
datetime.timedelta(1, days=1)
assert False, 'timedelta with duplicate days should raise TypeError'
except TypeError as e:
if _monty:
assert str(e) == "argument for timedelta() given by name ('days') and position (1)", f'td dup days: {e}'
else:
assert str(e) == "argument for __new__() given by name ('days') and position (1)", f'td dup days: {e}'
try:
datetime.timedelta(1, 2, seconds=2)
assert False, 'timedelta with duplicate seconds should raise TypeError'
except TypeError as e:
if _monty:
assert str(e) == "argument for timedelta() given by name ('seconds') and position (2)", f'td dup seconds: {e}'
else:
assert str(e) == "argument for __new__() given by name ('seconds') and position (2)", f'td dup seconds: {e}'
try:
datetime.timedelta(1, 2, 3, microseconds=3)
assert False, 'timedelta with duplicate microseconds should raise TypeError'
except TypeError as e:
if _monty:
assert str(e) == "argument for timedelta() given by name ('microseconds') and position (3)", (
f'td dup micro: {e}'
)
else:
assert str(e) == "argument for __new__() given by name ('microseconds') and position (3)", f'td dup micro: {e}'
try:
datetime.timedelta(foo=1)
assert False, 'timedelta with unexpected kwarg should raise TypeError'
except TypeError as e:
if _monty:
assert str(e) == "timedelta() got an unexpected keyword argument 'foo'", f'td foo kw: {e}'
else:
assert str(e) == "__new__() got an unexpected keyword argument 'foo'", f'td foo kw: {e}'
try:
datetime.timedelta('x')
assert False, 'timedelta(non-int) should raise TypeError'
except TypeError as e:
if _monty:
assert str(e) == "'str' object cannot be interpreted as an integer", f'td non-int days: {e}'
else:
assert str(e) == 'unsupported type for timedelta days component: str', f'td non-int days: {e}'
try:
datetime.timedelta(milliseconds=[1, 2])
assert False, 'timedelta(milliseconds=non-int) should raise TypeError'
except TypeError as e:
if _monty:
assert str(e) == "'list' object cannot be interpreted as an integer", f'td non-int ms kw: {e}'
else:
assert str(e) == 'unsupported type for timedelta milliseconds component: list', f'td non-int ms kw: {e}'
base_dt = datetime.datetime(2024, 6, 15)
try:
base_dt.replace(year='nope')
assert False, 'datetime.replace(year=str) should raise TypeError'
except TypeError as e:
assert str(e) == "'str' object cannot be interpreted as an integer", f'dt.replace bad type: {e}'
base_date = datetime.date(2024, 6, 15)
try:
base_date.replace(day='last')
assert False, 'date.replace(day=str) should raise TypeError'
except TypeError as e:
assert str(e) == "'str' object cannot be interpreted as an integer", f'date.replace bad type: {e}'
try:
datetime.datetime(year=2024, month=6)
assert False, 'datetime missing day should raise TypeError'
except TypeError as e:
assert str(e) == "function missing required argument 'day' (pos 3)", f'dt missing day: {e}'
try:
datetime.datetime('twenty-four', 6, 15)
assert False, 'datetime non-int year should raise TypeError'
except TypeError as e:
assert str(e) == "'str' object cannot be interpreted as an integer", f'dt non-int year: {e}'
try:
datetime.datetime(2024, 6, 15, 0, 0, 0, 'oops')
assert False, 'datetime non-int microsecond should raise TypeError'
except TypeError as e:
assert str(e) == "'str' object cannot be interpreted as an integer", f'dt non-int microsec: {e}'
try:
datetime.datetime(2024, 6, 15, microsecond='nope')
assert False, 'datetime non-int microsecond kwarg should raise TypeError'
except TypeError as e:
assert str(e) == "'str' object cannot be interpreted as an integer", f'dt non-int microsec kw: {e}'
assert str(datetime.timedelta(seconds=1, microseconds=500)) == '0:00:01.000500'
assert str(datetime.timedelta(microseconds=1)) == '0:00:00.000001'
assert str(datetime.timedelta(days=1, microseconds=123456)) == '1 day, 0:00:00.123456'
assert datetime.timedelta(days=1) < datetime.timedelta(days=2)
assert datetime.timedelta(days=2) > datetime.timedelta(days=1)
assert datetime.timedelta(days=1) <= datetime.timedelta(days=1)
assert datetime.timedelta(days=1) >= datetime.timedelta(days=1)
assert datetime.timedelta(seconds=30) < datetime.timedelta(seconds=60)
assert datetime.timedelta(days=1) >= datetime.timedelta(seconds=86399)
try:
datetime.timezone(datetime.timedelta(0), 'UTC', 'extra')
assert False, 'timezone with 3 args should raise TypeError'
except TypeError as e:
assert str(e) == 'timezone() takes at most 2 arguments (3 given)', f'tz too many: {e}'
try:
datetime.timezone(datetime.timedelta(0), foo='bar')
assert False, 'timezone with unexpected kwarg should raise TypeError'
except TypeError as e:
assert str(e) == "timezone() got an unexpected keyword argument 'foo'", f'tz bad kwarg: {e}'
try:
datetime.timezone(3600)
assert False, 'timezone(int) should raise TypeError'
except TypeError as e:
assert str(e) == 'timezone() argument 1 must be datetime.timedelta, not int', f'tz non-td offset: {e}'
try:
datetime.timezone(None)
assert False, 'timezone(None) should raise TypeError'
except TypeError as e:
assert str(e) == 'timezone() argument 1 must be datetime.timedelta, not None', f'tz None offset: {e}'
try:
datetime.timezone(datetime.timedelta(0), 123)
assert False, 'timezone(td, int) should raise TypeError'
except TypeError as e:
assert str(e) == 'timezone() argument 2 must be str, not int', f'tz non-str name: {e}'
try:
datetime.timezone(datetime.timedelta(hours=25))
assert False, 'timezone with 25h offset should raise ValueError'
except ValueError as e:
assert 'strictly between' in str(e), f'tz out of range: {e}'
try:
datetime.timezone(datetime.timedelta(hours=-25))
assert False, 'timezone with -25h offset should raise ValueError'
except ValueError as e:
assert 'strictly between' in str(e), f'tz neg out of range: {e}'
tz_five = datetime.timezone(datetime.timedelta(hours=5))
tz_five_b = datetime.timezone(datetime.timedelta(hours=5))
tz_six = datetime.timezone(datetime.timedelta(hours=6))
assert tz_five == tz_five_b
assert tz_five != tz_six
assert not (tz_five != tz_five_b), 'same offset timezones should not be not-equal'
try:
datetime.datetime(2024, 1, 1, month=1)
assert False, 'datetime with duplicate month should raise TypeError'
except TypeError as e:
assert str(e) == "argument for function given by name ('month') and position (2)", f'dt dup month: {e}'
tz_keepalive = datetime.timezone(datetime.timedelta(hours=5))
dt_keepalive = datetime.datetime(2024, 1, 1, tzinfo=tz_keepalive)
tz_keepalive = None
gc_seed = []
gc_seed.append(gc_seed)
_ = []
assert str(dt_keepalive.tzinfo) == 'UTC+05:00'