summaryrefslogtreecommitdiffstats
path: root/vendor/chrono/src/lib.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /vendor/chrono/src/lib.rs
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/chrono/src/lib.rs')
-rw-r--r--vendor/chrono/src/lib.rs1226
1 files changed, 109 insertions, 1117 deletions
diff --git a/vendor/chrono/src/lib.rs b/vendor/chrono/src/lib.rs
index 9d66ae324..861ee1059 100644
--- a/vendor/chrono/src/lib.rs
+++ b/vendor/chrono/src/lib.rs
@@ -1,6 +1,3 @@
-// This is a part of Chrono.
-// See README.md and LICENSE.txt for details.
-
//! # Chrono: Date and Time for Rust
//!
//! It aims to be a feature-complete superset of
@@ -19,18 +16,6 @@
//! * Dietrich Epp's [datetime-rs](https://github.com/depp/datetime-rs)
//! * Luis de Bethencourt's [rust-datetime](https://github.com/luisbg/rust-datetime)
//!
-//! Any significant changes to Chrono are documented in
-//! the [`CHANGELOG.md`](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) file.
-//!
-//! ## Usage
-//!
-//! Put this in your `Cargo.toml`:
-//!
-//! ```toml
-//! [dependencies]
-//! chrono = "0.4"
-//! ```
-//!
//! ### Features
//!
//! Chrono supports various runtime environments and operating systems, and has
@@ -42,12 +27,11 @@
//! - `std`: Enables functionality that depends on the standard library. This
//! is a superset of `alloc` and adds interoperation with standard library types
//! and traits.
-//! - `clock`: enables reading the system time (`now`), independent of whether
-//! `std::time::SystemTime` is present, depends on having a libc.
+//! - `clock`: Enables reading the system time (`now`) that depends on the standard library for
+//! UNIX-like operating systems and the Windows API (`winapi`) for Windows.
//!
//! Optional features:
//!
-//! - `wasmbind`: Enable integration with [wasm-bindgen][] and its `js-sys` project
//! - [`serde`][]: Enable serialization/deserialization via serde.
//! - `unstable-locales`: Enable localization. This adds various methods with a
//! `_localized` suffix. The implementation and API may change or even be
@@ -142,26 +126,26 @@
//! use chrono::prelude::*;
//! use chrono::offset::LocalResult;
//!
-//! let dt = Utc.ymd(2014, 7, 8).and_hms(9, 10, 11); // `2014-07-08T09:10:11Z`
+//! let dt = Utc.with_ymd_and_hms(2014, 7, 8, 9, 10, 11).unwrap(); // `2014-07-08T09:10:11Z`
//! // July 8 is 188th day of the year 2014 (`o` for "ordinal")
-//! assert_eq!(dt, Utc.yo(2014, 189).and_hms(9, 10, 11));
+//! assert_eq!(dt, Utc.yo(2014, 189).and_hms_opt(9, 10, 11).unwrap());
//! // July 8 is Tuesday in ISO week 28 of the year 2014.
-//! assert_eq!(dt, Utc.isoywd(2014, 28, Weekday::Tue).and_hms(9, 10, 11));
+//! assert_eq!(dt, Utc.isoywd(2014, 28, Weekday::Tue).and_hms_opt(9, 10, 11).unwrap());
//!
-//! let dt = Utc.ymd(2014, 7, 8).and_hms_milli(9, 10, 11, 12); // `2014-07-08T09:10:11.012Z`
-//! assert_eq!(dt, Utc.ymd(2014, 7, 8).and_hms_micro(9, 10, 11, 12_000));
-//! assert_eq!(dt, Utc.ymd(2014, 7, 8).and_hms_nano(9, 10, 11, 12_000_000));
+//! let dt = NaiveDate::from_ymd_opt(2014, 7, 8).unwrap().and_hms_milli_opt(9, 10, 11, 12).unwrap().and_local_timezone(Utc).unwrap(); // `2014-07-08T09:10:11.012Z`
+//! assert_eq!(dt, NaiveDate::from_ymd_opt(2014, 7, 8).unwrap().and_hms_micro_opt(9, 10, 11, 12_000).unwrap().and_local_timezone(Utc).unwrap());
+//! assert_eq!(dt, NaiveDate::from_ymd_opt(2014, 7, 8).unwrap().and_hms_nano_opt(9, 10, 11, 12_000_000).unwrap().and_local_timezone(Utc).unwrap());
//!
//! // dynamic verification
//! assert_eq!(Utc.ymd_opt(2014, 7, 8).and_hms_opt(21, 15, 33),
-//! LocalResult::Single(Utc.ymd(2014, 7, 8).and_hms(21, 15, 33)));
+//! LocalResult::Single(Utc.with_ymd_and_hms(2014, 7, 8, 21, 15, 33).unwrap()));
//! assert_eq!(Utc.ymd_opt(2014, 7, 8).and_hms_opt(80, 15, 33), LocalResult::None);
//! assert_eq!(Utc.ymd_opt(2014, 7, 38).and_hms_opt(21, 15, 33), LocalResult::None);
//!
//! // other time zone objects can be used to construct a local datetime.
//! // obviously, `local_dt` is normally different from `dt`, but `fixed_dt` should be identical.
-//! let local_dt = Local.ymd(2014, 7, 8).and_hms_milli(9, 10, 11, 12);
-//! let fixed_dt = FixedOffset::east(9 * 3600).ymd(2014, 7, 8).and_hms_milli(18, 10, 11, 12);
+//! let local_dt = Local.from_local_datetime(&NaiveDate::from_ymd_opt(2014, 7, 8).unwrap().and_hms_milli_opt(9, 10, 11, 12).unwrap()).unwrap();
+//! let fixed_dt = FixedOffset::east_opt(9 * 3600).unwrap().from_local_datetime(&NaiveDate::from_ymd_opt(2014, 7, 8).unwrap().and_hms_milli_opt(18, 10, 11, 12).unwrap()).unwrap();
//! assert_eq!(dt, fixed_dt);
//! # let _ = local_dt;
//! ```
@@ -173,14 +157,11 @@
//! The following illustrates most supported operations to the date and time:
//!
//! ```rust
-//! # extern crate chrono;
-//!
-//! # fn main() {
//! use chrono::prelude::*;
//! use chrono::Duration;
//!
//! // assume this returned `2014-11-28T21:45:59.324310806+09:00`:
-//! let dt = FixedOffset::east(9*3600).ymd(2014, 11, 28).and_hms_nano(21, 45, 59, 324310806);
+//! let dt = FixedOffset::east_opt(9*3600).unwrap().from_local_datetime(&NaiveDate::from_ymd_opt(2014, 11, 28).unwrap().and_hms_nano_opt(21, 45, 59, 324310806).unwrap()).unwrap();
//!
//! // property accessors
//! assert_eq!((dt.year(), dt.month(), dt.day()), (2014, 11, 28));
@@ -193,8 +174,8 @@
//!
//! // time zone accessor and manipulation
//! assert_eq!(dt.offset().fix().local_minus_utc(), 9 * 3600);
-//! assert_eq!(dt.timezone(), FixedOffset::east(9 * 3600));
-//! assert_eq!(dt.with_timezone(&Utc), Utc.ymd(2014, 11, 28).and_hms_nano(12, 45, 59, 324310806));
+//! assert_eq!(dt.timezone(), FixedOffset::east_opt(9 * 3600).unwrap());
+//! assert_eq!(dt.with_timezone(&Utc), NaiveDate::from_ymd_opt(2014, 11, 28).unwrap().and_hms_nano_opt(12, 45, 59, 324310806).unwrap().and_local_timezone(Utc).unwrap());
//!
//! // a sample of property manipulations (validates dynamically)
//! assert_eq!(dt.with_day(29).unwrap().weekday(), Weekday::Sat); // 2014-11-29 is Saturday
@@ -202,15 +183,14 @@
//! assert_eq!(dt.with_year(-300).unwrap().num_days_from_ce(), -109606); // November 29, 301 BCE
//!
//! // arithmetic operations
-//! let dt1 = Utc.ymd(2014, 11, 14).and_hms(8, 9, 10);
-//! let dt2 = Utc.ymd(2014, 11, 14).and_hms(10, 9, 8);
+//! let dt1 = Utc.with_ymd_and_hms(2014, 11, 14, 8, 9, 10).unwrap();
+//! let dt2 = Utc.with_ymd_and_hms(2014, 11, 14, 10, 9, 8).unwrap();
//! assert_eq!(dt1.signed_duration_since(dt2), Duration::seconds(-2 * 3600 + 2));
//! assert_eq!(dt2.signed_duration_since(dt1), Duration::seconds(2 * 3600 - 2));
-//! assert_eq!(Utc.ymd(1970, 1, 1).and_hms(0, 0, 0) + Duration::seconds(1_000_000_000),
-//! Utc.ymd(2001, 9, 9).and_hms(1, 46, 40));
-//! assert_eq!(Utc.ymd(1970, 1, 1).and_hms(0, 0, 0) - Duration::seconds(1_000_000_000),
-//! Utc.ymd(1938, 4, 24).and_hms(22, 13, 20));
-//! # }
+//! assert_eq!(Utc.with_ymd_and_hms(1970, 1, 1, 0, 0, 0).unwrap() + Duration::seconds(1_000_000_000),
+//! Utc.with_ymd_and_hms(2001, 9, 9, 1, 46, 40).unwrap());
+//! assert_eq!(Utc.with_ymd_and_hms(1970, 1, 1, 0, 0, 0).unwrap() - Duration::seconds(1_000_000_000),
+//! Utc.with_ymd_and_hms(1938, 4, 24, 22, 13, 20).unwrap());
//! ```
//!
//! ### Formatting and Parsing
@@ -230,8 +210,8 @@
//! help of an additional C library. This functionality is under the feature
//! `unstable-locales`:
//!
-//! ```text
-//! chrono { version = "0.4", features = ["unstable-locales"]
+//! ```toml
+//! chrono = { version = "0.4", features = ["unstable-locales"] }
//! ```
//!
//! The `unstable-locales` feature requires and implies at least the `alloc` feature.
@@ -239,20 +219,28 @@
//! ```rust
//! use chrono::prelude::*;
//!
-//! let dt = Utc.ymd(2014, 11, 28).and_hms(12, 0, 9);
+//! # #[cfg(feature = "unstable-locales")]
+//! # fn test() {
+//! let dt = Utc.with_ymd_and_hms(2014, 11, 28, 12, 0, 9).unwrap();
//! assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2014-11-28 12:00:09");
//! assert_eq!(dt.format("%a %b %e %T %Y").to_string(), "Fri Nov 28 12:00:09 2014");
//! assert_eq!(dt.format_localized("%A %e %B %Y, %T", Locale::fr_BE).to_string(), "vendredi 28 novembre 2014, 12:00:09");
-//! assert_eq!(dt.format("%a %b %e %T %Y").to_string(), dt.format("%c").to_string());
//!
+//! assert_eq!(dt.format("%a %b %e %T %Y").to_string(), dt.format("%c").to_string());
//! assert_eq!(dt.to_string(), "2014-11-28 12:00:09 UTC");
//! assert_eq!(dt.to_rfc2822(), "Fri, 28 Nov 2014 12:00:09 +0000");
//! assert_eq!(dt.to_rfc3339(), "2014-11-28T12:00:09+00:00");
//! assert_eq!(format!("{:?}", dt), "2014-11-28T12:00:09Z");
//!
//! // Note that milli/nanoseconds are only printed if they are non-zero
-//! let dt_nano = Utc.ymd(2014, 11, 28).and_hms_nano(12, 0, 9, 1);
+//! let dt_nano = NaiveDate::from_ymd_opt(2014, 11, 28).unwrap().and_hms_nano_opt(12, 0, 9, 1).unwrap().and_local_timezone(Utc).unwrap();
//! assert_eq!(format!("{:?}", dt_nano), "2014-11-28T12:00:09.000000001Z");
+//! # }
+//! # #[cfg(not(feature = "unstable-locales"))]
+//! # fn test() {}
+//! # if cfg!(feature = "unstable-locales") {
+//! # test();
+//! # }
//! ```
//!
//! Parsing can be done with three methods:
@@ -285,8 +273,8 @@
//! ```rust
//! use chrono::prelude::*;
//!
-//! let dt = Utc.ymd(2014, 11, 28).and_hms(12, 0, 9);
-//! let fixed_dt = dt.with_timezone(&FixedOffset::east(9*3600));
+//! let dt = Utc.with_ymd_and_hms(2014, 11, 28, 12, 0, 9).unwrap();
+//! let fixed_dt = dt.with_timezone(&FixedOffset::east_opt(9*3600).unwrap());
//!
//! // method 1
//! assert_eq!("2014-11-28T12:00:09Z".parse::<DateTime<Utc>>(), Ok(dt.clone()));
@@ -353,9 +341,9 @@
//! assert_eq!(Utc::today(), Utc::now().date());
//! assert_eq!(Local::today(), Local::now().date());
//!
-//! assert_eq!(Utc.ymd(2014, 11, 28).weekday(), Weekday::Fri);
+//! assert_eq!(Utc.ymd_opt(2014, 11, 28).unwrap().weekday(), Weekday::Fri);
//! assert_eq!(Utc.ymd_opt(2014, 11, 31), LocalResult::None);
-//! assert_eq!(Utc.ymd(2014, 11, 28).and_hms_milli(7, 8, 9, 10).format("%H%M%S").to_string(),
+//! assert_eq!(NaiveDate::from_ymd_opt(2014, 11, 28).unwrap().and_hms_milli_opt(7, 8, 9, 10).unwrap().and_local_timezone(Utc).unwrap().format("%H%M%S").to_string(),
//! "070809");
//! ```
//!
@@ -401,7 +389,7 @@
//! Chrono inherently does not support an inaccurate or partial date and time representation.
//! Any operation that can be ambiguous will return `None` in such cases.
//! For example, "a month later" of 2014-01-30 is not well-defined
-//! and consequently `Utc.ymd(2014, 1, 30).with_month(2)` returns `None`.
+//! and consequently `Utc.ymd_opt(2014, 1, 30).unwrap().with_month(2)` returns `None`.
//!
//! Non ISO week handling is not yet supported.
//! For now you can use the [chrono_ext](https://crates.io/crates/chrono_ext)
@@ -414,1122 +402,126 @@
#![cfg_attr(feature = "bench", feature(test))] // lib stability features as per RFC #507
#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
+#![warn(unreachable_pub)]
#![deny(dead_code)]
-// lints are added all the time, we test on 1.13
-#![allow(unknown_lints)]
#![cfg_attr(not(any(feature = "std", test)), no_std)]
-#![cfg_attr(feature = "cargo-clippy", allow(
- renamed_and_removed_lints,
- // The explicit 'static lifetimes are still needed for rustc 1.13-16
- // backward compatibility, and this appeases clippy. If minimum rustc
- // becomes 1.17, should be able to remove this, those 'static lifetimes,
- // and use `static` in a lot of places `const` is used now.
- redundant_static_lifetimes,
- // Similarly, redundant_field_names lints on not using the
- // field-init-shorthand, which was stabilized in rust 1.17.
- redundant_field_names,
- // Changing trivially_copy_pass_by_ref would require an incompatible version
- // bump.
- trivially_copy_pass_by_ref,
- try_err,
- // Currently deprecated, we use the separate implementation to add docs
- // warning that putting a time in a hash table is probably a bad idea
- derive_hash_xor_eq,
-))]
-
-#[cfg(feature = "alloc")]
-extern crate alloc;
-#[cfg(all(feature = "std", not(feature = "alloc")))]
-extern crate std as alloc;
-#[cfg(any(feature = "std", test))]
-extern crate std as core;
+// can remove this if/when rustc-serialize support is removed
+// keeps clippy happy in the meantime
+#![cfg_attr(feature = "rustc-serialize", allow(deprecated))]
+#![cfg_attr(docsrs, feature(doc_cfg))]
#[cfg(feature = "oldtime")]
+#[cfg_attr(docsrs, doc(cfg(feature = "oldtime")))]
extern crate time as oldtime;
#[cfg(not(feature = "oldtime"))]
mod oldtime;
+// this reexport is to aid the transition and should not be in the prelude!
+pub use oldtime::{Duration, OutOfRangeError};
-#[cfg(feature = "clock")]
-extern crate libc;
-#[cfg(all(feature = "clock", windows))]
-extern crate winapi;
-#[cfg(all(
- feature = "clock",
- not(all(target_arch = "wasm32", not(target_os = "wasi"), feature = "wasmbind"))
-))]
-mod sys;
-
-extern crate num_integer;
-extern crate num_traits;
-#[cfg(feature = "rustc-serialize")]
-extern crate rustc_serialize;
-#[cfg(feature = "serde")]
-extern crate serde as serdelib;
#[cfg(feature = "__doctest")]
#[cfg_attr(feature = "__doctest", cfg(doctest))]
-#[macro_use]
-extern crate doc_comment;
-#[cfg(all(target_arch = "wasm32", not(target_os = "wasi"), feature = "wasmbind"))]
-extern crate js_sys;
-#[cfg(feature = "unstable-locales")]
-extern crate pure_rust_locales;
-#[cfg(feature = "bench")]
-extern crate test;
-#[cfg(all(target_arch = "wasm32", not(target_os = "wasi"), feature = "wasmbind"))]
-extern crate wasm_bindgen;
+use doc_comment::doctest;
#[cfg(feature = "__doctest")]
#[cfg_attr(feature = "__doctest", cfg(doctest))]
doctest!("../README.md");
-// this reexport is to aid the transition and should not be in the prelude!
-pub use oldtime::Duration;
-
-pub use date::{Date, MAX_DATE, MIN_DATE};
-#[cfg(feature = "rustc-serialize")]
-pub use datetime::rustc_serialize::TsSeconds;
-pub use datetime::{DateTime, SecondsFormat, MAX_DATETIME, MIN_DATETIME};
-/// L10n locales.
-#[cfg(feature = "unstable-locales")]
-pub use format::Locale;
-pub use format::{ParseError, ParseResult};
-#[doc(no_inline)]
-pub use naive::{IsoWeek, NaiveDate, NaiveDateTime, NaiveTime};
-#[cfg(feature = "clock")]
-#[doc(no_inline)]
-pub use offset::Local;
-#[doc(no_inline)]
-pub use offset::{FixedOffset, LocalResult, Offset, TimeZone, Utc};
-pub use round::{DurationRound, RoundingError, SubsecRound};
-
/// A convenience module appropriate for glob imports (`use chrono::prelude::*;`).
pub mod prelude {
#[doc(no_inline)]
- pub use Date;
+ #[allow(deprecated)]
+ pub use crate::Date;
#[cfg(feature = "clock")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "clock")))]
#[doc(no_inline)]
- pub use Local;
+ pub use crate::Local;
#[cfg(feature = "unstable-locales")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "unstable-locales")))]
#[doc(no_inline)]
- pub use Locale;
+ pub use crate::Locale;
#[doc(no_inline)]
- pub use SubsecRound;
+ pub use crate::SubsecRound;
#[doc(no_inline)]
- pub use {DateTime, SecondsFormat};
+ pub use crate::{DateTime, SecondsFormat};
#[doc(no_inline)]
- pub use {Datelike, Month, Timelike, Weekday};
+ pub use crate::{Datelike, Month, Timelike, Weekday};
#[doc(no_inline)]
- pub use {FixedOffset, Utc};
+ pub use crate::{FixedOffset, Utc};
#[doc(no_inline)]
- pub use {NaiveDate, NaiveDateTime, NaiveTime};
+ pub use crate::{NaiveDate, NaiveDateTime, NaiveTime};
#[doc(no_inline)]
- pub use {Offset, TimeZone};
+ pub use crate::{Offset, TimeZone};
}
-// useful throughout the codebase
-macro_rules! try_opt {
- ($e:expr) => {
- match $e {
- Some(v) => v,
- None => return None,
- }
- };
-}
+mod date;
+#[allow(deprecated)]
+pub use date::{Date, MAX_DATE, MIN_DATE};
-mod div;
-pub mod offset;
-pub mod naive {
- //! Date and time types unconcerned with timezones.
- //!
- //! They are primarily building blocks for other types
- //! (e.g. [`TimeZone`](../offset/trait.TimeZone.html)),
- //! but can be also used for the simpler date and time handling.
+mod datetime;
+#[cfg(feature = "rustc-serialize")]
+#[cfg_attr(docsrs, doc(cfg(feature = "rustc-serialize")))]
+pub use datetime::rustc_serialize::TsSeconds;
+#[allow(deprecated)]
+pub use datetime::{DateTime, SecondsFormat, MAX_DATETIME, MIN_DATETIME};
- mod date;
- mod datetime;
- mod internals;
- mod isoweek;
- mod time;
+pub mod format;
+/// L10n locales.
+#[cfg(feature = "unstable-locales")]
+#[cfg_attr(docsrs, doc(cfg(feature = "unstable-locales")))]
+pub use format::Locale;
+pub use format::{ParseError, ParseResult};
- pub use self::date::{NaiveDate, MAX_DATE, MIN_DATE};
- #[cfg(feature = "rustc-serialize")]
- #[allow(deprecated)]
- pub use self::datetime::rustc_serialize::TsSeconds;
- pub use self::datetime::{NaiveDateTime, MAX_DATETIME, MIN_DATETIME};
- pub use self::isoweek::IsoWeek;
- pub use self::time::NaiveTime;
+pub mod naive;
+#[doc(no_inline)]
+pub use naive::{Days, IsoWeek, NaiveDate, NaiveDateTime, NaiveTime, NaiveWeek};
- #[cfg(feature = "__internal_bench")]
- #[doc(hidden)]
- pub use self::internals::YearFlags as __BenchYearFlags;
+pub mod offset;
+#[cfg(feature = "clock")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clock")))]
+#[doc(no_inline)]
+pub use offset::Local;
+#[doc(no_inline)]
+pub use offset::{FixedOffset, LocalResult, Offset, TimeZone, Utc};
- /// Serialization/Deserialization of naive types in alternate formats
- ///
- /// The various modules in here are intended to be used with serde's [`with`
- /// annotation][1] to serialize as something other than the default [RFC
- /// 3339][2] format.
- ///
- /// [1]: https://serde.rs/attributes.html#field-attributes
- /// [2]: https://tools.ietf.org/html/rfc3339
- #[cfg(feature = "serde")]
- pub mod serde {
- pub use super::datetime::serde::*;
- }
-}
-mod date;
-mod datetime;
-pub mod format;
mod round;
+pub use round::{DurationRound, RoundingError, SubsecRound};
+
+mod weekday;
+pub use weekday::{ParseWeekdayError, Weekday};
+
+mod month;
+pub use month::{Month, Months, ParseMonthError};
+
+mod traits;
+pub use traits::{Datelike, Timelike};
#[cfg(feature = "__internal_bench")]
#[doc(hidden)]
pub use naive::__BenchYearFlags;
-/// Serialization/Deserialization in alternate formats
+/// Serialization/Deserialization with serde.
+///
+/// This module provides default implementations for `DateTime` using the [RFC 3339][1] format and various
+/// alternatives for use with serde's [`with` annotation][1].
///
-/// The various modules in here are intended to be used with serde's [`with`
-/// annotation][1] to serialize as something other than the default [RFC
-/// 3339][2] format.
+/// *Available on crate feature 'serde' only.*
///
-/// [1]: https://serde.rs/attributes.html#field-attributes
-/// [2]: https://tools.ietf.org/html/rfc3339
+/// [1]: https://tools.ietf.org/html/rfc3339
+/// [2]: https://serde.rs/attributes.html#field-attributes
#[cfg(feature = "serde")]
+#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
pub mod serde {
pub use super::datetime::serde::*;
}
-// Until rust 1.18 there is no "pub(crate)" so to share this we need it in the root
-
-#[cfg(feature = "serde")]
-enum SerdeError<V: fmt::Display, D: fmt::Display> {
- NonExistent { timestamp: V },
- Ambiguous { timestamp: V, min: D, max: D },
-}
-
-/// Construct a [`SerdeError::NonExistent`]
-#[cfg(feature = "serde")]
-fn ne_timestamp<T: fmt::Display>(ts: T) -> SerdeError<T, u8> {
- SerdeError::NonExistent::<T, u8> { timestamp: ts }
-}
-
-#[cfg(feature = "serde")]
-impl<V: fmt::Display, D: fmt::Display> fmt::Debug for SerdeError<V, D> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "ChronoSerdeError({})", self)
- }
-}
-
-// impl<V: fmt::Display, D: fmt::Debug> core::error::Error for SerdeError<V, D> {}
-#[cfg(feature = "serde")]
-impl<V: fmt::Display, D: fmt::Display> fmt::Display for SerdeError<V, D> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match self {
- &SerdeError::NonExistent { ref timestamp } => {
- write!(f, "value is not a legal timestamp: {}", timestamp)
- }
- &SerdeError::Ambiguous { ref timestamp, ref min, ref max } => write!(
- f,
- "value is an ambiguous timestamp: {}, could be either of {}, {}",
- timestamp, min, max
- ),
- }
- }
-}
-
-/// The day of week.
-///
-/// The order of the days of week depends on the context.
-/// (This is why this type does *not* implement `PartialOrd` or `Ord` traits.)
-/// One should prefer `*_from_monday` or `*_from_sunday` methods to get the correct result.
-#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)]
-#[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))]
-pub enum Weekday {
- /// Monday.
- Mon = 0,
- /// Tuesday.
- Tue = 1,
- /// Wednesday.
- Wed = 2,
- /// Thursday.
- Thu = 3,
- /// Friday.
- Fri = 4,
- /// Saturday.
- Sat = 5,
- /// Sunday.
- Sun = 6,
-}
-
-impl Weekday {
- /// The next day in the week.
- ///
- /// `w`: | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun`
- /// ----------- | ----- | ----- | ----- | ----- | ----- | ----- | -----
- /// `w.succ()`: | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun` | `Mon`
- #[inline]
- pub fn succ(&self) -> Weekday {
- match *self {
- Weekday::Mon => Weekday::Tue,
- Weekday::Tue => Weekday::Wed,
- Weekday::Wed => Weekday::Thu,
- Weekday::Thu => Weekday::Fri,
- Weekday::Fri => Weekday::Sat,
- Weekday::Sat => Weekday::Sun,
- Weekday::Sun => Weekday::Mon,
- }
- }
-
- /// The previous day in the week.
- ///
- /// `w`: | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun`
- /// ----------- | ----- | ----- | ----- | ----- | ----- | ----- | -----
- /// `w.pred()`: | `Sun` | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat`
- #[inline]
- pub fn pred(&self) -> Weekday {
- match *self {
- Weekday::Mon => Weekday::Sun,
- Weekday::Tue => Weekday::Mon,
- Weekday::Wed => Weekday::Tue,
- Weekday::Thu => Weekday::Wed,
- Weekday::Fri => Weekday::Thu,
- Weekday::Sat => Weekday::Fri,
- Weekday::Sun => Weekday::Sat,
- }
- }
-
- /// Returns a day-of-week number starting from Monday = 1. (ISO 8601 weekday number)
- ///
- /// `w`: | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun`
- /// ------------------------- | ----- | ----- | ----- | ----- | ----- | ----- | -----
- /// `w.number_from_monday()`: | 1 | 2 | 3 | 4 | 5 | 6 | 7
- #[inline]
- pub fn number_from_monday(&self) -> u32 {
- match *self {
- Weekday::Mon => 1,
- Weekday::Tue => 2,
- Weekday::Wed => 3,
- Weekday::Thu => 4,
- Weekday::Fri => 5,
- Weekday::Sat => 6,
- Weekday::Sun => 7,
- }
- }
-
- /// Returns a day-of-week number starting from Sunday = 1.
- ///
- /// `w`: | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun`
- /// ------------------------- | ----- | ----- | ----- | ----- | ----- | ----- | -----
- /// `w.number_from_sunday()`: | 2 | 3 | 4 | 5 | 6 | 7 | 1
- #[inline]
- pub fn number_from_sunday(&self) -> u32 {
- match *self {
- Weekday::Mon => 2,
- Weekday::Tue => 3,
- Weekday::Wed => 4,
- Weekday::Thu => 5,
- Weekday::Fri => 6,
- Weekday::Sat => 7,
- Weekday::Sun => 1,
- }
- }
-
- /// Returns a day-of-week number starting from Monday = 0.
- ///
- /// `w`: | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun`
- /// --------------------------- | ----- | ----- | ----- | ----- | ----- | ----- | -----
- /// `w.num_days_from_monday()`: | 0 | 1 | 2 | 3 | 4 | 5 | 6
- #[inline]
- pub fn num_days_from_monday(&self) -> u32 {
- match *self {
- Weekday::Mon => 0,
- Weekday::Tue => 1,
- Weekday::Wed => 2,
- Weekday::Thu => 3,
- Weekday::Fri => 4,
- Weekday::Sat => 5,
- Weekday::Sun => 6,
- }
- }
-
- /// Returns a day-of-week number starting from Sunday = 0.
- ///
- /// `w`: | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun`
- /// --------------------------- | ----- | ----- | ----- | ----- | ----- | ----- | -----
- /// `w.num_days_from_sunday()`: | 1 | 2 | 3 | 4 | 5 | 6 | 0
- #[inline]
- pub fn num_days_from_sunday(&self) -> u32 {
- match *self {
- Weekday::Mon => 1,
- Weekday::Tue => 2,
- Weekday::Wed => 3,
- Weekday::Thu => 4,
- Weekday::Fri => 5,
- Weekday::Sat => 6,
- Weekday::Sun => 0,
- }
- }
-}
-
-impl fmt::Display for Weekday {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.write_str(match *self {
- Weekday::Mon => "Mon",
- Weekday::Tue => "Tue",
- Weekday::Wed => "Wed",
- Weekday::Thu => "Thu",
- Weekday::Fri => "Fri",
- Weekday::Sat => "Sat",
- Weekday::Sun => "Sun",
- })
- }
-}
-
-/// Any weekday can be represented as an integer from 0 to 6, which equals to
-/// [`Weekday::num_days_from_monday`](#method.num_days_from_monday) in this implementation.
-/// Do not heavily depend on this though; use explicit methods whenever possible.
-impl num_traits::FromPrimitive for Weekday {
- #[inline]
- fn from_i64(n: i64) -> Option<Weekday> {
- match n {
- 0 => Some(Weekday::Mon),
- 1 => Some(Weekday::Tue),
- 2 => Some(Weekday::Wed),
- 3 => Some(Weekday::Thu),
- 4 => Some(Weekday::Fri),
- 5 => Some(Weekday::Sat),
- 6 => Some(Weekday::Sun),
- _ => None,
- }
- }
-
- #[inline]
- fn from_u64(n: u64) -> Option<Weekday> {
- match n {
- 0 => Some(Weekday::Mon),
- 1 => Some(Weekday::Tue),
- 2 => Some(Weekday::Wed),
- 3 => Some(Weekday::Thu),
- 4 => Some(Weekday::Fri),
- 5 => Some(Weekday::Sat),
- 6 => Some(Weekday::Sun),
- _ => None,
- }
- }
-}
-
-use core::fmt;
-
-/// An error resulting from reading `Weekday` value with `FromStr`.
-#[derive(Clone, PartialEq)]
-pub struct ParseWeekdayError {
- _dummy: (),
-}
-
-impl fmt::Debug for ParseWeekdayError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "ParseWeekdayError {{ .. }}")
- }
-}
-
-// the actual `FromStr` implementation is in the `format` module to leverage the existing code
-
-#[cfg(feature = "serde")]
-mod weekday_serde {
- use super::Weekday;
- use core::fmt;
- use serdelib::{de, ser};
-
- impl ser::Serialize for Weekday {
- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- where
- S: ser::Serializer,
- {
- serializer.collect_str(&self)
- }
- }
-
- struct WeekdayVisitor;
-
- impl<'de> de::Visitor<'de> for WeekdayVisitor {
- type Value = Weekday;
-
- fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "Weekday")
- }
-
- fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
- where
- E: de::Error,
- {
- value.parse().map_err(|_| E::custom("short or long weekday names expected"))
- }
- }
-
- impl<'de> de::Deserialize<'de> for Weekday {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: de::Deserializer<'de>,
- {
- deserializer.deserialize_str(WeekdayVisitor)
- }
- }
-
- #[cfg(test)]
- extern crate serde_json;
-
- #[test]
- fn test_serde_serialize() {
- use self::serde_json::to_string;
- use Weekday::*;
-
- let cases: Vec<(Weekday, &str)> = vec![
- (Mon, "\"Mon\""),
- (Tue, "\"Tue\""),
- (Wed, "\"Wed\""),
- (Thu, "\"Thu\""),
- (Fri, "\"Fri\""),
- (Sat, "\"Sat\""),
- (Sun, "\"Sun\""),
- ];
-
- for (weekday, expected_str) in cases {
- let string = to_string(&weekday).unwrap();
- assert_eq!(string, expected_str);
- }
- }
-
- #[test]
- fn test_serde_deserialize() {
- use self::serde_json::from_str;
- use Weekday::*;
-
- let cases: Vec<(&str, Weekday)> = vec![
- ("\"mon\"", Mon),
- ("\"MONDAY\"", Mon),
- ("\"MonDay\"", Mon),
- ("\"mOn\"", Mon),
- ("\"tue\"", Tue),
- ("\"tuesday\"", Tue),
- ("\"wed\"", Wed),
- ("\"wednesday\"", Wed),
- ("\"thu\"", Thu),
- ("\"thursday\"", Thu),
- ("\"fri\"", Fri),
- ("\"friday\"", Fri),
- ("\"sat\"", Sat),
- ("\"saturday\"", Sat),
- ("\"sun\"", Sun),
- ("\"sunday\"", Sun),
- ];
-
- for (str, expected_weekday) in cases {
- let weekday = from_str::<Weekday>(str).unwrap();
- assert_eq!(weekday, expected_weekday);
- }
-
- let errors: Vec<&str> =
- vec!["\"not a weekday\"", "\"monDAYs\"", "\"mond\"", "mon", "\"thur\"", "\"thurs\""];
-
- for str in errors {
- from_str::<Weekday>(str).unwrap_err();
- }
- }
-}
-
-/// The month of the year.
-///
-/// This enum is just a convenience implementation.
-/// The month in dates created by DateLike objects does not return this enum.
-///
-/// It is possible to convert from a date to a month independently
-/// ```
-/// # extern crate num_traits;
-/// use num_traits::FromPrimitive;
-/// use chrono::prelude::*;
-/// let date = Utc.ymd(2019, 10, 28).and_hms(9, 10, 11);
-/// // `2019-10-28T09:10:11Z`
-/// let month = Month::from_u32(date.month());
-/// assert_eq!(month, Some(Month::October))
-/// ```
-/// Or from a Month to an integer usable by dates
-/// ```
-/// # use chrono::prelude::*;
-/// let month = Month::January;
-/// let dt = Utc.ymd(2019, month.number_from_month(), 28).and_hms(9, 10, 11);
-/// assert_eq!((dt.year(), dt.month(), dt.day()), (2019, 1, 28));
-/// ```
-/// Allows mapping from and to month, from 1-January to 12-December.
-/// Can be Serialized/Deserialized with serde
-// Actual implementation is zero-indexed, API intended as 1-indexed for more intuitive behavior.
-#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)]
-#[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))]
-pub enum Month {
- /// January
- January = 0,
- /// February
- February = 1,
- /// March
- March = 2,
- /// April
- April = 3,
- /// May
- May = 4,
- /// June
- June = 5,
- /// July
- July = 6,
- /// August
- August = 7,
- /// September
- September = 8,
- /// October
- October = 9,
- /// November
- November = 10,
- /// December
- December = 11,
-}
-
-impl Month {
- /// The next month.
- ///
- /// `m`: | `January` | `February` | `...` | `December`
- /// ----------- | --------- | ---------- | --- | ---------
- /// `m.succ()`: | `February` | `March` | `...` | `January`
- #[inline]
- pub fn succ(&self) -> Month {
- match *self {
- Month::January => Month::February,
- Month::February => Month::March,
- Month::March => Month::April,
- Month::April => Month::May,
- Month::May => Month::June,
- Month::June => Month::July,
- Month::July => Month::August,
- Month::August => Month::September,
- Month::September => Month::October,
- Month::October => Month::November,
- Month::November => Month::December,
- Month::December => Month::January,
- }
- }
-
- /// The previous month.
- ///
- /// `m`: | `January` | `February` | `...` | `December`
- /// ----------- | --------- | ---------- | --- | ---------
- /// `m.succ()`: | `December` | `January` | `...` | `November`
- #[inline]
- pub fn pred(&self) -> Month {
- match *self {
- Month::January => Month::December,
- Month::February => Month::January,
- Month::March => Month::February,
- Month::April => Month::March,
- Month::May => Month::April,
- Month::June => Month::May,
- Month::July => Month::June,
- Month::August => Month::July,
- Month::September => Month::August,
- Month::October => Month::September,
- Month::November => Month::October,
- Month::December => Month::November,
- }
- }
-
- /// Returns a month-of-year number starting from January = 1.
- ///
- /// `m`: | `January` | `February` | `...` | `December`
- /// -------------------------| --------- | ---------- | --- | -----
- /// `m.number_from_month()`: | 1 | 2 | `...` | 12
- #[inline]
- pub fn number_from_month(&self) -> u32 {
- match *self {
- Month::January => 1,
- Month::February => 2,
- Month::March => 3,
- Month::April => 4,
- Month::May => 5,
- Month::June => 6,
- Month::July => 7,
- Month::August => 8,
- Month::September => 9,
- Month::October => 10,
- Month::November => 11,
- Month::December => 12,
- }
- }
-
- /// Get the name of the month
- ///
- /// ```
- /// use chrono::Month;
- ///
- /// assert_eq!(Month::January.name(), "January")
- /// ```
- pub fn name(&self) -> &'static str {
- match *self {
- Month::January => "January",
- Month::February => "February",
- Month::March => "March",
- Month::April => "April",
- Month::May => "May",
- Month::June => "June",
- Month::July => "July",
- Month::August => "August",
- Month::September => "September",
- Month::October => "October",
- Month::November => "November",
- Month::December => "December",
- }
- }
-}
-
-impl num_traits::FromPrimitive for Month {
- /// Returns an Option<Month> from a i64, assuming a 1-index, January = 1.
- ///
- /// `Month::from_i64(n: i64)`: | `1` | `2` | ... | `12`
- /// ---------------------------| -------------------- | --------------------- | ... | -----
- /// ``: | Some(Month::January) | Some(Month::February) | ... | Some(Month::December)
-
- #[inline]
- fn from_u64(n: u64) -> Option<Month> {
- Self::from_u32(n as u32)
- }
-
- #[inline]
- fn from_i64(n: i64) -> Option<Month> {
- Self::from_u32(n as u32)
- }
-
- #[inline]
- fn from_u32(n: u32) -> Option<Month> {
- match n {
- 1 => Some(Month::January),
- 2 => Some(Month::February),
- 3 => Some(Month::March),
- 4 => Some(Month::April),
- 5 => Some(Month::May),
- 6 => Some(Month::June),
- 7 => Some(Month::July),
- 8 => Some(Month::August),
- 9 => Some(Month::September),
- 10 => Some(Month::October),
- 11 => Some(Month::November),
- 12 => Some(Month::December),
- _ => None,
- }
- }
-}
-
-/// An error resulting from reading `<Month>` value with `FromStr`.
-#[derive(Clone, PartialEq)]
-pub struct ParseMonthError {
- _dummy: (),
-}
-
-impl fmt::Debug for ParseMonthError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "ParseMonthError {{ .. }}")
- }
-}
-
-#[cfg(feature = "serde")]
-mod month_serde {
- use super::Month;
- use serdelib::{de, ser};
-
- use core::fmt;
-
- impl ser::Serialize for Month {
- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- where
- S: ser::Serializer,
- {
- serializer.collect_str(self.name())
- }
- }
-
- struct MonthVisitor;
-
- impl<'de> de::Visitor<'de> for MonthVisitor {
- type Value = Month;
-
- fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "Month")
- }
-
- fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
- where
- E: de::Error,
- {
- value.parse().map_err(|_| E::custom("short (3-letter) or full month names expected"))
- }
- }
-
- impl<'de> de::Deserialize<'de> for Month {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: de::Deserializer<'de>,
- {
- deserializer.deserialize_str(MonthVisitor)
- }
- }
-
- #[cfg(test)]
- extern crate serde_json;
-
- #[test]
- fn test_serde_serialize() {
- use self::serde_json::to_string;
- use Month::*;
-
- let cases: Vec<(Month, &str)> = vec![
- (January, "\"January\""),
- (February, "\"February\""),
- (March, "\"March\""),
- (April, "\"April\""),
- (May, "\"May\""),
- (June, "\"June\""),
- (July, "\"July\""),
- (August, "\"August\""),
- (September, "\"September\""),
- (October, "\"October\""),
- (November, "\"November\""),
- (December, "\"December\""),
- ];
-
- for (month, expected_str) in cases {
- let string = to_string(&month).unwrap();
- assert_eq!(string, expected_str);
- }
- }
-
- #[test]
- fn test_serde_deserialize() {
- use self::serde_json::from_str;
- use Month::*;
-
- let cases: Vec<(&str, Month)> = vec![
- ("\"january\"", January),
- ("\"jan\"", January),
- ("\"FeB\"", February),
- ("\"MAR\"", March),
- ("\"mar\"", March),
- ("\"april\"", April),
- ("\"may\"", May),
- ("\"june\"", June),
- ("\"JULY\"", July),
- ("\"august\"", August),
- ("\"september\"", September),
- ("\"October\"", October),
- ("\"November\"", November),
- ("\"DECEmbEr\"", December),
- ];
-
- for (string, expected_month) in cases {
- let month = from_str::<Month>(string).unwrap();
- assert_eq!(month, expected_month);
- }
-
- let errors: Vec<&str> =
- vec!["\"not a month\"", "\"ja\"", "\"Dece\"", "Dec", "\"Augustin\""];
-
- for string in errors {
- from_str::<Month>(string).unwrap_err();
- }
- }
-}
-
-/// The common set of methods for date component.
-pub trait Datelike: Sized {
- /// Returns the year number in the [calendar date](./naive/struct.NaiveDate.html#calendar-date).
- fn year(&self) -> i32;
-
- /// Returns the absolute year number starting from 1 with a boolean flag,
- /// which is false when the year predates the epoch (BCE/BC) and true otherwise (CE/AD).
- #[inline]
- fn year_ce(&self) -> (bool, u32) {
- let year = self.year();
- if year < 1 {
- (false, (1 - year) as u32)
- } else {
- (true, year as u32)
- }
- }
-
- /// Returns the month number starting from 1.
- ///
- /// The return value ranges from 1 to 12.
- fn month(&self) -> u32;
-
- /// Returns the month number starting from 0.
- ///
- /// The return value ranges from 0 to 11.
- fn month0(&self) -> u32;
-
- /// Returns the day of month starting from 1.
- ///
- /// The return value ranges from 1 to 31. (The last day of month differs by months.)
- fn day(&self) -> u32;
-
- /// Returns the day of month starting from 0.
- ///
- /// The return value ranges from 0 to 30. (The last day of month differs by months.)
- fn day0(&self) -> u32;
-
- /// Returns the day of year starting from 1.
- ///
- /// The return value ranges from 1 to 366. (The last day of year differs by years.)
- fn ordinal(&self) -> u32;
-
- /// Returns the day of year starting from 0.
- ///
- /// The return value ranges from 0 to 365. (The last day of year differs by years.)
- fn ordinal0(&self) -> u32;
-
- /// Returns the day of week.
- fn weekday(&self) -> Weekday;
-
- /// Returns the ISO week.
- fn iso_week(&self) -> IsoWeek;
-
- /// Makes a new value with the year number changed.
- ///
- /// Returns `None` when the resulting value would be invalid.
- fn with_year(&self, year: i32) -> Option<Self>;
-
- /// Makes a new value with the month number (starting from 1) changed.
- ///
- /// Returns `None` when the resulting value would be invalid.
- fn with_month(&self, month: u32) -> Option<Self>;
-
- /// Makes a new value with the month number (starting from 0) changed.
- ///
- /// Returns `None` when the resulting value would be invalid.
- fn with_month0(&self, month0: u32) -> Option<Self>;
-
- /// Makes a new value with the day of month (starting from 1) changed.
- ///
- /// Returns `None` when the resulting value would be invalid.
- fn with_day(&self, day: u32) -> Option<Self>;
-
- /// Makes a new value with the day of month (starting from 0) changed.
- ///
- /// Returns `None` when the resulting value would be invalid.
- fn with_day0(&self, day0: u32) -> Option<Self>;
-
- /// Makes a new value with the day of year (starting from 1) changed.
- ///
- /// Returns `None` when the resulting value would be invalid.
- fn with_ordinal(&self, ordinal: u32) -> Option<Self>;
-
- /// Makes a new value with the day of year (starting from 0) changed.
- ///
- /// Returns `None` when the resulting value would be invalid.
- fn with_ordinal0(&self, ordinal0: u32) -> Option<Self>;
-
- /// Counts the days in the proleptic Gregorian calendar, with January 1, Year 1 (CE) as day 1.
- ///
- /// # Examples
- ///
- /// ```
- /// use chrono::{NaiveDate, Datelike};
- ///
- /// assert_eq!(NaiveDate::from_ymd(1970, 1, 1).num_days_from_ce(), 719_163);
- /// assert_eq!(NaiveDate::from_ymd(2, 1, 1).num_days_from_ce(), 366);
- /// assert_eq!(NaiveDate::from_ymd(1, 1, 1).num_days_from_ce(), 1);
- /// assert_eq!(NaiveDate::from_ymd(0, 1, 1).num_days_from_ce(), -365);
- /// ```
- fn num_days_from_ce(&self) -> i32 {
- // See test_num_days_from_ce_against_alternative_impl below for a more straightforward
- // implementation.
-
- // we know this wouldn't overflow since year is limited to 1/2^13 of i32's full range.
- let mut year = self.year() - 1;
- let mut ndays = 0;
- if year < 0 {
- let excess = 1 + (-year) / 400;
- year += excess * 400;
- ndays -= excess * 146_097;
- }
- let div_100 = year / 100;
- ndays += ((year * 1461) >> 2) - div_100 + (div_100 >> 2);
- ndays + self.ordinal() as i32
- }
-}
-
-/// The common set of methods for time component.
-pub trait Timelike: Sized {
- /// Returns the hour number from 0 to 23.
- fn hour(&self) -> u32;
-
- /// Returns the hour number from 1 to 12 with a boolean flag,
- /// which is false for AM and true for PM.
- #[inline]
- fn hour12(&self) -> (bool, u32) {
- let hour = self.hour();
- let mut hour12 = hour % 12;
- if hour12 == 0 {
- hour12 = 12;
- }
- (hour >= 12, hour12)
- }
-
- /// Returns the minute number from 0 to 59.
- fn minute(&self) -> u32;
-
- /// Returns the second number from 0 to 59.
- fn second(&self) -> u32;
-
- /// Returns the number of nanoseconds since the whole non-leap second.
- /// The range from 1,000,000,000 to 1,999,999,999 represents
- /// the [leap second](./naive/struct.NaiveTime.html#leap-second-handling).
- fn nanosecond(&self) -> u32;
-
- /// Makes a new value with the hour number changed.
- ///
- /// Returns `None` when the resulting value would be invalid.
- fn with_hour(&self, hour: u32) -> Option<Self>;
-
- /// Makes a new value with the minute number changed.
- ///
- /// Returns `None` when the resulting value would be invalid.
- fn with_minute(&self, min: u32) -> Option<Self>;
-
- /// Makes a new value with the second number changed.
- ///
- /// Returns `None` when the resulting value would be invalid.
- /// As with the [`second`](#tymethod.second) method,
- /// the input range is restricted to 0 through 59.
- fn with_second(&self, sec: u32) -> Option<Self>;
-
- /// Makes a new value with nanoseconds since the whole non-leap second changed.
- ///
- /// Returns `None` when the resulting value would be invalid.
- /// As with the [`nanosecond`](#tymethod.nanosecond) method,
- /// the input range can exceed 1,000,000,000 for leap seconds.
- fn with_nanosecond(&self, nano: u32) -> Option<Self>;
-
- /// Returns the number of non-leap seconds past the last midnight.
- #[inline]
- fn num_seconds_from_midnight(&self) -> u32 {
- self.hour() * 3600 + self.minute() * 60 + self.second()
- }
-}
-
+/// MSRV 1.42
#[cfg(test)]
-extern crate num_iter;
-
-mod test {
- #[allow(unused_imports)]
- use super::*;
-
- #[test]
- fn test_readme_doomsday() {
- use num_iter::range_inclusive;
-
- for y in range_inclusive(naive::MIN_DATE.year(), naive::MAX_DATE.year()) {
- // even months
- let d4 = NaiveDate::from_ymd(y, 4, 4);
- let d6 = NaiveDate::from_ymd(y, 6, 6);
- let d8 = NaiveDate::from_ymd(y, 8, 8);
- let d10 = NaiveDate::from_ymd(y, 10, 10);
- let d12 = NaiveDate::from_ymd(y, 12, 12);
-
- // nine to five, seven-eleven
- let d59 = NaiveDate::from_ymd(y, 5, 9);
- let d95 = NaiveDate::from_ymd(y, 9, 5);
- let d711 = NaiveDate::from_ymd(y, 7, 11);
- let d117 = NaiveDate::from_ymd(y, 11, 7);
-
- // "March 0"
- let d30 = NaiveDate::from_ymd(y, 3, 1).pred();
-
- let weekday = d30.weekday();
- let other_dates = [d4, d6, d8, d10, d12, d59, d95, d711, d117];
- assert!(other_dates.iter().all(|d| d.weekday() == weekday));
+#[macro_export]
+macro_rules! matches {
+ ($expression:expr, $(|)? $( $pattern:pat )|+ $( if $guard: expr )? $(,)?) => {
+ match $expression {
+ $( $pattern )|+ $( if $guard )? => true,
+ _ => false
}
}
-
- #[test]
- fn test_month_enum_primitive_parse() {
- use num_traits::FromPrimitive;
-
- let jan_opt = Month::from_u32(1);
- let feb_opt = Month::from_u64(2);
- let dec_opt = Month::from_i64(12);
- let no_month = Month::from_u32(13);
- assert_eq!(jan_opt, Some(Month::January));
- assert_eq!(feb_opt, Some(Month::February));
- assert_eq!(dec_opt, Some(Month::December));
- assert_eq!(no_month, None);
-
- let date = Utc.ymd(2019, 10, 28).and_hms(9, 10, 11);
- assert_eq!(Month::from_u32(date.month()), Some(Month::October));
-
- let month = Month::January;
- let dt = Utc.ymd(2019, month.number_from_month(), 28).and_hms(9, 10, 11);
- assert_eq!((dt.year(), dt.month(), dt.day()), (2019, 1, 28));
- }
-}
-
-/// Tests `Datelike::num_days_from_ce` against an alternative implementation.
-///
-/// The alternative implementation is not as short as the current one but it is simpler to
-/// understand, with less unexplained magic constants.
-#[test]
-fn test_num_days_from_ce_against_alternative_impl() {
- /// Returns the number of multiples of `div` in the range `start..end`.
- ///
- /// If the range `start..end` is back-to-front, i.e. `start` is greater than `end`, the
- /// behaviour is defined by the following equation:
- /// `in_between(start, end, div) == - in_between(end, start, div)`.
- ///
- /// When `div` is 1, this is equivalent to `end - start`, i.e. the length of `start..end`.
- ///
- /// # Panics
- ///
- /// Panics if `div` is not positive.
- fn in_between(start: i32, end: i32, div: i32) -> i32 {
- assert!(div > 0, "in_between: nonpositive div = {}", div);
- let start = (start.div_euclid(div), start.rem_euclid(div));
- let end = (end.div_euclid(div), end.rem_euclid(div));
- // The lowest multiple of `div` greater than or equal to `start`, divided.
- let start = start.0 + (start.1 != 0) as i32;
- // The lowest multiple of `div` greater than or equal to `end`, divided.
- let end = end.0 + (end.1 != 0) as i32;
- end - start
- }
-
- /// Alternative implementation to `Datelike::num_days_from_ce`
- fn num_days_from_ce<Date: Datelike>(date: &Date) -> i32 {
- let year = date.year();
- let diff = move |div| in_between(1, year, div);
- // 365 days a year, one more in leap years. In the gregorian calendar, leap years are all
- // the multiples of 4 except multiples of 100 but including multiples of 400.
- date.ordinal() as i32 + 365 * diff(1) + diff(4) - diff(100) + diff(400)
- }
-
- use num_iter::range_inclusive;
-
- for year in range_inclusive(naive::MIN_DATE.year(), naive::MAX_DATE.year()) {
- let jan1_year = NaiveDate::from_ymd(year, 1, 1);
- assert_eq!(
- jan1_year.num_days_from_ce(),
- num_days_from_ce(&jan1_year),
- "on {:?}",
- jan1_year
- );
- let mid_year = jan1_year + Duration::days(133);
- assert_eq!(mid_year.num_days_from_ce(), num_days_from_ce(&mid_year), "on {:?}", mid_year);
- }
-}
-
-#[test]
-fn test_month_enum_succ_pred() {
- assert_eq!(Month::January.succ(), Month::February);
- assert_eq!(Month::December.succ(), Month::January);
- assert_eq!(Month::January.pred(), Month::December);
- assert_eq!(Month::February.pred(), Month::January);
}