So... after poking around a bit in Rust, I went looking for date/time libraries, because I have some strong opinions about how to do that.
I found chrono, but I find myself fundamentally opposed to its core model for DateTime
- using trait implementations for whether it represents something in UTC, your "local" offset, or some other, unknown offset:
let utc: DateTime<Utc> = Utc::now(); // e.g. `2014-11-28T12:45:59.324310806Z`
let local: DateTime<Local> = Local::now(); // e.g. `2014-11-28T21:45:59.324310806+09:00`
Putting aside all the specific complaints I have about this model, what's the consensus on developing a competing library for this?
- Too widely used, don't bother.
- Would prefer a different domain model, but not sure what.
- Get something started, we'll see.
- (Something else?)
Personally, I find something similar to Java's java.time
library, or the C# NodaTime package to be a more natural model. Here's a table listing out what the base types are for java.time
and their closest equivalents in standard rust and chrono:
Java type | Purpose | closest chrono equivalent |
---|---|---|
LocalDate |
date-only | NaiveDate |
LocalTime |
time-only | NaiveTime |
LocalDateTime |
date-time without timezone or offset | NaiveDateTime |
OffsetDateTime |
date-time with an offset from UTC | DateTime<FixedOffset> |
ZonedDateTime |
date-time with a timezone |
DateTime<Tz> (from the chrono-tz crate) |
Duration |
exact amount of time | Duration |
Period |
inexact amount of time - years, months, days | none |
Instant |
timezone and offset agnostic point on timeline | none (std::time::Instant represents something akin to a "system uptime clock". std::time::SystemTime is closer, but the documentation concentrates too much on "what time does my system think the time is?", whereas java.time.Instant is explicitly "this represents this point on the timeline", and hence is not opaque. Whether it's the actual instant is left as an exercise for the application) |
I've been playing around privately with translating java.time
into Rust, but figured I would ask before I put any more effort into it. The original Java version heavily depends on subclassing and virtual calls, which don't work so well in Rust, but the core types are usable without most of that indirection.