Skip to content

Commit

Permalink
Avoid using floating points during timestamp-datetime conversions (#591)
Browse files Browse the repository at this point in the history
  • Loading branch information
hakanakyurek authored Apr 19, 2024
1 parent 9aedf8e commit e776722
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
6 changes: 4 additions & 2 deletions msgpack/ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,14 @@ def to_datetime(self):
:rtype: `datetime.datetime`
"""
utc = datetime.timezone.utc
return datetime.datetime.fromtimestamp(0, utc) + datetime.timedelta(seconds=self.to_unix())
return datetime.datetime.fromtimestamp(0, utc) + datetime.timedelta(
seconds=self.seconds, microseconds=self.nanoseconds // 1000
)

@staticmethod
def from_datetime(dt):
"""Create a Timestamp from datetime with tzinfo.
:rtype: Timestamp
"""
return Timestamp.from_unix(dt.timestamp())
return Timestamp(seconds=int(dt.timestamp()), nanoseconds=dt.microsecond * 1000)
15 changes: 15 additions & 0 deletions test/test_timestamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,21 @@ def test_timestamp_datetime():
utc = datetime.timezone.utc
assert t.to_datetime() == datetime.datetime(1970, 1, 1, 0, 0, 42, 0, tzinfo=utc)

ts = datetime.datetime(2024, 4, 16, 8, 43, 9, 420317, tzinfo=utc)
ts2 = datetime.datetime(2024, 4, 16, 8, 43, 9, 420318, tzinfo=utc)

assert (
Timestamp.from_datetime(ts2).nanoseconds - Timestamp.from_datetime(ts).nanoseconds == 1000
)

ts3 = datetime.datetime(2024, 4, 16, 8, 43, 9, 4256)
ts4 = datetime.datetime(2024, 4, 16, 8, 43, 9, 4257)
assert (
Timestamp.from_datetime(ts4).nanoseconds - Timestamp.from_datetime(ts3).nanoseconds == 1000
)

assert Timestamp.from_datetime(ts).to_datetime() == ts


def test_unpack_datetime():
t = Timestamp(42, 14)
Expand Down

0 comments on commit e776722

Please sign in to comment.