Skip to content

Commit 678c867

Browse files
authored
🐛 Preserve timezone information when validating Pendulum DateTimes (#189)
Fixes #188
1 parent 5edf337 commit 678c867

File tree

3 files changed

+28
-10
lines changed

3 files changed

+28
-10
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ _build/
2525
/.ghtopdep_cache/
2626
/worktrees/
2727
.ruff_cache/
28+
.python-version

pydantic_extra_types/pendulum_dt.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,7 @@ def _validate(cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler
8282
# probably the best way to have feature parity with
8383
# https://docs.pydantic.dev/latest/api/standard_library_types/#datetimedatetime
8484
value = handler(value)
85-
return DateTime(
86-
value.year,
87-
value.month,
88-
value.day,
89-
value.hour,
90-
value.minute,
91-
value.second,
92-
value.microsecond,
93-
value.tzinfo,
94-
)
85+
return DateTime.instance(value)
9586
except ValueError:
9687
try:
9788
value = parse(value, strict=cls.strict)

tests/test_pendulum_dt.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,32 @@ def test_pendulum_dt_from_serialized(dt):
129129
assert isinstance(model.dt, pendulum.DateTime)
130130

131131

132+
@pytest.mark.parametrize(
133+
'dt',
134+
[
135+
pendulum.now().to_iso8601_string(),
136+
pendulum.now().to_w3c_string(),
137+
],
138+
)
139+
def test_pendulum_dt_from_serialized_preserves_timezones(dt):
140+
"""
141+
Verifies that building an instance from serialized, well-formed strings decode
142+
properly and preserves the timezone information across all of the Pendulum DateTime
143+
properties. Regression test for pydantic/pydantic-extra-types#188.
144+
"""
145+
dt_actual = pendulum.parse(dt)
146+
model = DtModel(dt=dt)
147+
assert model.dt == dt_actual
148+
assert type(model.dt) is DateTime
149+
assert isinstance(model.dt, pendulum.DateTime)
150+
assert model.dt.tzinfo is not None
151+
assert model.dt.tzinfo.utcoffset(model.dt) == dt_actual.tzinfo.utcoffset(dt_actual)
152+
assert model.dt.tz is not None
153+
assert model.dt.tz.utcoffset(model.dt) == dt_actual.tz.utcoffset(dt_actual)
154+
assert model.dt.timezone is not None
155+
assert model.dt.timezone.utcoffset(model.dt) == dt_actual.timezone.utcoffset(dt_actual)
156+
157+
132158
@pytest.mark.parametrize(
133159
'dt',
134160
[

0 commit comments

Comments
 (0)