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

Fix incorrect datetime string generation in NSISO8601DateFormatter #339

Closed

Conversation

kevinpeizner
Copy link

By default, the NSISO8601DateFormatter uses the
NSISO8601DateFormatWithInternetDateTime formatting:

https://github.com/gnustep/libs-base/blob/master/Headers/Foundation/NSISO8601DateFormatter.h#L57

This equates to these format options:

NSISO8601DateFormatWithYear |
NSISO8601DateFormatWithMonth |
NSISO8601DateFormatWithDay |
NSISO8601DateFormatWithDashSeparatorInDate |

NSISO8601DateFormatWithTime |
NSISO8601DateFormatWithColonSeparatorInTime |
NSISO8601DateFormatWithTimeZone |
NSISO8601DateFormatWithColonSeparatorInTimeZone

The last option (NSISO8601DateFormatWithColonSeparatorInTimeZone) causes the formatter to append "ZZ:ZZ" to the formatting string. But ZZ maps to a timezone like this: "-0800" according to the ICU documentation:
https://unicode-org.github.io/icu/userguide/format_parse/datetime/#date-field-symbol-table

The full format string that GNUStep puts together with the above options is:

"yyyy-MM-dd'T'HH:mm:ssZZ:ZZ"

As a result, "ZZ:ZZ" will always translate to something like:

"-0800:-08:00"

"ZZ:ZZ" should be "ZZZZZ" which is would output the timezone offset once with the : separator between hours and minutes.

"yyyy-MM-dd'T'HH:mm:ssZZZZZ" is also the same format string used in Apple's implementation according to their documentation: https://developer.apple.com/documentation/foundation/nsiso8601dateformatter/1643114-init

By default, the NSISO8601DateFormatter uses the
NSISO8601DateFormatWithInternetDateTime formatting:

https://github.com/gnustep/libs-base/blob/master/Headers/Foundation/NSISO8601DateFormatter.h#L57

This equates to these format options:
```
NSISO8601DateFormatWithYear |
NSISO8601DateFormatWithMonth |
NSISO8601DateFormatWithDay |
NSISO8601DateFormatWithDashSeparatorInDate |

NSISO8601DateFormatWithTime |
NSISO8601DateFormatWithColonSeparatorInTime |
NSISO8601DateFormatWithTimeZone |
NSISO8601DateFormatWithColonSeparatorInTimeZone
```

The last option (`NSISO8601DateFormatWithColonSeparatorInTimeZone`)
causes the formatter to append "ZZ:ZZ" to the formatting string. But ZZ
maps to a timezone like this: “-0800" according to the ICU
documentation:
https://unicode-org.github.io/icu/userguide/format_parse/datetime/#date-field-symbol-table

The full format string that GNUStep puts together with the above
options is:

"yyyy-MM-dd'T'HH:mm:ssZZ:ZZ"

As a result, "ZZ:ZZ" will always translate to something like:

“-0800:-0800”

"ZZ:ZZ" should be "ZZZZZ" which is would output the timezone offset
once with the `:` separator between hours and minutes.

"yyyy-MM-dd'T'HH:mm:ssZZZZZ" is also the same format string used in
Apple's implementation according to their documentation:
https://developer.apple.com/documentation/foundation/nsiso8601dateformatter/1643114-init
@kevinpeizner kevinpeizner requested a review from rfm as a code owner October 26, 2023 00:18
@kevinpeizner kevinpeizner changed the title Fix incorrect formatting in NSISO8601DateFormatter Fix incorrect datetime string generation in NSISO8601DateFormatter Oct 27, 2023
@hmelder
Copy link
Contributor

hmelder commented Nov 11, 2023

Looks good to me! It would be nice to have a test for this :)

But I can write one as well.

@rfm what do you think?

@rfm
Copy link
Contributor

rfm commented Nov 14, 2023

I made a fix and added testcases based on this report a while back, but forgot about it.
Sorry about forgetting, but the current code in git master should be correct.

@rfm rfm closed this Nov 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants