BurntSushi / jiff

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

export `TimeZone` to TZif #30

Open scottlamb opened 3 months ago

scottlamb commented 3 months ago

I'd like a method, say jiff::tz::TimeZone::to_tzif, that exports a time zone to TZif, much like jiff::tz::TimeZone::tzif imports a time zone from TZif.

This is by no means urgent as (a) I just heard about jiff and haven't even switched my project to it yet, and (b) I need some Typescript-side functionality to make use of it anyway (likely glue for using MUI's pickers with Temporal + a Temporal TimeZone subclass that imports from user-supplied TZif). But I'm firmly convinced this is useful functionality, and here's why:

My project moonfire-nvr is a server/client deal with a web interface. As it's focused on what's happening physically near the server, it describes time in terms of the server's time zone, regardless of where the user currently is. E.g., if I'm traveling in another time zone, and I'm looking at my home NVR, I still want "midnight" to mean "midnight at home", not "midnight where I am now". Event times are stored in simple machine-centered terms (x fractions of a second since epoch) but the Rust-based server also keeps indices by calendar day (x minutes of total video, x minutes of activity, x discrete events, etc. for this day) so that the client can load immediately with a hint of what happened on those days for general awareness and navigation. The Typescript/React/MUI/...-based client does (and will do) more of the interesting time zone stuff like selecting the start and end of a time range in human-centered terms and rendering a scrub bar with times on it. It's important that the client can translate between machine and human times rapidly (without a round trip) and consistently with the server. I'm currently doing this by communicating the IANA time zone name, but there's no guarantee the server and client actually match in how up-to-date their zone definitions are and such, and the UI experience falls apart when they don't do the calculations in the same way.

Thus I'd like the server to convey the actual TZif-based zone, and the client to load that definition and use it for its calculations.

I expect there are other projects in the same boat where they want a client to be able to accurately perform local operations on a notion of time zone conveyed from the server.

BurntSushi commented 3 months ago

I think this is probably mostly blocked on #20, although perhaps not entirely. #20 technically doesn't need to get TZif data itself to be useful, since it could just represent time zone transitions in memory. But an actual port of zic would enable the use case you describe, in addition to jiff-cli being able to compile its own TZif data without relying on zic. (I don't know if that's a huge benefit or not though.)

I'm still not sold on this however. It seems like there ought to be other ways of achieving your same goal here without needing Jiff to write raw TZif data. For example, why can't you have a check that ensures your tzdb copies are identical on client and server? Or you could make it true by construction by embedding tzdb into both the client and server so that you know all IANA tz identifiers always point to the same binary data.

scottlamb commented 3 months ago

It seems like there ought to be other ways of achieving your same goal here without needing Jiff to write raw TZif data. For example, why can't you have a check that ensures your tzdb copies are identical on client and server? Or you could make it true by construction by embedding tzdb into both the client and server so that you know all IANA tz identifiers always point to the same binary data.

Fair point; a few alternatives:

BurntSushi commented 3 months ago

I think we should find a way to do this. But I would like the zic compiler infrastructure to exist first to make this work. Which, I think, will unlock other benefits. Such as making the embedded tzdb for, e.g., Windows, be much smaller.