BurntSushi / jiff

A date-time library for Rust that encourages you to jump into the pit of success.
The Unlicense
1.74k stars 33 forks source link

locale support #4

Open BurntSushi opened 7 months ago

BurntSushi commented 7 months ago

In the course of developing Jiff, I have paid almost no attention to locale support. This is in part due to my awareness of the difficulty of the task, and also because Temporal largely ignores locale as well. (With the exception of toLocaleString methods on each of Temporal's data types. But as I understand it, those routines are the responsibility of another tc39 design proposal.) Indeed, at present, there really isn't much room for injecting locale into Jiff since all of the datetime string formats supported are "machine" readable interchange formats (that also happen to be human readable and writable). Like, you don't apply locale to things like 2024-07-06T17:46:00-04[America/New_York] because those aren't meant to be read by end users. The time zone might look like something that is amenable to localization, but the time zone is actually an identifier, not an end user facing message (even if some applications might use a time zone ID as an end user facing description of a time zone).

However, I do plan to add strftime and strptime support. And I'd like to add RFC 2822 support as well. I haven't read RFC 2822 yet, but my understanding is that it falls in the "machine readable" bucket even though it uses the English language names for months. As for strftime, I think I would like it to be very specifically limited to English as a best effort sort of thing.

Because localization is not a domain I am familiar with, and because I am at least aware that it is very challenging to get right, here are my current thoughts:

  1. I would like for Jiff to not deal with localization at all.
  2. I would like to suggest that folks use the icu crate for localization, although I do not at present (2024-07-07) have a full understanding of its capabilities in this space.
  3. If a domain expert in localization helped educated me on something small and correct that Jiff could do to help with the localization use case, I would be open to that. My understanding though is that such a thing ("small and correct") does not exist.
  4. My expectation is that Jiff exposes whatever is needed to do localization external to Jiff. If this is not true, I think we should fix that. I certainly do not want to impede localization efforts.
workingjubilee commented 3 months ago

From my experience in localization, I believe you are correct on 3 ("no small fixes exist"), and that any form of 3 will look more like 4 ("make it easier to localize"). Those that have done significantly more directions than across a few languages may have different opinions.

My impression is that because of the joy of :musical_note:orphan rules:musical_note: it may be most convenient if jiff implements icu::datetime::input (behind a feature flag, ofc).

BurntSushi commented 3 months ago

Yeah, I just struggle with putting crates as public dependencies that may make breaking changes in the not-too-distant future. It's fine now because I'll likely be doing breaking change releases of Jiff, but in about ~1 year (I hope), I want to effectively stop doing breaking releases and stabilize. Then what happens if an icu 2.0 comes out?

I did speak to @sffc about this a little, and it seemed like maybe icu could take a dependency on Jiff here, but that also to be honest seems wrong to me. I suppose the only other option in a separate crate with adapter types, which is kinda lame. But if we give it some good docs, it might be good enough. I'm not sure. I'll have to actually play with those icu APIs.

sffc commented 3 months ago

Jiff serves an important use case involving datetime representation and manipulation. Localized formatting of the datetimes is almost entirely a separable concern for a separate crate, except in the one specific case of date arithmetic with months and years (for example, add 1 month or add 1 year to this date), which is why ECMAScript Temporal has the calendar system in its data model.

Therefore, a reasonable path for Jiff to take would be to recommend that clients use another crate, such as icu, for the display of datetimes to humans, and add caveats in all arithmetic functions (add, subtract, difference, round) that they should be used in Gregorian-only situations.

I would recommend against strftime-like functionality. This type of function is the anti-pattern of good localization: at best, it lets you print datetimes styled for a specific language and region, but even in English, this fails to produce dates in a human-readable format given differences between US and Europe date formats, for example. There are only two ways that dates should be formatted for human consumption:

  1. For general-purpose human-readable formatting: use ICU4X or another locale-aware formatting library.
  2. For a tech-savvy audience: use ISO-8601 / IXDTF strings.

I'm happy to discuss more about how we could improve interop between icu and `jiff``.

BurntSushi commented 3 months ago

RE strftime: Yeah, that's why I document it as being a utility tool that doesn't support localization. So like, yes, it shouldn't be used. But also, it's too useful of a tool to not have. strftime/strptime was a late addition to Jiff. In the run up to the release, I started porting code from Chrono to Jiff, and I basically immediately ran into a problem where I needed strptime (or something equivalent) because some XML data file didn't use a standardized datetime format. strftime is useful for the dual reason: to write in a non-standardized datetime format. But otherwise, yes, I absolutely agree with the spirit of what you're saying.

But okay, I think the next step for me is to sink some time into learning icu's API so I can better understand what our choices are here.

except in the one specific case of date arithmetic with months and years (for example, add 1 month or add 1 year to this date), which is why ECMAScript Temporal has the calendar system in its data model.

I did not know this!

workingjubilee commented 2 months ago

Yeah, strftime-like APIs are the things where you kinda do want them but also you aaalmost kinda want to put them behind something like

/// Please avoid this if you can find any other way.
pub mod dont;

or just in general trying to be careful to not make the DX of using it better than the DX of using the actual localization API people are supposed to be using, and unfortunately those often feel a bit clunky because humanity is a bit clunky.