|
363 | 363 | //!
|
364 | 364 | //! The MSRV is explicitly tested in CI. It may be bumped in minor releases, but this is not done
|
365 | 365 | //! 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 |
366 | 463 |
|
367 | 464 | #![doc(html_root_url = "https://docs.rs/chrono/latest/", test(attr(deny(warnings))))]
|
368 | 465 | #![cfg_attr(feature = "bench", feature(test))] // lib stability features as per RFC #507
|
|
0 commit comments