zig icon indicating copy to clipboard operation
zig copied to clipboard

`std`: add generic `date.Date`, `time.Time`, and `date_time.DateTime`

Open clickingbuttons opened this issue 1 year ago • 8 comments

Add Date, Time, and DateTime structs with functions to convert to/from epoch subseconds and to add durations to them.

These types are based off generic types which let the user make their own tradeoffs between memory and precision.

  • Add std.Date, a Gregorian calendar date based off the Unix epoch.
  • Add std.Time, a time with second resolution.
    • You may create a Time type with arbitrary subsecond precision using std.time.TimeAdvanced(precision).
  • Add std.DateTime which contains a std.Date and std.Time.
  • Use new DateTime types in status quo.
    • UEFI
    • Certificate parsing
    • C date and time macros in aro/Compilation.zig

Potential future work:

  • Localization:
    • Parse /etc/localtime on Linux/OSX. Use GetTimeZoneInformation on Windows.
    • Conversion to arbitrary timezone by using timezone database on the user's system. These are rather large (440.7kb zipped, 2096kb unzipped). I do not think these qualify as "dependency zero" to be embedded with Zig. Related #14168.
  • RFC 3339 parsing + formatting.
  • ISO 8601 parsing + formatting.
  • Add leap second clock. Handle leap seconds using historical leap second table.

Closes #8396. Prior art #18272.

clickingbuttons avatar Apr 05 '24 17:04 clickingbuttons

I just now read https://github.com/ziglang/zig/pull/18272#issuecomment-1876648529 and would like to give an argument in favor of this change:

Date APIs are necessary for converting epoch timestamps to calendar dates and back. In addition to retrieving epoch seconds from a clock, the standard C library provides a struct tm that many programs rely on. I believe for Zig to compete with C it needs its own struct tm.

Zig is also already using 3 different versions of DateTime internally.

clickingbuttons avatar Apr 05 '24 17:04 clickingbuttons

The user would not need to bring their own time zone database (unless they are doing embedded development, in which case, they should be aware of the implementation details and bring their own), the OS does this. See https://github.com/ziglang/zig/issues/8396#issuecomment-2041134795.

notcancername avatar Apr 06 '24 16:04 notcancername

~~This CI error is a bit outside my comfort zone, but I'll try to tackle it:~~

lib/std/time.zig:379:13: error: TODO implement airWithOverflow from u8 to u17

Edit: Found workarounds. Opened #19606 and #19607.

clickingbuttons avatar Apr 08 '24 23:04 clickingbuttons

Now that RFC3339 parsing/formatting is removed, does it still satisfy the needs described here?

By the way, I don't see any problems down the line if datetime comes with a UTC offset field. This is the most basic information you need for timezone handling, while it does not carry any of the more complex details. Timezone rules exist independent of any date&time, however, when applied to a date&time, they result in just and offset, specific to that date&time. So since the offset is specific, I think it would actually help a timezone wrapper around this datetime implementation to do its job.

FObersteiner avatar Apr 10 '24 06:04 FObersteiner

Yes, it still satisfies the needs. The offset was added to aid the UEFI implementation, but that implementation can simply add the offset. The RFC 3339 implementation was just something I thought was nice to have and easy to add.

clickingbuttons avatar Apr 10 '24 23:04 clickingbuttons

The CI might get fixed by rebasing on master.

Vexu avatar Apr 11 '24 06:04 Vexu

The proposal this implements is not accepted.

I suggest to maintain a third party date/time Zig package, and then at some point you can suggest to upstream it if you wish.

Also Avoid Redundant Names in Fully-Qualified Namespaces

andrewrk avatar Apr 17 '24 19:04 andrewrk

The proposal this implements is not accepted.

A public (albeit inconvenient) implementation of Date already exists, so I considered the proposal at least partially accepted. Was #9040 was never meant to be public? https://github.com/ziglang/zig/blob/12191c8a220ca5594b278b5077bff98e8fecac08/lib/std/time/epoch.zig#L42-L186

I suggest to maintain a third party date/time Zig package, and then at some point you can suggest to upstream it if you wish.

zig zen reads:

  • Only one obvious way to do things.
  • Incremental improvements.

I believe this PR creates one obvious way of using Date and Time in the stdlib. Currently for contributors there are four: std.time.epoch.*, std.crypto.Certificate.Date, std.uefi.Time, or roll your own.

I consider this an incremental improvement to the existing std.time.epoch.* types. It fixes a bug in the UEFI implementation and improves performance of all 3.

Moving forward

If you believe this change goes too far beyond status quo I'm happy to leave #8396 open and remove the following:

  • fn adds.
  • Hardcode Year = i16.
  • Remove Time.subseconds or hardcode to nanosecond for UEFI.

Those changes will likely make this PR a net negative in terms of LOC and offer no additional functionality than what's already in std.time.epoch.*.

clickingbuttons avatar Apr 17 '24 22:04 clickingbuttons

It's with great sorrow I publish yet another datetime library.

I really hope the stdlib will have general purpose date and time parsing upon 1.0.0.

clickingbuttons avatar Apr 27 '24 01:04 clickingbuttons