I recently started learning Zig. So far, this has been a very interesting journey. As a learning project, I began to write a library to handle datetime, something I always wanted to approach in a “low-level” language. You can find it here. Be warned, it’s at a very early stage right now. Also, I’m aware that there are other attempts at this topic in Zig. But, re-inventing the wheel can be very insightful. Suggestions etc. welcome
Skimming through some repos (zig-datetime, zig-time, zig-tzif), as well as the standard library, I asked myself, what is the state of datetime handling in Zig? What are the plans for the future?
- the standard library does implement some basic aspects like obtain current Unix time from the system, e.g.
std.time.nanoTimestamp() or a
- then there’s
epoch.zig, which defines some stuff that I would consider “utilities”, evolving around the Unix epoch - although the name “epoch” could imply anything… Furthermore, for instance there is a function
isLeapYear in there, which is not related to any epoch but the Gregorian calendar
- finally, there’s
tz.zig, which seems to contain functionality to handle RFC 8536 TZif files. Which
zig-tzif also does, IIUC
- not exactly datetime, but interesting: std.fmt has a duration formatter - with fixed 365 days per year
This leaves me wondering, is datetime a planned std-lib feature? If you have datetime, you might just add time zones as well. So what about time zones?
Python is a good example how not to do it I think; have datetime but no time zones at first, then incomplete ones, then as third party libraries, then years later finally in the std lib.
I think C++'s std::chrono does it really well. Granted, it’s a bit confusing and took me a lecture from Cppcon to understand it, but it’s not C++'s fault, it can be a confusing problem on its own, with timezones and all, and it becomes even more complicated when you take into account problems that are specific to computer science, like resolution and overflows. Since you can access C++ std library from zig, that’s one option.
Right, C/C++ interop makes the number of available options pretty big I guess. Btw. I also took some inspiration from Howard Hinnant’s date library (C++)
Nevertheless, from what I found in the Zig std lib, it seems some attempts were made to come up with something Zig-specific? Also, I think Zig offers some nice features which would come as an advantage, for example arbitrary-width integers (e.g. you only need
u3 to represent the day of the week) and general simplicity compared to C++. For me not coming from a C++ background this last one is huge. Just take quoted
date library from above for instance - the amount of code just to satisfy the C++11 C++14 and C++17 compatibility is huge in my eyes.
In general, the most relevant question for this is usually “is this / will this be a required component of some part of the compiler or standard library?”
I’m not familiar enough with datetime-related stuff to know what the answer is in this case.
By “standard library” you mean other, “low level” parts of the standard library, that depend on this?
As for the compiler, I’ve never worked on one, but that seems reasonable of course. I’d say that being able to putting a timestamp (Unix time) somewhere could come in handy, but obtaining the day of the week or reading a tzif file?
As an example, one feature of the compiler is the package manager, which means that the standard library needs to have:
- HTTP client
- Decompression algorithms
- TLS implementation
If not for the package manager, this stuff may not be in the standard library at all, and instead left to 3rd party libraries.
I see that my TZif library got mentioned, so I’ll go ahead and mention another library I worked on,
chrono-zig. It was an attempt to port the rust crate named chrono. I implemented datetime parsing and formatting, at least to an extent. I think it was missing conversions from localtime to UTC. In the end I’m not sure the abstractions
chrono used make sense to use in zig.
Great, thanks for coming over here
Sorry I didn’t mention chrono-zig. I’m not really familiar with Rust’s chrono, but I remember having to use an additional package to handle time zones. Regarding ports in general, it seems that after all, you could just use C++ chrono in Zig, no? Ok, guess that won’t be that easy in the details. Anyways, what was your motivation of making a port?
I had a couple reasons to do a port:
- At the time I only knew of Rust’s chrono crate. I didn’t want to require a Rust toolchain to build my projects.
- Staying within pure Zig means I can write code that cross-compiles well, and works on embedded or WebAssembly targets. I was specifically targeting WebAssembly at the time.
- I like Zig! I wanted to expand the ecosystem and write Zig code.
As far as using the C++ chrono, Zig doesn’t have a way to interact with C++ directly. It would require writing a C++ library that exports chrono’s functionality to C.
Addendum - since I can’t edit the original post: Karl Seguin’s zig utils also have some datetime functionality: GitHub - karlseguin/zul: zig utility library