hybrid approach: datetime combines incremental and field based representation (Unix time, year, month, etc. fields)
relatively simple concept for time zone type (IANA-db file and/or offset from UTC)
uses the TZif parser from the Zig standard library
This post is sort of a follow-up to What’s the state of datetime in Zig?. I’m happy that writing a library to handle datetime with time zones worked out well, Zig is fun to code in and its context (the community etc.) is nice. The goal for zdt is “exploration”, not to build something according to some spec. There’s probably a lot to do better, and a lot of edge cases to catch.
Some context; the proposal to add datetime functionality to the Zig standard lib is still open. There also has been a pull request, which is now closed (2024-01-08).
That’s cool. Things like date time are so complex that some people find unattractive, but so fundamental that we need them for any mundane work.
Last time I wanted a decent date time library with Zig, I reached out for a very crude solution with strftime attached with a microsecond timestamp (as Python did). I believe established Zig users such as Bun and Tigerbeetle have their own implementation, too, but there seems not to be a standalone excerpt anyway.
Thanks! Yeah there’s a couple of related projects out there, I’ve collected a few in the misc/advanced document in the docs. I think it is perfectly fine to make a case-specific date/time implementation; that’s part of Zig’s philosophy I guess. In many cases, you don’t need time zone support for example, which makes things a lot simpler. Performance and memory limitations might also play a role, if you think embedded devices for instance. And as you say, using a platform’s C library (time struct, strftime/strptime etc.) is also relatively easy to include in Zig.
BTW, how popular is Code Berg in Deutschland?
I have no idea actually; I started using it the same time I started dabbling in Zig, which was only end of last year ^^
Missing portability and cross-compilation capability annoyed me so much that I’ve added an embedding of the full IANA tz database
I’m using a StaticStringMap for this, which just holds the TZif data for each time zone name. That means that the actual rules still need to be extracted using the TZif parser. For maximum performance (trading for memory I guess), the TZ structure returned by the parser could be stored at comptime, so that parsing isn’t required at runtime. However, the parser requires memory allocation. So if this would be possible to do at compile time (compile time allocator), here might be an application. The other option could be to come up with a zero allocation structure, potentially trading even more memory for performance.
Re-written datetime parser/formatter = new possibilities. Yes, it’s a switch-loop state machine - I did not use labeled switches though to make it work in Zig 0.13.
directives with modifier à la Rust chrono, e.g. %z gives a UTC offset +0100 whilst %:z gives the offset with a colon, +01:00
added some common formats à la go time pkg, like RFC822 or RFC3339
extended ISO calendar handling, e.g. parse from string with %t and convert to a Gregorian calendar date
ISO8601 parser now also handles Year - Day-of-Year format
0.3 to 0.4: important update on how timezones/offsets are handled, motivated by #32. Clean separation of timezone and UTC offset, timezones passed as *const consistently.
0.4.2 and 0.4.3 patches extend duration handling. ISO8601 duration strings take some time getting used to (à la ‘M’ can be monthsandminutes?! Who thought up this madness…) but can be quite handy. There’s a parser for those now, plus you can do wall-time arithmetic like the following