diff --git a/bson/__init__.py b/bson/__init__.py index 4ad98237b6..16573b3de2 100644 --- a/bson/__init__.py +++ b/bson/__init__.py @@ -819,7 +819,7 @@ def _dict_to_bson(doc, check_keys, opts, top_level=True): def _millis_to_datetime(millis, opts): """Convert milliseconds since epoch UTC to datetime.""" diff = ((millis % 1000) + 1000) % 1000 - seconds = (millis - diff) / 1000 + seconds = (millis - diff) // 1000 micros = diff * 1000 if opts.tz_aware: dt = EPOCH_AWARE + datetime.timedelta(seconds=seconds, @@ -837,7 +837,7 @@ def _datetime_to_millis(dtm): if dtm.utcoffset() is not None: dtm = dtm - dtm.utcoffset() return int(calendar.timegm(dtm.timetuple()) * 1000 + - dtm.microsecond / 1000) + dtm.microsecond // 1000) _CODEC_OPTIONS_TYPE_ERROR = TypeError( diff --git a/test/test_bson.py b/test/test_bson.py index b5291c5ad5..86653c9c90 100644 --- a/test/test_bson.py +++ b/test/test_bson.py @@ -474,6 +474,13 @@ def test_datetime_encode_decode(self): dt2 = BSON.encode({"date": dt1}).decode()["date"] self.assertEqual(dt1, dt2) + def test_large_datetime_truncation(self): + # Ensure that a large datetime is truncated correctly. + dt1 = datetime.datetime(9999, 1, 1, 1, 1, 1, 999999) + dt2 = BSON.encode({"date": dt1}).decode()["date"] + self.assertEqual(dt2.microsecond, 999000) + self.assertEqual(dt2.second, dt1.second) + def test_aware_datetime(self): aware = datetime.datetime(1993, 4, 4, 2, tzinfo=FixedOffset(555, "SomeZone"))