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

feature request: week number formatting support in strftime #147

Open
LeoniePhiline opened this issue Oct 30, 2024 · 6 comments
Open

feature request: week number formatting support in strftime #147

LeoniePhiline opened this issue Oct 30, 2024 · 6 comments
Labels
breaking change Issues that require a breaking change for resolution. enhancement New feature or request

Comments

@LeoniePhiline
Copy link
Contributor

While looking to replace chrono with jiff in code where date formats are passed in from configuration, I realized I could not yet perform the full migration:

jiff does not yet provide formatting of zoned or civil date-time objects as week number in ISO 8601 week date (01–53, zero-padded).

chrono supports this as %V, among other week number formats (%U, %W).

chrono::format::strftime matches GNU coreutils DATE(1) (e.g. date +%V), which is very convenient when modernizing software.

Is there any chance jiff would ever change its existing %V (IANA time zone identifier) to a different specifier to allow for coreutils and chrono compatible specifiers?

Is the implementation of week number and week year formatting specifiers a feature that might be added to jiff?

@BurntSushi
Copy link
Owner

The %V being for IANA time zone identifiers comes from java.time: https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html

I don't think that will change personally. Particularly since I see %V as being more important/broadly applicable than ISO 8601 week dates. Chrono itself doesn't have first class support for IANA time zone identifiers (you need to reach out to chrono-tz or tzfile for that), so it makes sense that it wouldn't have an analog.

More generally, full compatibility with other strtime APIs is pretty hard. There's no one featureful spec, and like regex engines, each implementation has their own little quirks and features with little hope for unification. I did of course try to be compatible where I could, but I think given how strtime works (a bunch of overly terse letter modifiers), there's just always going to be points where it doesn't fully line up with other implementations.

As far as supporting ISO 8601 week dates in strtime, yes, absolutely, 100% I want to do that. I just didn't do it initially because I wasn't sure about the use case. Given that %V is already taken, what modifier do you think Jiff should use?

@BurntSushi BurntSushi added the enhancement New feature or request label Oct 30, 2024
@LeoniePhiline
Copy link
Contributor Author

LeoniePhiline commented Oct 30, 2024

As always, thank you for your considerate and detailed response!

The %V being for IANA time zone identifiers comes from java.time: https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html

Interesting. This reminds me of old times with PHP, where DateTime::format uses different specifiers than strftime - and no % sigil.

Java does not use % sigils either and appears uninterested in strftime compatibility.

However, jiff appears to chosen a different approach, with %V seemingly being its only incompatibilty.

Since jiff explicitly names its parsing and formatting strptime and strftime and uses % sigils, wouldn't it rather align itself with libc's strftime, than with Java?

As far as supporting ISO 8601 week dates in strtime, yes, absolutely, 100% I want to do that. I just didn't do it initially because I wasn't sure about the use case.

That sounds fantastic!

Given that %V is already taken, what modifier do you think Jiff should use?

