Skip to content

ZmanimFormatter.formatXSDDurationTime: valid xsd:duration for negative durations - #301

Merged
KosherJava merged 1 commit into
KosherJava:masterfrom
Elyahu41:fix/xsd-negative-duration
Nov 6, 2026
Merged

KosherJava merged 1 commit into
KosherJava:masterfrom
Elyahu41:fix/xsd-negative-duration

Conversation

@Elyahu41

@Elyahu41 Elyahu41 commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

The issue

ZmanimFormatter.formatXSDDurationTime(Duration) is documented to return an xsd:duration, but for negative durations it returns a string that isn't a valid xsd:duration.

The edge case

Any negative Duration. For example:

  • Duration.ofMinutes(-75) passed directly.
  • A sha'ah zmanis whose start is after its end, such as a polar day or odd custom zmanim.
  • A negative offset formatted with format() when the formatter uses XSD_DURATION_FORMAT, which toXML() / toJSON() do.

What happens

The method returns Duration.toString(), and Java writes a negative duration with a sign on every field:

new ZmanimFormatter(ZoneId.of("UTC")).formatXSDDurationTime(Duration.ofMinutes(-75).minusSeconds(3));
// "PT-1H-15M-3S"

XML Schema (and ISO 8601) allows only one sign, in front of the whole value: -PT1H15M3S. So the output is rejected by javax.xml.datatype.DatatypeFactory.newDuration, by schema validation, and by other XSD / ISO 8601 parsers (for example .NET's XmlConvert.ToTimeSpan).

The fix

For a negative duration, return "-" + duration.negated().toString(). Zero and positive durations are unchanged.

Tests

ZmanimFormatterXsdDurationTest checks:

  • Positive durations, zero and null are unchanged.
  • -PT1H15M3S and -PT0.5S for negative durations, and that the result round-trips through DatatypeFactory.newDuration to the same value.
  • format() with XSD_DURATION_FORMAT gives -PT30M.

The negative cases fail without the fix.


🤖 Generated with Claude Code

https://claude.ai/code/session_015Er4Sx7LnKzzCbgDEatxkU

…lid xsd:duration

Duration.toString() writes a negative duration as "PT-1H-15M-3S", which isn't
a valid xsd:duration (XSD only allows one leading sign: "-PT1H15M3S"). This
also affected format() with XSD_DURATION_FORMAT and the durations in toXML()
/ toJSON().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Er4Sx7LnKzzCbgDEatxkU
@KosherJava
KosherJava merged commit 24d29fb into KosherJava:master Nov 6, 2026
3 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.

2 participants