From 4ea42eba4d73ff448fd81edf438e38d33d00db57 Mon Sep 17 00:00:00 2001 From: Kadir Can Ozden <101993364+bysiber@users.noreply.github.com> Date: Fri, 20 Feb 2026 14:59:16 +0300 Subject: [PATCH 1/2] Fix Timestamp.from_datetime returning wrong value for pre-epoch times int() truncates towards zero, so for pre-epoch datetimes with non-zero microseconds the seconds component gets the wrong value. For example, datetime(1969, 12, 31, 23, 59, 59, 500000, UTC) has timestamp -0.5, but int(-0.5) == 0, producing Timestamp(0, 500000000) (+0.5s after epoch) instead of Timestamp(-1, 500000000) (-0.5s before epoch). Use floor division (// 1) instead, consistent with from_unix(). --- msgpack/ext.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msgpack/ext.py b/msgpack/ext.py index 9694819a..92ea4530 100644 --- a/msgpack/ext.py +++ b/msgpack/ext.py @@ -167,4 +167,4 @@ def from_datetime(dt): :rtype: Timestamp """ - return Timestamp(seconds=int(dt.timestamp()), nanoseconds=dt.microsecond * 1000) + return Timestamp(seconds=int(dt.timestamp() // 1), nanoseconds=dt.microsecond * 1000) From 8ddd5d77881a38aaf73e4a5185833549eaf2f7b9 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Tue, 2 Jun 2026 21:21:38 +0900 Subject: [PATCH 2/2] add test for pre-epoch datetime --- test/test_timestamp.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/test_timestamp.py b/test/test_timestamp.py index 831141a1..6dfe3689 100644 --- a/test/test_timestamp.py +++ b/test/test_timestamp.py @@ -103,6 +103,13 @@ def test_timestamp_datetime(): assert Timestamp.from_datetime(ts).to_datetime() == ts + # Regression test: pre-epoch fractional seconds must floor toward -inf. + pre_epoch = datetime.datetime(1969, 12, 31, 23, 59, 59, 500000, tzinfo=utc) + ts_pre_epoch = Timestamp.from_datetime(pre_epoch) + assert ts_pre_epoch.seconds == -1 + assert ts_pre_epoch.nanoseconds == 500000000 + assert ts_pre_epoch.to_datetime() == pre_epoch + def test_unpack_datetime(): t = Timestamp(42, 14)