Skip to content

fix: correct ISO 8601 serialization for negative pendulum Duration values - #377

Merged
yezz123 merged 1 commit into
pydantic:mainfrom
r266-tech:fix/negative-duration-iso8601
Mar 22, 2026
Merged

yezz123 merged 1 commit into
pydantic:mainfrom
r266-tech:fix/negative-duration-iso8601

Conversation

@r266-tech

Copy link
Copy Markdown

Problem

The Duration.to_iso8601_string() method produces invalid ISO 8601 output for negative durations. For example:

Duration(days=-10).to_iso8601_string()   # returns '-P-10D' (invalid)
Duration(seconds=-10).to_iso8601_string() # returns '-PT-10S' (invalid)

The root cause is that individual component values (days, seconds, etc.) are negative, and the code also adds a - prefix, resulting in double negation in the output string.

This also causes data loss during model_copy(deep=True) since Pydantic serializes via to_iso8601_string() and the invalid string can't be properly deserialized.

Fixes #329

Fix

When the duration is negative, take absolute values of all components so the - prefix alone conveys the sign. The output is now valid ISO 8601:

Duration(days=-10).to_iso8601_string()   # returns '-P10D' ✓
Duration(seconds=-10).to_iso8601_string() # returns '-PT10S' ✓

Tests

Added 9 new tests covering:

  • Negative duration serialization round-trip (days, seconds, hours, weeks, months, years, combined)
  • Direct ISO 8601 string validation for negative durations

All 13517 tests pass (up from 13508).

…lues

The to_iso8601_string() method produced invalid ISO 8601 output for
negative durations (e.g., '-P-10D' instead of '-P10D'). This happened
because individual component values (days, seconds, etc.) were negative
while also being prefixed with '-'. Fixed by taking absolute values of
components when the duration is negative.

Fixes pydantic#329
@yezz123
yezz123 merged commit 7b75619 into pydantic:main Mar 22, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Data loss in pendulum_dt.Duration when using model_copy(deep=True)

3 participants