`std`: add generic `date.Date`, `time.Time`, and `date_time.DateTime`
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.toEpochandfromEpochimplemented using state of the art Euclidean Affine Functions (EAFs) by Neri and Schneider.- You may create your Gregorian date type with a larger year range or a different epoch using
std.date.gregorian.Date(YearType, epoch_days_since_1970_01_01).
- Add
std.Time, a time with second resolution.- You may create a Time type with arbitrary subsecond precision using
std.time.TimeAdvanced(precision).
- You may create a Time type with arbitrary subsecond precision using
- Add
std.DateTimewhich contains astd.Dateandstd.Time. - Use new
DateTimetypes in status quo.- UEFI
- Certificate parsing
- C date and time macros in
aro/Compilation.zig
Potential future work:
- Localization:
- Parse
/etc/localtimeon Linux/OSX. UseGetTimeZoneInformationon 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.
- Parse
- 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.
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.
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.
~~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.
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.
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.
The CI might get fixed by rebasing on master.
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.
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.subsecondsor hardcode tonanosecondfor 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.*.
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.