-
-
Notifications
You must be signed in to change notification settings - Fork 266
Description
Hello,
There may be a regression in Structlog 25.2.0 as a result of #709. My unit tests found that it always displays time in local timezone, even if you set flag utc=True. For ISO format it works fine, but for custom format, it strips the UTC timezone and applies a local one.
Easiest way to reproduce is:
event_dict = {}
time_stamper_local = structlog.processors.TimeStamper(fmt="%Y-%m-%d %H:%M:%S %Z", utc=False)
print(time_stamper_local(None, None, event_dict))
time_stamper_utc = structlog.processors.TimeStamper(fmt="%Y-%m-%d %H:%M:%S %Z", utc=True)
print(time_stamper_utc(None, None, event_dict))
# prints
{'timestamp': '2025-03-14 13:33:03 CET'}
{'timestamp': '2025-03-14 13:33:03 CET'}In structlog/src/structlog/processors.py
TimeStamper(fmt="%Y-%m-%d %H:%M:%S %Z", utc=True) effectively does:
datetime.datetime.now(tz=datetime.timezone.utc).astimezone()
Before applying astimezone() the object has UTC timezone, then it is replaced by local timezone. As per datetime documentation:
If called without arguments (or with tz=None) the system local time zone is assumed for the target time zone.
Not sure if this is intentional, but this behavior changed from Structlog 25.1.0. How about handling UTC separately, the same way it is done for ISO format?
diff --git a/structlog/.venv/lib/python3.10/site-packages/structlog/processors.py b/structlog/.venv/lib/python3.10/site-packages/structlog/processors.py
index 4ef7578..39e1532 100644
--- a/structlog/.venv/lib/python3.10/site-packages/structlog/processors.py
+++ b/structlog/.venv/lib/python3.10/site-packages/structlog/processors.py
@@ -553,12 +553,18 @@ def _make_stamper(
return stamper_iso_local
- def stamper_fmt(event_dict: EventDict) -> EventDict:
+ def stamper_fmt_local(event_dict: EventDict) -> EventDict:
event_dict[key] = now().astimezone().strftime(fmt)
+ return event_dict
+ def stamper_fmt_utc(event_dict: EventDict) -> EventDict:
+ event_dict[key] = now().strftime(fmt)
return event_dict
- return stamper_fmt
+ if utc:
+ return stamper_fmt_utc
+
+ return stamper_fmt_local
class MaybeTimeStamper:Let me know if this makes sense or I misconfigured something,
Thanks,
Marcin Endraszka