Skip to content

Commit b8967c5

Browse files
authored
Merge pull request #736 from Bogdanp/message-datetime
Message.mesage_datetime property
2 parents 9037687 + cb8e099 commit b8967c5

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

dramatiq/message.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import dataclasses
2121
import time
2222
import uuid
23+
from datetime import datetime, timezone
2324
from typing import Any, Generic, Optional, TypeVar
2425

2526
from .broker import get_broker
@@ -189,3 +190,13 @@ def _fields(self) -> tuple[str, ...]:
189190

190191
def _replace(self, **changes) -> Message[R]:
191192
return dataclasses.replace(self, **changes)
193+
194+
@property
195+
def message_datetime(self) -> datetime:
196+
"""Read ``message_timestamp`` as a UTC-aware datetime.
197+
198+
Datetime precision is limited by the representation of ``Message.message_timestamp``, which is an
199+
integer storing milliseconds.
200+
"""
201+
unix_seconds, ms = divmod(self.message_timestamp, 1000)
202+
return datetime.fromtimestamp(unix_seconds, tz=timezone.utc).replace(microsecond=ms * 1000)

tests/test_messages.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import annotations
22

3+
from datetime import datetime, timedelta, timezone
4+
35
import dramatiq
46

57

@@ -47,3 +49,21 @@ def actor(arg):
4749

4850
assert repr(message) in repr(message_proxy), "Expecting MessageProxy repr to contain Message repr"
4951
assert str(message) == str(message_proxy), "Expecting identical __str__ of MessageProxy and Message"
52+
53+
54+
def test_message_datetime(stub_broker):
55+
"""Test reading message time as datetime."""
56+
57+
@dramatiq.actor
58+
def actor(arg):
59+
return arg
60+
61+
message = actor.send("input")
62+
after = datetime.now(timezone.utc)
63+
64+
assert message.message_datetime.tzinfo is timezone.utc
65+
assert message.message_datetime < after
66+
assert message.message_datetime > after - timedelta(seconds=1)
67+
68+
# no rounding problems here because message_timestamp is an int
69+
assert message.message_datetime.timestamp() == message.message_timestamp / 1000

0 commit comments

Comments
 (0)