Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions dramatiq/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import dataclasses
import time
import uuid
from datetime import datetime, timezone
from typing import Any, Generic, Optional, TypeVar

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

def _replace(self, **changes) -> Message[R]:
return dataclasses.replace(self, **changes)

@property
def message_datetime(self) -> datetime:
"""Read ``message_timestamp`` as a UTC-aware datetime.
Datetime precision is limited by the representation of ``Message.message_timestamp``, which is an
integer storing milliseconds.
"""
unix_seconds, ms = divmod(self.message_timestamp, 1000)
return datetime.fromtimestamp(unix_seconds, tz=timezone.utc).replace(microsecond=ms * 1000)
20 changes: 20 additions & 0 deletions tests/test_messages.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from __future__ import annotations

from datetime import datetime, timedelta, timezone

import dramatiq


Expand Down Expand Up @@ -47,3 +49,21 @@ def actor(arg):

assert repr(message) in repr(message_proxy), "Expecting MessageProxy repr to contain Message repr"
assert str(message) == str(message_proxy), "Expecting identical __str__ of MessageProxy and Message"


def test_message_datetime(stub_broker):
"""Test reading message time as datetime."""

@dramatiq.actor
def actor(arg):
return arg

message = actor.send("input")
after = datetime.now(timezone.utc)

assert message.message_datetime.tzinfo is timezone.utc
assert message.message_datetime < after
assert message.message_datetime > after - timedelta(seconds=1)

# no rounding problems here because message_timestamp is an int
assert message.message_datetime.timestamp() == message.message_timestamp / 1000