self.assertEqual(t.microsecond, 7812)
def test_timestamp_limits(self):
- # minimum timestamp
- min_dt = self.theclass.min.replace(tzinfo=timezone.utc)
+ with self.subTest("minimum UTC"):
+ min_dt = self.theclass.min.replace(tzinfo=timezone.utc)
+ min_ts = min_dt.timestamp()
+
+ # This test assumes that datetime.min == 0000-01-01T00:00:00.00
+ # If that assumption changes, this value can change as well
+ self.assertEqual(min_ts, -62135596800)
+
+ with self.subTest("maximum UTC"):
+ # Zero out microseconds to avoid rounding issues
+ max_dt = self.theclass.max.replace(tzinfo=timezone.utc,
+ microsecond=0)
+ max_ts = max_dt.timestamp()
+
+ # This test assumes that datetime.max == 9999-12-31T23:59:59.999999
+ # If that assumption changes, this value can change as well
+ self.assertEqual(max_ts, 253402300799.0)
+
+ def test_fromtimestamp_limits(self):
+ try:
+ self.theclass.fromtimestamp(-2**32 - 1)
+ except (OSError, OverflowError):
+ self.skipTest("Test not valid on this platform")
+
+ # XXX: Replace these with datetime.{min,max}.timestamp() when we solve
+ # the issue with gh-91012
+ min_dt = self.theclass.min + timedelta(days=1)
min_ts = min_dt.timestamp()
+
+ max_dt = self.theclass.max.replace(microsecond=0)
+ max_ts = ((self.theclass.max - timedelta(hours=23)).timestamp() +
+ timedelta(hours=22, minutes=59, seconds=59).total_seconds())
+
+ for (test_name, ts, expected) in [
+ ("minimum", min_ts, min_dt),
+ ("maximum", max_ts, max_dt),
+ ]:
+ with self.subTest(test_name, ts=ts, expected=expected):
+ actual = self.theclass.fromtimestamp(ts)
+
+ self.assertEqual(actual, expected)
+
+ # Test error conditions
+ test_cases = [
+ ("Too small by a little", min_ts - timedelta(days=1, hours=12).total_seconds()),
+ ("Too small by a lot", min_ts - timedelta(days=400).total_seconds()),
+ ("Too big by a little", max_ts + timedelta(days=1).total_seconds()),
+ ("Too big by a lot", max_ts + timedelta(days=400).total_seconds()),
+ ]
+
+ for test_name, ts in test_cases:
+ with self.subTest(test_name, ts=ts):
+ with self.assertRaises((ValueError, OverflowError)):
+ # converting a Python int to C time_t can raise a
+ # OverflowError, especially on 32-bit platforms.
+ self.theclass.fromtimestamp(ts)
+
+ def test_utcfromtimestamp_limits(self):
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)
+ self.theclass.utcfromtimestamp(-2**32 - 1)
+ except (OSError, OverflowError):
+ self.skipTest("Test not valid on this platform")
+
+ min_dt = self.theclass.min.replace(tzinfo=timezone.utc)
+ min_ts = min_dt.timestamp()
+
+ max_dt = self.theclass.max.replace(microsecond=0, tzinfo=timezone.utc)
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.
- with self.assertRaises((ValueError, OverflowError)):
- self.theclass.fromtimestamp(ts)
- with self.assertRaises((ValueError, OverflowError)):
- self.theclass.utcfromtimestamp(ts)
-
- # too big
- ts = max_dt.timestamp() + delta
- with self.assertRaises((ValueError, OverflowError)):
- self.theclass.fromtimestamp(ts)
- with self.assertRaises((ValueError, OverflowError)):
- self.theclass.utcfromtimestamp(ts)
+
+ for (test_name, ts, expected) in [
+ ("minimum", min_ts, min_dt.replace(tzinfo=None)),
+ ("maximum", max_ts, max_dt.replace(tzinfo=None)),
+ ]:
+ with self.subTest(test_name, ts=ts, expected=expected):
+ try:
+ actual = self.theclass.utcfromtimestamp(ts)
+ except (OSError, OverflowError) as exc:
+ self.skipTest(str(exc))
+
+ self.assertEqual(actual, expected)
+
+ # Test error conditions
+ test_cases = [
+ ("Too small by a little", min_ts - 1),
+ ("Too small by a lot", min_ts - timedelta(days=400).total_seconds()),
+ ("Too big by a little", max_ts + 1),
+ ("Too big by a lot", max_ts + timedelta(days=400).total_seconds()),
+ ]
+
+ for test_name, ts in test_cases:
+ with self.subTest(test_name, ts=ts):
+ with self.assertRaises((ValueError, OverflowError)):
+ # converting a Python int to C time_t can raise a
+ # OverflowError, especially on 32-bit platforms.
+ self.theclass.utcfromtimestamp(ts)
def test_insane_fromtimestamp(self):
# It's possible that some platform maps time_t to double,