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
i had tested this solution, but when i saw during the system update that the time zone had moved, moreover a modification was in sight on the timestamp there was an announcement like there will be deep changes. then i took the datetimectl …
Also, for example, France Paris il 180 enrg. Not everything is clear, it’s mentioned in the specifications. But bravo. And you put windows too bravo
Yes, there have been many breaking API changes from 0.2 to 0.3. Since then, it was mostly stable. The new release adds one new method to the API (zdt.Timezone.fromPosixTz). The documentation could potentially be improved; at the moment there is the API overview I wrote manually, the auto-generated docs and the examples.
Regarding Windows, I have experimented with a couple of features / the Windows API, however never gotten really deep into it since Windows is not my “native platform”. Shipping the IANA tzdb with zdt makes it platform independent in principle.
I don’t understand how you get .tzif files and why you can’t use ./usr/share/info files directly.
ps: just one question…
Again, a lot of thought and hard work, I know a thing or two about that…
It’s true that my way of doing things has a cost, but it’s less than a second, and it’s a one-off for the day. After that, it’s a matter of milliseconds.
TZif is used as an independent media for timezone information exchange (see RFC9636). That became a common standard, at least in the non-Windows world. So with zdt, I just ended up using what many people do. Of course that doesn’t mean that it should prevent you from thinking about other possibility to store such data.
As to how to create tzif files, you can compile them from GitHub - eggert/tz: Time zone database and code - that’s what zdt/scripts/gen_tzdb.zig at master · FObersteiner/zdt · GitHub does (basically just runs the makefile from Paul Eggert’s repo). Besides, if you want to use the TZif files from your system with zdt, you can do that with zdt.Timezone.fromSystemTzdata. You can supply the prefix (path) to your system’s zoneinfo directory at build time with -prefix_tzdb (it defaults to /usr/share/zoneinfo/ if you don’t specify the argument).
Two reasons why it makes sense to have another option to have timezone data besides what your system provides are (1) some systems just don’t come with such data and (2) some systems are notoriously slow to update; for example at the time of writing this, my Debian 12 machine still uses tzdata 2024b (2025a was released two months ago).
Yes, thanks for the information, I work with Manjaro, and besides, I have a supercomputer, maybe the last one (I’m 73), and I bought myself the top-of-the-range model.
So no time problem, and I always have the latest update, and I’m always getting my hands dirty, for updates, which I refine