Skip to content

std.datetime.interval: add Interval.fromISOString for ISO 8601 interv… - #11090

Open
burner wants to merge 4 commits into
dlang:masterfrom
burner:iso8601_interval_parser
Open

std.datetime.interval: add Interval.fromISOString for ISO 8601 interv…#11090
burner wants to merge 4 commits into
dlang:masterfrom
burner:iso8601_interval_parser

Conversation

@burner

@burner burner commented Sep 3, 2026

Copy link
Copy Markdown
Member

…al parsing

Add Interval.fromISOString to parse ISO 8601 interval strings in both basic and extended formats. Supports:

  • start/end time points (e.g., '20030115/20030215', '2003-01-15/2003-02-15')
  • start/duration (e.g., '20030115/P1M', '2003-01-15/P1M')
  • duration/end (e.g., 'P1M/20030215', 'P1M/2003-02-15')

The parser handles both basic (YYYYMMDD) and extended (YYYY-MM-DD) formats, and correctly distinguishes months (in date portion) from minutes (in time portion after 'T'). Duration values accumulate as a Duration via dur!'unit' additions. As with the date and time types in std.datetime, each designator value is validated against the range which its unit can hold (hours at most TimeOfDay.maxHour, minutes/seconds at most 59, months at most 12, days at most 31), so larger spans must use the next larger designator (e.g., PT36H must be written P1DT12H).

Changelog: interval_fromisostring

Rationale

Feature request or issue tracking

Closes #10944

Pre-review checklist

  • I have performed a self-review of my code.
  • If my PR fixes a bug or introduces a new feature, I have added thorough tests.
  • If my changes are non-trivial and do not concern a reported issue, I have added a changelog entry.

LLM/AI disclosure

This PR was written mostly by an LLM/AI. But I had to change more things than I hoped for.

…al parsing

Add Interval.fromISOString to parse ISO 8601 interval strings in both basic
and extended formats. Supports:
- start/end time points (e.g., '20030115/20030215', '2003-01-15/2003-02-15')
- start/duration (e.g., '20030115/P1M', '2003-01-15/P1M')
- duration/end (e.g., 'P1M/20030215', 'P1M/2003-02-15')

The parser handles both basic (YYYYMMDD) and extended (YYYY-MM-DD) formats,
and correctly distinguishes months (in date portion) from minutes (in time
portion after 'T'). Duration values accumulate as a Duration via dur!'unit'
additions. As with the date and time types in std.datetime, each designator
value is validated against the range which its unit can hold (hours at most
TimeOfDay.maxHour, minutes/seconds at most 59, months at most 12, days at
most 31), so larger spans must use the next larger designator (e.g., PT36H
must be written P1DT12H).

Changelog: interval_fromisostring
@burner
burner requested a review from jmdavis as a code owner September 3, 2026 14:37
Comment thread changelog/interval_fromisostring.dd Outdated
@jmdavis

jmdavis commented Sep 3, 2026

Copy link
Copy Markdown
Member

I wasn't aware of ISO 8601 intervals, so I'll have to look into them to really comment on the details here. However, if there are both ISO and ISO extended strings, for consistency with the rest of std.datetime, fromISOString arguably should only handle ISO strings, and a fromISOExtString should handle ISO extended strings.

@burner

burner commented Sep 3, 2026

Copy link
Copy Markdown
Member Author

I wasn't aware of ISO 8601 intervals, so I'll have to look into them to really comment on the details here.

fair enough

However, if there are both ISO and ISO extended strings, for consistency with the rest of std.datetime, fromISOString arguably should only handle ISO strings, and a fromISOExtString should handle ISO extended strings.

I can make that change. I expected some pushback on the merging/branching of the two.

@Herringway

Copy link
Copy Markdown
Contributor

This does not fully address #10944, and should not close it. There must be a .toISO[Ext]String as well.

Add Interval.fromISOString and Interval.fromISOExtString to parse ISO 8601
interval strings in the basic and the extended format respectively, like
the fromISOString/fromISOExtString pairs of the other std.datetime types.
They support:
- start/end time points (e.g., '20030115/20030215', '2003-01-15/2003-02-15')
- start/duration (e.g., '20030115/P1M', '2003-01-15/P1M')
- duration/end (e.g., 'P1M/20030215', 'P1M/2003-02-15')

Both share a private parseISOInterval helper which splits the string on the
slash and delegates each time point to TP.fromISOString or
TP.fromISOExtString, so no format detection is needed.

Duration values accumulate as a Duration via dur!'unit' additions. As with
the date and time types in std.datetime, each designator value is validated
against the range which its unit can hold (hours at most TimeOfDay.maxHour,
minutes/seconds at most 59, months at most 12, days at most 31), so larger
spans must use the next larger designator (e.g., PT36H must be written
P1DT12H).

Changelog: interval_fromisostring
…rval types

Add Interval.toISOString and Interval.toISOExtString, which emit the begin
and end time points in the basic and the extended ISO 8601 format separated
by a slash. They round trip with fromISOString/fromISOExtString.

Per ISO 8601, an omitted time point means that it is unknown, so
PosInfInterval and NegInfInterval convert to '20030115/' and '/20030215'
respectively, and the corresponding fromISOString/fromISOExtString parse
those strings back.

Changelog: interval_fromisostring
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.

std.datetime.interval.Interval does not support ISO8601 representation

4 participants