Skip to content

Commit e776722

Browse files
authored
Avoid using floating points during timestamp-datetime conversions (#591)
1 parent 9aedf8e commit e776722

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

Diff for: msgpack/ext.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,14 @@ def to_datetime(self):
157157
:rtype: `datetime.datetime`
158158
"""
159159
utc = datetime.timezone.utc
160-
return datetime.datetime.fromtimestamp(0, utc) + datetime.timedelta(seconds=self.to_unix())
160+
return datetime.datetime.fromtimestamp(0, utc) + datetime.timedelta(
161+
seconds=self.seconds, microseconds=self.nanoseconds // 1000
162+
)
161163

162164
@staticmethod
163165
def from_datetime(dt):
164166
"""Create a Timestamp from datetime with tzinfo.
165167
166168
:rtype: Timestamp
167169
"""
168-
return Timestamp.from_unix(dt.timestamp())
170+
return Timestamp(seconds=int(dt.timestamp()), nanoseconds=dt.microsecond * 1000)

Diff for: test/test_timestamp.py

+15
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,21 @@ def test_timestamp_datetime():
8686
utc = datetime.timezone.utc
8787
assert t.to_datetime() == datetime.datetime(1970, 1, 1, 0, 0, 42, 0, tzinfo=utc)
8888

89+
ts = datetime.datetime(2024, 4, 16, 8, 43, 9, 420317, tzinfo=utc)
90+
ts2 = datetime.datetime(2024, 4, 16, 8, 43, 9, 420318, tzinfo=utc)
91+
92+
assert (
93+
Timestamp.from_datetime(ts2).nanoseconds - Timestamp.from_datetime(ts).nanoseconds == 1000
94+
)
95+
96+
ts3 = datetime.datetime(2024, 4, 16, 8, 43, 9, 4256)
97+
ts4 = datetime.datetime(2024, 4, 16, 8, 43, 9, 4257)
98+
assert (
99+
Timestamp.from_datetime(ts4).nanoseconds - Timestamp.from_datetime(ts3).nanoseconds == 1000
100+
)
101+
102+
assert Timestamp.from_datetime(ts).to_datetime() == ts
103+
89104

90105
def test_unpack_datetime():
91106
t = Timestamp(42, 14)

0 commit comments

Comments
 (0)