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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ You can find our backwards-compatibility policy [here](https://github.com/hynek/
- `structlog.stdlib.BoundLogger`'s binding-related methods now also return `Self`.
[#694](https://github.com/hynek/structlog/pull/694)

- `structlog.processors.TimeStamper` now produces internally timezone-aware `datetime` objects.
Default output hasn't changed, but you can now use `%z` in your *fmt* string.
[#709](https://github.com/hynek/structlog/pull/709)


### Fixed

Expand Down
5 changes: 3 additions & 2 deletions src/structlog/processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,8 @@ def now() -> datetime.datetime:
else:

def now() -> datetime.datetime:
# A naive local datetime is fine here, because we only format it.
# We don't need the TZ for our own formatting. We add it only for
# user-defined formats later.
return datetime.datetime.now() # noqa: DTZ005

if fmt is None:
Expand Down Expand Up @@ -553,7 +554,7 @@ def stamper_iso_utc(event_dict: EventDict) -> EventDict:
return stamper_iso_local

def stamper_fmt(event_dict: EventDict) -> EventDict:
event_dict[key] = now().strftime(fmt)
event_dict[key] = now().astimezone().strftime(fmt)

return event_dict

Expand Down
15 changes: 13 additions & 2 deletions tests/processors/test_renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,8 +396,8 @@ def test_inserts_utc_unix_timestamp_by_default(self):
@freeze_time("1980-03-25 16:00:00")
def test_local(self):
"""
Timestamp in local timezone work. We can't add a timezone to the
string without additional libraries.
Timestamp in local timezone work. Due to historic reasons, the default
format does not include a timezone.
"""
ts = TimeStamper(fmt="iso", utc=False)
d = ts(None, None, {})
Expand All @@ -414,6 +414,17 @@ def test_formats(self):

assert "1980" == d["timestamp"]

@freeze_time("1980-03-25 16:00:00")
def test_tz_aware(self):
"""
The timestamp that is used for formatting is timezone-aware.
"""
ts = TimeStamper(fmt="%z")
d = ts(None, None, {})

assert "" == datetime.datetime.now().strftime("%z") # noqa: DTZ005
assert "" != d["timestamp"]

@freeze_time("1980-03-25 16:00:00")
def test_adds_Z_to_iso(self):
"""
Expand Down