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

[SUGGESTION] Support decoding ISO8601 dates with fractional seconds #323

Open
BrentMifsud opened this issue Nov 18, 2023 · 9 comments
Open
Assignees

Comments

@BrentMifsud
Copy link

BrentMifsud commented Nov 18, 2023

I know that date formatters have not been implemented here just yet, but I would like to bring light to this issue that has existed in the original foundation for quite some time.

Essentially, by default, ISO8601DateFormatters fail to parse valid ISO8601 dates when there are fractional seconds present. You can fix this by adding the .withFractionalSeconds option. But in some cases, this isn't possible.

For example:

I noticed this issue recently in my own codebase where we were using the .iso8601 JSON date decoding strategy. We got around this by creating a custom date decoding strategy. But it would be nice if we didn't have to do this.

It would be nice to have this fixed in Swift Foundation.

@BrentMifsud BrentMifsud changed the title [SUGGESTION] Old Foundation ISO8601DateFormatters fails to parse dates with fractional seconds [SUGGESTION] Support decoding ISO8601 dates with fractional seconds Nov 18, 2023
@itingliu
Copy link
Contributor

Currently .withFractionalSeconds requires the string to contain fractional seconds, and decoding would fail if it doesn't. Just as a general survey -- Do all strings contain fractional seconds, or some of them do and some of them don't?

@Craz1k0ek
Copy link

Just as a general survey -- Do all strings contain fractional seconds, or some of them do and some of them don't?

This shouldn't affect the implementation, as the ISO 8601 standard clearly defined a way to have reduced precision by omitting values.

For a starter it would be nice if the existing implementation would be renamed to RFC 3339, which it appears to be, and the requested behaviour would be correctly implemented as the ISO 8601 standard.

@hassila
Copy link
Contributor

hassila commented Feb 8, 2024

I'd also like to add that it would be fantastic if the formatter can support precision all the way down to nanoseconds, which is practically useful for some domains (e.g. financial transaction timestamps can have that).

@Playrom
Copy link

Playrom commented Mar 11, 2024

As stated in the RFC https://www.rfc-editor.org/rfc/rfc3339#page-8 , at page 7 , "Internet Date/Time Format"

The fractional part of the second is optional (time-secfrac between square parenthesis). The foundation implementation, when setting "withFractionalSeconds", should correctly parse a string with or without the fractional part

This "forcing" behaviour is creating a lot of headaches In the current foundation library, and I think It would be helpful to have a change (which is additive, not breaking compatibilty) in the new swift-foundation!

I would propose myself a PR but checking the current source code I'm not so confident in writing a code that is fast enough to be placed in this part of the library (ICUFoundation is using pointers and direct string access)

@itingliu
Copy link
Contributor

We can't change the behavior of Date.ISO8601FormatStyle or ISO8601DateFormatter so that withFractionalSeconds parses both strings with and without the fractional seconds if the current behavior requires strict matching.

We can consider having a separate option, say, lenientFractionalSecond instead. If anyone has any good ideas about enabling this while being compatible with the existing behavior, I think we'll all be very glad to see a pitch to kick off the discussion

@hassila
Copy link
Contributor

hassila commented Mar 11, 2024

Is a pitch really needed to adopt correct iso8601 behavior? (I can see the need to discuss what is a good implementation though :-)

@itingliu
Copy link
Contributor

My point was that we can't simply "fix this bug" by changing the behavior. It's important to maintain compatibility for clients who are relying on the current strict behavior.

So the only option we have is to add a different configuration, which by its nature would be an API, hence the need for a pitch

@Playrom
Copy link

Playrom commented Mar 11, 2024

@itingliu I see your point, you are right
Honestly I thought that being this rewrite not "just a port" some changes on the api may be possible, but if strict compatibility is necessary your approach of a lenientFractionalSecond it appears the way to go!

@BrentMifsud
Copy link
Author

BrentMifsud commented Mar 12, 2024

I like the idea of a lenientFractionalSeconds option. I'd like to propose an additional option: .replacingMissingTimeValues

This will automatically populate time, fractional seconds, and time zone with a safe default when constructing a date from a string if those values are missing.

For example if the time zone is missing, use UTC. If fractional seconds are missing, use .000, if time is missing, use 00:00:00.

Obviously you can't really do this for missing year month or day, but it will prevent failures when your date string is missing some of the time values.

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

No branches or pull requests

5 participants