chrono
chrono copied to clipboard
Differences between this crate and `time`
I'm new to Rust and I'm wondering: what substantial differences are there between this crate and time?
As a mini-history, glossing over all details: before the release of rust 1.0 time-rs had the simple platform interfaces, and chrono was the date-time library. At some point time-rs was deprecated and chrono absorbed its functionality. Then chrono became unmaintained for a while, and time-rs became a new crate with a simplified part of chrono's API. Now both are actively developed again.
Chrono 0.4.33 vs time 0.3.34
| feature | Chrono 0.4.33 | time 0.3.34 |
|---|---|---|
| date type | NaiveDate |
Date |
| time type | NaiveTime |
Time |
| date and time type | NaiveDateTime |
PrimitiveDateTime |
| date, time and offset from UTC | DateTime<FixedOffset> |
OffsetDateTime |
| date and time in UTC | DateTime<Utc> (Utc is a ZST) |
OffsetDateTime |
| date and time, offset and associated timezone | DateTime<Tz> |
-- |
| formatting and parsing format | strftime-inspired |
custom (nice) format |
| converting between time zones (not just offsets) | yes | no |
| handles results in DST transitions correctly | yes | no |
| compile-time IANA database | via chrono-tz |
in progress |
| parsing and formatting RFC 2822 | complete | complete(?) |
| parsing and formatting RFC 3339 | complete | complete |
| formatting and parsing ISO 8601 | no (open PR) | yes |
| localization | unstable, formatting only | no |
| API | needs new major version to match current standards | quite ergonomic |
initialization and basic operations are const |
yes | yes |
| macros for easy initialization | no | yes |
| serde | yes | yes |
| fix for CVE-2020-26235 | pure-rust implementation | requires single thread or platform guarantees for soundness |
I am of course biased. In my opinion chrono has the better implementations (this is all not meant as bragging, it is not designed by me). Unique features: Operations on dates can be very fast thanks to a smart internal representation. Chrono can correctly recognize tricky invalid cases when parsing (see the Parsed documentation). It can handle time zones and all the complexities that come with that. Our platform code can handle more tricky cases.
On the other hand chrono is quite old and predates current API standards. Time is more ergonomic to use at the moment, at least until chrono 0.5. Chrono uses the not-that-readable strftime format for formatting and parsing; you may like the functionality of time-rs better.
Consider also asking for the time crate (https://github.com/time-rs/time/issues/308) for less bias :smile:.
chrono has a much more conservative MSRV. time is increasingly splitting out more dependencies.
I would say you basically can't go wrong with either. time is a bit more popular right now.
Corrections/clarifications on my end (as maintainer of time):
handles results in DST transitions correctly
This is because DST transitions do not exist in fixed-offset implementations.
compile-time IANA database
In progress!
date and time in UTC
OffsetDateTime can handle this, although I actually have been working on a new type recently.
parsing and formatting RFC 2822
time supports the full RFC, including all deprecated parts. If you have a counterexample, please let me know.
formatting and parsing ISO 8601
This is fully supported.
fix for CVE-2020-26235
The "user guarantee" is not the case. Soundness is guaranteed. The only exception is if someone falsely asserts (in an unsafe context!) that they are upholding the soundness requirements.
chrono has a much more conservative MSRV. time is increasingly splitting out more dependencies.
chrono is 1.61; time is 1.67. That's not a huge difference. 1.67 is still a year old. The policy is different (does chrono have anything concrete?), but the reality is that I have not had a reason to bump MSRV in quite a while.
chrono is 1.61; time is 1.67. That's not a huge difference. 1.67 is still a year old. The policy is different (does chrono have anything concrete?), but the reality is that I have not had a reason to bump MSRV in quite a while.
Oh, that is a much smaller difference than I thought, nice! Still wary of the policy, though.
I keep track of a number of features. #![feature(int_roundings)] is the only item currently set for a bump, though I have yet to check whether the stabilization is what's actually needed internally, given that it was a partial stabilization. Even then, I probably wouldn't bump it for just that.
Ultimately I don't see the MSRV being bumped in the near future, as nothing being tracked is close to stabilization and has sufficient impact.
Corrections/clarifications on my end (as maintainer of
time):
Nice, good to have your input @jhpratt!
handles results in DST transitions correctly
This is because DST transitions do not exist in fixed-offset implementations.
Yes. Not meant as critique of time. Dealing with this just might be a feature someone would want and could help choosing a library.
date and time in UTC
OffsetDateTimecan handle this, although I actually have been working on a new type recently.parsing and formatting RFC 2822
timesupports the full RFC, including all deprecated parts. If you have a counterexample, please let me know.
At the time I though I missed something with the timezone names, but haven't found the relevant parts back agin in your crate.
formatting and parsing ISO 8601
This is fully supported.
Really? Nice.
fix for CVE-2020-26235
The "user guarantee" is not the case. Soundness is guaranteed. The only exception is if someone falsely asserts (in an unsafe context!) that they are upholding the soundness requirements.
I guess we can call it: 'requires single thread or platform guarantees for soundness'
I'll update the table in my comment. It came from some notes while I was looking into the differences for myself, and wanted to give something mostly right instead of nothing :smile:. Good to have some form of comparison anyway.
I would say you basically can't go wrong with either. time is a bit more popular right now.
Pretty similar to each other it seems.
Chrono
Time
Yes. Not meant as critique of time. Dealing with this just might be a feature someone would want and could help choosing a library.
Absolutely! My remark there was more for context, as it's implied by the other row.
Really? Nice.
It was an open issue for quite a while, but I was able to obtain the 2019 version of the spec (the most recent) when a company purchased it in my name.
I guess we can call it: 'requires single thread or platform guarantees for soundness'
That's a fair way to word it.
It came from some notes while I was looking into the differences for myself
Depending on how long ago it was done, some of the info may have been accurate at the time. It's certainly good to have something, as it's hard to be impartial, particularly given that I haven't used chrono in many years.
I would say you basically can't go wrong with either. time is a bit more popular right now.
Pretty similar to each other it seems.
Well, I think 17% more qualifies as a "bit more" -- but yeah, it's definitely same order of magnitude.
@pitdicker maybe you can add another important difference in the table: with chrono I can freely use the #[derive(Default)], with time no.
Why are there no conversion options between time and chrono? As a new rust developer, I'm finding trying to figure out chrono to be pretty unnerving and frustrating. For example, using the solar-calendar-events crate:
let equinox: time::OffsetDateTime = MarchEquinox::new(year).unwrap().date_time().unwrap();
Now, I want to convert that from an OffsetDateTime to another time zone. But the time crate does not support that (only offsets). My other code is using chrono, so I have to go through all this to get a time in a particular zone in chrono. Then, how do I even convert from OffsetDateTime to DateTime<Tz>? You'd think this would be simple with the popularity of both chrono and time crates...
let tehran = Tehran
.with_ymd_and_hms(year, 3, equinox.day() as u32, 0, 0, 0)
.unwrap();
tehran.with_time(equinox.time());
mismatched types
expected `NaiveTime`, found `Time`
So they seem totally incompatible (without having to convert to/from UNIX timestamp, I guess?).
Time zones and dealing with time are a real pain in most languages, but they don't have to be in Rust, as the compiler should help you. The methods and auto-suggestions on chrono (and chrono-tz) just don't seem intuitive to me, and the documentation lacks many examples on how to just parse time from a database with a dynamic time zone like most people do (how many people really hard-code their timezones in apps?).
But my main point here is that between these two popular crates, there is no way to convert (!!!), while most other languages (Dart, Python, etc.) have centered around pretty standard time structures and good documentation on how to deal with and convert them. Even JavaScript has luxon, which provides a means to convert between it and other types.
Due to the notion of coherence in the language, providing conversion routines would mean one of these crates taking a dependency on the other. That would kind of defeat the purpose of picking a single one... So yes, these crates have evolved independently and they are completely "incompatible" at the type system level.
If you have constructive specific feedback on our API or the documentation, we're happy to discuss those in a separate issues.