Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expose a "broken down" representation of parsing a Temporal ISO 8601 datetime #188

Closed
BurntSushi opened this issue Jan 1, 2025 · 2 comments · Fixed by #193
Closed

expose a "broken down" representation of parsing a Temporal ISO 8601 datetime #188

BurntSushi opened this issue Jan 1, 2025 · 2 comments · Fixed by #193
Labels
enhancement New feature or request

Comments

@BurntSushi
Copy link
Owner

BurntSushi commented Jan 1, 2025

This has come up a few times in one form or another, but it basically boils down to the fact that if you're given something like 2024-08-24T14:00:00-05, then there's no easy way to get access to the -05 offset. You can do it with strptime APIs, but it's not obvious. And in particular, going that route means abandoning the Temporal ISO 8601 datetime parser, which is a fair bit more flexible (and has a specification). Trying to re-create that with strptime is annoying and probably impossible.

So, I think supporting this use case should be possible. But we don't want to make it work without an explicit opt-in, since (as is done today), Jiff will prevent you from parsing a 2024-08-24T14:00:00-05 directly into a Zoned, even though a Zoned can have a fixed offset time zone. The reason is that it's often a mistake to do so, since the resulting Zoned won't do DST safe arithmetic. This issue on the Temporal tracker goes into this in more depth.

One way of supporting this is by permitting the offset to be parsed via a config knob on jiff::fmt::temporal::DateTimeParser. But I think a better approach is to expose a new parsing routine that returns a "parse result" indicating the components that were parsed from the string. That is strictly more flexible and might unlock some other use cases. Notably, using the Temporal ISO 8601 datetime parser currently requires one to ask for what they need. But this new API should let them parse and then inspect what was given.

See also:

@BurntSushi BurntSushi added the enhancement New feature or request label Jan 1, 2025
BurntSushi added a commit that referenced this issue Jan 2, 2025
This somewhat revives #22, but makes it possible to restore the previous
behavior by enabling `jiff::fmt::temporal::SpanPrinter::lowercase`.

The main motivation here is also detailed in #22, and it came up again
in #188. I was previously reluctant to do this because I find
`P1Y2M3DT4H5M6S` hideously difficult to read and `P1y2m3dT4h5m6s`
somewhat less difficult to read. But now that `jiff::fmt::friendly` is a
thing and users have easy access to a more readable duration display
format, I feel less bad about this. It's still a shame that it's the
default via `span.to_string()`, but I tried to sprinkle a few
`format!("{span:#}")` in places to nudge users toward the friendly
format.

It's a shame more systems don't accept lowercase unit designator labels,
but since Jiff uses the ISO 8601 by default specifically for its
interoperability, it makes sense to be as interoperable as we can by
default.

Fixes #188
BurntSushi added a commit that referenced this issue Jan 2, 2025
This somewhat revives #22, but makes it possible to restore the previous
behavior by enabling `jiff::fmt::temporal::SpanPrinter::lowercase`.

The main motivation here is also detailed in #22, and it came up again
in #188. I was previously reluctant to do this because I find
`P1Y2M3DT4H5M6S` hideously difficult to read and `P1y2m3dT4h5m6s`
somewhat less difficult to read. But now that `jiff::fmt::friendly` is a
thing and users have easy access to a more readable duration display
format, I feel less bad about this. It's still a shame that it's the
default via `span.to_string()`, but I tried to sprinkle a few
`format!("{span:#}")` in places to nudge users toward the friendly
format.

It's a shame more systems don't accept lowercase unit designator labels,
but since Jiff uses the ISO 8601 by default specifically for its
interoperability, it makes sense to be as interoperable as we can by
default.

Fixes #188
@fbstj
Copy link

fbstj commented Jan 2, 2025

I believe you meant #190 rather than this in #191 ?

@BurntSushi
Copy link
Owner Author

Gah, yup! Thank you!

@BurntSushi BurntSushi reopened this Jan 2, 2025
BurntSushi added a commit that referenced this issue Jan 4, 2025
This commit adds a new type to the `jiff::fmt::temporal` module that
exposes the raw components of a parsed Temporal ISO 8601 datetime
string.

This is meant to address use cases that need something a bit more
flexible than what is provided by the higher level parsing routines.
Namely, the higher level routines go out of their way to stop you from
shooting yourself in the foot. For example, parsing into a `Zoned`
requires a time zone annotation.

But parsing into a `Pieces` doesn't require any of that. It just has
to match the Temporal ISO 8601 grammar. Then you can mix and match
the pieces in whatever way you desire. And indeed, you can pretty
easily shoot yourself in the foot with this API. I feel okay about this
because it's tucked into a corner of Jiff that you specifically have to
seek out to use. I've also included examples in the docs of _how_ you
can easily shoot yourself in the foot.

I've included a couple case studies in the docs reflecting some real
world examples I've come across in the issue tracker.

Ref #112, Ref #181, Closes #188,
Ref tc39/proposal-temporal#2930
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants