Skip to content

Commit a83ff4a

Browse files
committed
Add history of chrono and time 0.1 to main documentation
1 parent 8509da4 commit a83ff4a

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed

src/lib.rs

+97
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,103 @@
363363
//!
364364
//! The MSRV is explicitly tested in CI. It may be bumped in minor releases, but this is not done
365365
//! lightly.
366+
//!
367+
//! Chrono inherently does not support an inaccurate or partial date and time representation.
368+
//! Any operation that can be ambiguous will return `None` in such cases.
369+
//! For example, "a month later" of 2014-01-30 is not well-defined
370+
//! and consequently `Utc.ymd_opt(2014, 1, 30).unwrap().with_month(2)` returns `None`.
371+
//!
372+
//! Non ISO week handling is not yet supported.
373+
//! For now you can use the [chrono_ext](https://crates.io/crates/chrono_ext)
374+
//! crate ([sources](https://github.com/bcourtine/chrono-ext/)).
375+
//!
376+
//! Advanced time zone handling is not yet supported.
377+
//! For now you can try the [Chrono-tz](https://github.com/chronotope/chrono-tz/) crate instead.
378+
//!
379+
//! ## Relation between chrono and time 0.1
380+
//!
381+
//! Since Rust 0.7 the standard library had a `time` module. It moved to `libextra`, and then to a
382+
//! `libtime` library shipped alongside the standard library. In 2014 the work on chrono started in
383+
//! order to provide a full-featured date and time library in Rust. Some improvements from chrono
384+
//! made it into the standard library, notably the `chrono::Duration` type was moved to
385+
//! `std::time::Duration` ([rust#15934]).
386+
//!
387+
//! In preparation of Rust 1.0 at the end of 2014 `libtime` was moved out of the Rust distro and
388+
//! into the `time` crate to eventually be redesigned ([rust#18832], [rust#18858]), just like the
389+
//! `num` and `rand` crates. Naturally chrono gained `time` as a dependency. `time` also started
390+
//! re-exporting `std::time::Duration`. Later the standard library was changed to have a more
391+
//! limited unsigned `Duration` type ([rust#24920], [RFC 1040]), while the `time` crate kept the
392+
//! full functionality with `time::Duration`. And `time::Duration` was part of the public API of
393+
//! chrono.
394+
//!
395+
//! By 2016 `time` 0.1 lived under the `rust-lang-deprecated` organisation and was not actively
396+
//! maintained ([time#136]). Chrono absorbed the platform functionality and `Duration` type of the
397+
//! time crate in [chrono#478] (the work started in [chrono#286]). But because of the
398+
//! `time::Duration` type and to not make this a breaking change `time` would still remain as a
399+
//! dependency. Crates could opt to use chrono without the `old-time` feature to drop the
400+
//! dependency. During this time @jhpratt would take over `time` and release what amounts to a new
401+
//! crate under time 0.2.
402+
//!
403+
//! [rust#15934]: https://github.com/rust-lang/rust/pull/15934
404+
//! [rust#18832]: https://github.com/rust-lang/rust/pull/18832#issuecomment-62448221
405+
//! [rust#18858]: https://github.com/rust-lang/rust/pull/18858
406+
//! [rust#24920]: https://github.com/rust-lang/rust/pull/24920
407+
//! [RFC 1040]: https://rust-lang.github.io/rfcs/1040-duration-reform.html
408+
//! [time#136]: https://github.com/time-rs/time/issues/136
409+
//! [chrono#286]: https://github.com/chronotope/chrono/pull/286
410+
//! [chrono#478]: https://github.com/chronotope/chrono/pull/478
411+
//!
412+
//! #### Security advisories
413+
//!
414+
//! In november 2020 [CVE-2020-26235] and [RUSTSEC-2020-0071] were opened against the time crate,
415+
//! and the start of quite some frustration for the rust ecosystem. @quininer found that calls to
416+
//! `localtime_r` may be unsound ([chrono#499]). Eventually, almost a year later, this was also made
417+
//! into a security advisory against chrono as [RUSTSEC-2020-0159], which had platform code similar
418+
//! to `time`.
419+
//!
420+
//! The issue: on Unix-like systems a process is given a time zone id or description via the `TZ`
421+
//! environment variable. We need this time zone data to calculate the current local time from a
422+
//! value that is in UTC, such as the time from the system clock. `time` 0.1 and chrono used the
423+
//! POSIX function `localtime_r` to do the conversion to local time, which reads the `TZ` variable.
424+
//!
425+
//! Rust assumes the environment to be writable and uses locks to access it from multiple threads.
426+
//! So do some other programming languages and libraries, but there is no shared locking mechanism.
427+
//! More importantly POSIX declares modifying the environment in a multi-threaded process as unsafe,
428+
//! and `getenv` in libc can't be changed to just take a lock because it returns a pointer to the
429+
//! data (see [rust#27970] for more discussion).
430+
//!
431+
//! Since version 4.20 chrono no longer uses `localtime_r` but uses rust code to query the time zone
432+
//! (from the `TZ` variable or via `iana-time-zone` as a fallback) and work with data from the
433+
//! system time zone database directly. This involves the logic for POSIX TZ Strings, and parsing
434+
//! TZif files and working with their transition tables. The code mostly comes from the work by
435+
//! @x-hgg-x on the [tz-rs crate].
436+
//!
437+
//! So when reading the `TZ` environment variable chrono now respects the Rust locks. However in
438+
//! general it is probably best to avoid modifying the environment.
439+
//!
440+
//! The good thing to come from this is that we can improve beyond what the platform offers.
441+
//!
442+
//! [CVE-2020-26235]: https://nvd.nist.gov/vuln/detail/CVE-2020-26235
443+
//! [RUSTSEC-2020-0071]: https://rustsec.org/advisories/RUSTSEC-2020-0071
444+
//! [chrono#499]: https://github.com/chronotope/chrono/pull/499
445+
//! [RUSTSEC-2020-0159]: https://rustsec.org/advisories/RUSTSEC-2020-0159.html
446+
//! [rust#27970]: https://github.com/rust-lang/rust/issues/27970
447+
//! [chrono#677]: https://github.com/chronotope/chrono/pull/677
448+
//! [tz-rs crate]: https://crates.io/crates/tz-rs
449+
//!
450+
//! #### Removing time 0.1
451+
//!
452+
//! Still users of chrono would get a security advisory because of the time 0.1 dependency, which
453+
//! was never fixed. We were careful not to break backwards compatibility with the `time::Duration`
454+
//! type. But how many crates actually depend on this compatibility with time 0.1? Remember it was
455+
//! unmaintained for multiple years, and now had much improved new releases. After a primitive
456+
//! crater-like run it turned out only a tiny number of crates would break ([chrono#1095]), which we
457+
//! reached out to if still maintained.
458+
//!
459+
//! With 0.4.30 chrono finally drops the time 0.1 dependency, making an end to the *many* security
460+
//! advisory warnings against crates depending on chrono.
461+
//!
462+
//! [chrono#1095]: https://github.com/chronotope/chrono/pull/1095
366463
367464
#![doc(html_root_url = "https://docs.rs/chrono/latest/", test(attr(deny(warnings))))]
368465
#![cfg_attr(feature = "bench", feature(test))] // lib stability features as per RFC #507

0 commit comments

Comments
 (0)