Looking for gaps in jiff::fmt::strtime specifiers which do not clash with date(1)/strftime(3):

  • %U and %W are still free for legacy (non-ISO) week numbers compatible with libc's strftime(3), date(1) and chrono::format::strftime.

  • %Q is still free in jiff and unused in date(1) and chrono::format::strftime. Thus, %Q seems like a good candidate to replace %V in jiff for "ISO week number, with Monday as first day of week (01..53)".

  • %G is still free in jiff and may be used to implement %G "year of ISO week number (see %V); normally useful only with %V" which, in jiff would be associated with %Q. (date +%G-W would correspond to jiff's %G-%Q).

While %U, %W and %G can be added in a strftime(3)-compatible fashion, %Q in place of %V would remain forever incompatible.

May I be so bold and try to convince you that for jiff it might still be early enough for a breaking change of this kind:

  • changing the existing %V (IANA time zone) to %Q (which is unused in other %-sigil based formatters)
  • and implementing ISO week number formatting at %V?

The next semver-breaking version might move %V to %Q and free up %V.

A later (not necessarily semver-breaking) version may then add %U and %W, covering legacy week numbers, as well as %G and %V, covering ISO week numbers in a strftime(3)1 compatible fashion.

To my mind, the cost of such a breaking change is still small. At a later point, jiff might be stuck with an incompatibility that in hindsight should have been removed early on.

Of course, I am not in your shoes and this is merely my humble assessment of the situation and the options at hand.

Footnotes

  1. This trivially implies date(1) and chrono compatibility, which implement the mentioned specifiers the same way.

@BurntSushi
Copy link
Owner

If I were convinced it was the right way to go, I wouldn't mind doing the breaking change. The fact that it's breaking isn't really what gives me pause. I just think it's better to have IANA time zone identifiers match an existing convention (from java.time) than it is for ISO 8601 week dates to match. It's true that Java doesn't provide strftime, but the same spirit of single letter modifiers (with repetitions being significant) is still there.

wouldn't it rather align itself with libc's strftime

I wouldn't, no. At least, not from any rigorous perspective. There are lots of incompatible strtime APIs out there.

I'll think on this.

@LeoniePhiline
Copy link
Contributor Author

Thank you very much for your consideration!

@BurntSushi
Copy link
Owner

Given the discussion in #197, I'm leaning towards making a breaking change in jiff 0.2 here that improves compatibility with strftime(3). I'm kinda annoyed by this, particularly since this is a breaking change in runtime behavior, but I think it's probably the right call.

So we need to pick a different conversion specific for an IANA time zone identifier. I'm not sure there is much prior art here. I don't think I know of any other strftime or strptime implementation that supports IANA time zone identifiers.

@BurntSushi BurntSushi added the breaking change Issues that require a breaking change for resolution. label Jan 18, 2025
@BurntSushi
Copy link
Owner

I think the available choices, for capital letters at least, for a %V replacement are: J K L N Q. I checked both GNU's strftime and Python's strftime, and neither seem to use any of these letters. Are there other prominent strftime implementations we should check?

I feel like none of the letter really fit, which means the choices is probably down to compatibility. And if that's not discriminatory (which it appears not), then I guess it's pretty arbitrary. %Q seems as good as any other I suppose.

BurntSushi added a commit that referenced this issue Jan 18, 2025
And similarly, deprecate `%:V` in favor of `%:Q`.

This was regretably done to improve compatibility with other strtime
implementations. In particular, `%V` will, in `jiff 0.2`, correspond to
an ISO 8601 week number. This matches other `strftime` and `strptime`
implementations, such as GNU's.

Ref #147
BurntSushi added a commit that referenced this issue Jan 21, 2025
And similarly, deprecate `%:V` in favor of `%:Q`.

This was regretably done to improve compatibility with other strtime
implementations. In particular, `%V` will, in `jiff 0.2`, correspond to
an ISO 8601 week number. This matches other `strftime` and `strptime`
implementations, such as GNU's.

Ref #147
BurntSushi added a commit that referenced this issue Jan 21, 2025
This adds a whole bunch of conversion specifiers from reading
`man strftime` on my system (GNU libc).

I originally didn't add most of these because they bloat the size of
`BrokenDownTime` and many of them seem a little dubious. But a few folks
have filed issues about compatibility. Given the `strtime` API is
already a complete clusterfuck, it probably makes sense to just match
existing practice as much as we can.

One conversion specifier I intend to add but haven't yet is `%V` for the
ISO 8601 week number. It is conspicuously absent here since `%V` is
currently used for IANA time zone identifiers. That will change in
`jiff 0.2`, which will make room for `%V` to be the ISO 8601 week
number.

Ref #147
BurntSushi added a commit that referenced this issue Jan 21, 2025
This adds a whole bunch of conversion specifiers from reading
`man strftime` on my system (GNU libc).

I originally didn't add most of these because they bloat the size of
`BrokenDownTime` and many of them seem a little dubious. But a few folks
have filed issues about compatibility. Given the `strtime` API is
already a complete clusterfuck, it probably makes sense to just match
existing practice as much as we can.

One conversion specifier I intend to add but haven't yet is `%V` for the
ISO 8601 week number. It is conspicuously absent here since `%V` is
currently used for IANA time zone identifiers. That will change in
`jiff 0.2`, which will make room for `%V` to be the ISO 8601 week
number.

Ref #139, Ref #147
BurntSushi added a commit that referenced this issue Jan 21, 2025
And similarly, deprecate `%:V` in favor of `%:Q`.

This was regretably done to improve compatibility with other strtime
implementations. In particular, `%V` will, in `jiff 0.2`, correspond to
an ISO 8601 week number. This matches other `strftime` and `strptime`
implementations, such as GNU's.

Ref #147
BurntSushi added a commit that referenced this issue Jan 21, 2025
This adds a whole bunch of conversion specifiers from reading
`man strftime` on my system (GNU libc).

I originally didn't add most of these because they bloat the size of
`BrokenDownTime` and many of them seem a little dubious. But a few folks
have filed issues about compatibility. Given the `strtime` API is
already a complete clusterfuck, it probably makes sense to just match
existing practice as much as we can.

One conversion specifier I intend to add but haven't yet is `%V` for the
ISO 8601 week number. It is conspicuously absent here since `%V` is
currently used for IANA time zone identifiers. That will change in
`jiff 0.2`, which will make room for `%V` to be the ISO 8601 week
number.

Ref #139, Ref #147
BurntSushi added a commit that referenced this issue Jan 25, 2025
This officially drops the deprecated behavior of `%V`, which
corresponded to an IANA time zone identifier. This was done to improve
compatibility with other `strftime` and `strptime` implementations, such
as the one found in GNU libc.

Fixes #147
BurntSushi added a commit that referenced this issue Jan 25, 2025
This officially drops the deprecated behavior of `%V`, which
corresponded to an IANA time zone identifier. This was done to improve
compatibility with other `strftime` and `strptime` implementations, such
as the one found in GNU libc.

Fixes #147
BurntSushi added a commit that referenced this issue Jan 25, 2025
This officially drops the deprecated behavior of `%V`, which
corresponded to an IANA time zone identifier. This was done to improve
compatibility with other `strftime` and `strptime` implementations, such
as the one found in GNU libc.

Fixes #147
BurntSushi added a commit that referenced this issue Jan 27, 2025
This officially drops the deprecated behavior of `%V`, which
corresponded to an IANA time zone identifier. This was done to improve
compatibility with other `strftime` and `strptime` implementations, such
as the one found in GNU libc.

Fixes #147
BurntSushi added a commit that referenced this issue Jan 30, 2025
This officially drops the deprecated behavior of `%V`, which
corresponded to an IANA time zone identifier. This was done to improve
compatibility with other `strftime` and `strptime` implementations, such
as the one found in GNU libc.

Fixes #147
BurntSushi added a commit that referenced this issue Feb 1, 2025
This officially drops the deprecated behavior of `%V`, which
corresponded to an IANA time zone identifier. This was done to improve
compatibility with other `strftime` and `strptime` implementations, such
as the one found in GNU libc.

Fixes #147
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change Issues that require a breaking change for resolution. enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants