From a0b8f38ab54ac451646aa00cd5e91b6c76f22a84 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 30 May 2024 05:57:19 +0200 Subject: Merging upstream version 1.72.1+dfsg1. Signed-off-by: Daniel Baumann --- vendor/chrono/src/naive/date.rs | 281 ++++++++++++++++++++--------- vendor/chrono/src/naive/datetime/mod.rs | 220 +++++++++++------------ vendor/chrono/src/naive/datetime/serde.rs | 52 ++++-- vendor/chrono/src/naive/datetime/tests.rs | 10 +- vendor/chrono/src/naive/internals.rs | 287 +++++++++++++++++++----------- vendor/chrono/src/naive/isoweek.rs | 45 ++++- vendor/chrono/src/naive/time/mod.rs | 108 +++++++---- 7 files changed, 655 insertions(+), 348 deletions(-) (limited to 'vendor/chrono/src/naive') diff --git a/vendor/chrono/src/naive/date.rs b/vendor/chrono/src/naive/date.rs index 64af978f3..b9404a15f 100644 --- a/vendor/chrono/src/naive/date.rs +++ b/vendor/chrono/src/naive/date.rs @@ -5,12 +5,9 @@ #[cfg(any(feature = "alloc", feature = "std", test))] use core::borrow::Borrow; -use core::convert::TryFrom; use core::ops::{Add, AddAssign, RangeInclusive, Sub, SubAssign}; use core::{fmt, str}; -use num_integer::div_mod_floor; -use num_traits::ToPrimitive; #[cfg(feature = "rkyv")] use rkyv::{Archive, Deserialize, Serialize}; @@ -20,8 +17,10 @@ use pure_rust_locales::Locale; #[cfg(any(feature = "alloc", feature = "std", test))] use crate::format::DelayedFormat; -use crate::format::{parse, write_hundreds, ParseError, ParseResult, Parsed, StrftimeItems}; -use crate::format::{Item, Numeric, Pad}; +use crate::format::{ + parse, parse_and_remainder, write_hundreds, Item, Numeric, Pad, ParseError, ParseResult, + Parsed, StrftimeItems, +}; use crate::month::Months; use crate::naive::{IsoWeek, NaiveDateTime, NaiveTime}; use crate::oldtime::Duration as OldDuration; @@ -77,11 +76,15 @@ impl NaiveWeek { /// assert!(week.first_day() <= date); /// ``` #[inline] + #[must_use] pub fn first_day(&self) -> NaiveDate { - let start = self.start.num_days_from_monday(); - let end = self.date.weekday().num_days_from_monday(); - let days = if start > end { 7 - start + end } else { end - start }; - self.date - Duration::days(days.into()) + let start = self.start.num_days_from_monday() as i32; + let ref_day = self.date.weekday().num_days_from_monday() as i32; + // Calculate the number of days to subtract from `self.date`. + // Do not construct an intermediate date beyond `self.date`, because that may be out of + // range if `date` is close to `NaiveDate::MAX`. + let days = start - ref_day - if start > ref_day { 7 } else { 0 }; + self.date.diff_days(days as i64).unwrap() } /// Returns a date representing the last day of the week. @@ -96,8 +99,15 @@ impl NaiveWeek { /// assert!(week.last_day() >= date); /// ``` #[inline] + #[must_use] pub fn last_day(&self) -> NaiveDate { - self.first_day() + Duration::days(6) + let end = self.start.pred().num_days_from_monday() as i32; + let ref_day = self.date.weekday().num_days_from_monday() as i32; + // Calculate the number of days to add to `self.date`. + // Do not construct an intermediate date before `self.date` (like with `first_day()`), + // because that may be out of range if `date` is close to `NaiveDate::MIN`. + let days = end - ref_day + if end < ref_day { 7 } else { 0 }; + self.date.diff_days(days as i64).unwrap() } /// Returns a [`RangeInclusive`] representing the whole week bounded by @@ -115,6 +125,7 @@ impl NaiveWeek { /// assert!(days.contains(&date)); /// ``` #[inline] + #[must_use] pub fn days(&self) -> RangeInclusive { self.first_day()..=self.last_day() } @@ -137,8 +148,7 @@ impl Days { } /// ISO 8601 calendar date without timezone. -/// Allows for every [proleptic Gregorian date](#calendar-date) -/// from Jan 1, 262145 BCE to Dec 31, 262143 CE. +/// Allows for every [proleptic Gregorian date] from Jan 1, 262145 BCE to Dec 31, 262143 CE. /// Also supports the conversion from ISO 8601 ordinal and week date. /// /// # Calendar Date @@ -184,6 +194,8 @@ impl Days { /// The year number is the same as that of the [calendar date](#calendar-date). /// /// This is currently the internal format of Chrono's date types. +/// +/// [proleptic Gregorian date]: crate::NaiveDate#calendar-date #[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Copy, Clone)] #[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))] pub struct NaiveDate { @@ -239,19 +251,35 @@ impl NaiveDate { pub(crate) fn weeks_from(&self, day: Weekday) -> i32 { (self.ordinal() as i32 - self.weekday().num_days_from(day) as i32 + 6) / 7 } - /// Makes a new `NaiveDate` from year and packed ordinal-flags, with a verification. - fn from_of(year: i32, of: Of) -> Option { - if (MIN_YEAR..=MAX_YEAR).contains(&year) && of.valid() { - let Of(of) = of; - Some(NaiveDate { ymdf: (year << 13) | (of as DateImpl) }) - } else { - None + + /// Makes a new `NaiveDate` from year, ordinal and flags. + /// Does not check whether the flags are correct for the provided year. + const fn from_ordinal_and_flags( + year: i32, + ordinal: u32, + flags: YearFlags, + ) -> Option { + if year < MIN_YEAR || year > MAX_YEAR { + return None; // Out-of-range + } + // Enable debug check once the MSRV >= 1.57 (panicking in const feature) + // debug_assert!(YearFlags::from_year(year).0 == flags.0); + match Of::new(ordinal, flags) { + Some(of) => Some(NaiveDate { ymdf: (year << 13) | (of.inner() as DateImpl) }), + None => None, // Invalid: Ordinal outside of the nr of days in a year with those flags. } } - /// Makes a new `NaiveDate` from year and packed month-day-flags, with a verification. - fn from_mdf(year: i32, mdf: Mdf) -> Option { - NaiveDate::from_of(year, mdf.to_of()) + /// Makes a new `NaiveDate` from year and packed month-day-flags. + /// Does not check whether the flags are correct for the provided year. + const fn from_mdf(year: i32, mdf: Mdf) -> Option { + if year < MIN_YEAR || year > MAX_YEAR { + return None; // Out-of-range + } + match mdf.to_of() { + Some(of) => Some(NaiveDate { ymdf: (year << 13) | (of.inner() as DateImpl) }), + None => None, // Non-existing date + } } /// Makes a new `NaiveDate` from the [calendar date](#calendar-date) @@ -259,6 +287,7 @@ impl NaiveDate { /// /// Panics on the out-of-range date, invalid month and/or day. #[deprecated(since = "0.4.23", note = "use `from_ymd_opt()` instead")] + #[must_use] pub fn from_ymd(year: i32, month: u32, day: u32) -> NaiveDate { NaiveDate::from_ymd_opt(year, month, day).expect("invalid or out-of-range date") } @@ -282,6 +311,7 @@ impl NaiveDate { /// assert!(from_ymd_opt(400000, 1, 1).is_none()); /// assert!(from_ymd_opt(-400000, 1, 1).is_none()); /// ``` + #[must_use] pub fn from_ymd_opt(year: i32, month: u32, day: u32) -> Option { let flags = YearFlags::from_year(year); NaiveDate::from_mdf(year, Mdf::new(month, day, flags)?) @@ -292,6 +322,7 @@ impl NaiveDate { /// /// Panics on the out-of-range date and/or invalid day of year. #[deprecated(since = "0.4.23", note = "use `from_yo_opt()` instead")] + #[must_use] pub fn from_yo(year: i32, ordinal: u32) -> NaiveDate { NaiveDate::from_yo_opt(year, ordinal).expect("invalid or out-of-range date") } @@ -316,9 +347,10 @@ impl NaiveDate { /// assert!(from_yo_opt(400000, 1).is_none()); /// assert!(from_yo_opt(-400000, 1).is_none()); /// ``` + #[must_use] pub fn from_yo_opt(year: i32, ordinal: u32) -> Option { let flags = YearFlags::from_year(year); - NaiveDate::from_of(year, Of::new(ordinal, flags)?) + NaiveDate::from_ordinal_and_flags(year, ordinal, flags) } /// Makes a new `NaiveDate` from the [ISO week date](#week-date) @@ -327,6 +359,7 @@ impl NaiveDate { /// /// Panics on the out-of-range date and/or invalid week number. #[deprecated(since = "0.4.23", note = "use `from_isoywd_opt()` instead")] + #[must_use] pub fn from_isoywd(year: i32, week: u32, weekday: Weekday) -> NaiveDate { NaiveDate::from_isoywd_opt(year, week, weekday).expect("invalid or out-of-range date") } @@ -342,7 +375,7 @@ impl NaiveDate { /// ``` /// use chrono::{NaiveDate, Weekday}; /// - /// let from_ymd = NaiveDate::from_ymd; + /// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); /// let from_isoywd_opt = NaiveDate::from_isoywd_opt; /// /// assert_eq!(from_isoywd_opt(2015, 0, Weekday::Sun), None); @@ -358,7 +391,7 @@ impl NaiveDate { /// /// ``` /// # use chrono::{NaiveDate, Weekday}; - /// # let from_ymd = NaiveDate::from_ymd; + /// # let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); /// # let from_isoywd_opt = NaiveDate::from_isoywd_opt; /// // Mo Tu We Th Fr Sa Su /// // 2014-W52 22 23 24 25 26 27 28 has 4+ days of new year, @@ -375,6 +408,7 @@ impl NaiveDate { /// assert_eq!(from_isoywd_opt(2015, 54, Weekday::Mon), None); /// assert_eq!(from_isoywd_opt(2016, 1, Weekday::Mon), Some(from_ymd(2016, 1, 4))); /// ``` + #[must_use] pub fn from_isoywd_opt(year: i32, week: u32, weekday: Weekday) -> Option { let flags = YearFlags::from_year(year); let nweeks = flags.nisoweeks(); @@ -385,20 +419,21 @@ impl NaiveDate { if weekord <= delta { // ordinal < 1, previous year let prevflags = YearFlags::from_year(year - 1); - NaiveDate::from_of( + NaiveDate::from_ordinal_and_flags( year - 1, - Of::new(weekord + prevflags.ndays() - delta, prevflags)?, + weekord + prevflags.ndays() - delta, + prevflags, ) } else { let ordinal = weekord - delta; let ndays = flags.ndays(); if ordinal <= ndays { // this year - NaiveDate::from_of(year, Of::new(ordinal, flags)?) + NaiveDate::from_ordinal_and_flags(year, ordinal, flags) } else { // ordinal > ndays, next year let nextflags = YearFlags::from_year(year + 1); - NaiveDate::from_of(year + 1, Of::new(ordinal - ndays, nextflags)?) + NaiveDate::from_ordinal_and_flags(year + 1, ordinal - ndays, nextflags) } } } else { @@ -412,6 +447,7 @@ impl NaiveDate { /// Panics if the date is out of range. #[deprecated(since = "0.4.23", note = "use `from_num_days_from_ce_opt()` instead")] #[inline] + #[must_use] pub fn from_num_days_from_ce(days: i32) -> NaiveDate { NaiveDate::from_num_days_from_ce_opt(days).expect("out-of-range date") } @@ -436,12 +472,13 @@ impl NaiveDate { /// assert_eq!(from_ndays_opt(100_000_000), None); /// assert_eq!(from_ndays_opt(-100_000_000), None); /// ``` + #[must_use] pub fn from_num_days_from_ce_opt(days: i32) -> Option { - let days = days + 365; // make December 31, 1 BCE equal to day 0 + let days = days.checked_add(365)?; // make December 31, 1 BCE equal to day 0 let (year_div_400, cycle) = div_mod_floor(days, 146_097); let (year_mod_400, ordinal) = internals::cycle_to_yo(cycle as u32); let flags = YearFlags::from_year_mod_400(year_mod_400 as i32); - NaiveDate::from_of(year_div_400 * 400 + year_mod_400 as i32, Of::new(ordinal, flags)?) + NaiveDate::from_ordinal_and_flags(year_div_400 * 400 + year_mod_400 as i32, ordinal, flags) } /// Makes a new `NaiveDate` by counting the number of occurrences of a particular day-of-week @@ -455,6 +492,7 @@ impl NaiveDate { /// /// `n` is 1-indexed. Passing `n=0` will cause a panic. #[deprecated(since = "0.4.23", note = "use `from_weekday_of_month_opt()` instead")] + #[must_use] pub fn from_weekday_of_month(year: i32, month: u32, weekday: Weekday, n: u8) -> NaiveDate { NaiveDate::from_weekday_of_month_opt(year, month, weekday, n).expect("out-of-range date") } @@ -471,6 +509,7 @@ impl NaiveDate { /// /// Returns `None` if `n` out-of-range; ie. if `n` is larger than the number of `weekday` in /// `month` (eg. the 6th Friday of March 2017), or if `n == 0`. + #[must_use] pub fn from_weekday_of_month_opt( year: i32, month: u32, @@ -534,6 +573,28 @@ impl NaiveDate { parsed.to_naive_date() } + /// Parses a string from a user-specified format into a new `NaiveDate` value, and a slice with + /// the remaining portion of the string. + /// See the [`format::strftime` module](../format/strftime/index.html) + /// on the supported escape sequences. + /// + /// Similar to [`parse_from_str`](#method.parse_from_str). + /// + /// # Example + /// + /// ```rust + /// # use chrono::{NaiveDate}; + /// let (date, remainder) = NaiveDate::parse_and_remainder( + /// "2015-02-18 trailing text", "%Y-%m-%d").unwrap(); + /// assert_eq!(date, NaiveDate::from_ymd_opt(2015, 2, 18).unwrap()); + /// assert_eq!(remainder, " trailing text"); + /// ``` + pub fn parse_and_remainder<'a>(s: &'a str, fmt: &str) -> ParseResult<(NaiveDate, &'a str)> { + let mut parsed = Parsed::new(); + let remainder = parse_and_remainder(&mut parsed, s, StrftimeItems::new(fmt))?; + parsed.to_naive_date().map(|d| (d, remainder)) + } + /// Add a duration in [`Months`] to the date /// /// If the day would be out of range for the resulting month, use the last day for that month. @@ -551,6 +612,7 @@ impl NaiveDate { /// Some(NaiveDate::from_ymd_opt(2022, 9, 30).unwrap()) /// ); /// ``` + #[must_use] pub fn checked_add_months(self, months: Months) -> Option { if months.0 == 0 { return Some(self); @@ -581,6 +643,7 @@ impl NaiveDate { /// None /// ); /// ``` + #[must_use] pub fn checked_sub_months(self, months: Months) -> Option { if months.0 == 0 { return Some(self); @@ -654,6 +717,7 @@ impl NaiveDate { /// None /// ); /// ``` + #[must_use] pub fn checked_add_days(self, days: Days) -> Option { if days.0 == 0 { return Some(self); @@ -677,6 +741,7 @@ impl NaiveDate { /// None /// ); /// ``` + #[must_use] pub fn checked_sub_days(self, days: Days) -> Option { if days.0 == 0 { return Some(self); @@ -708,6 +773,7 @@ impl NaiveDate { /// assert_eq!(dt.time(), t); /// ``` #[inline] + #[must_use] pub const fn and_time(&self, time: NaiveTime) -> NaiveDateTime { NaiveDateTime::new(*self, time) } @@ -720,6 +786,7 @@ impl NaiveDate { /// Panics on invalid hour, minute and/or second. #[deprecated(since = "0.4.23", note = "use `and_hms_opt()` instead")] #[inline] + #[must_use] pub fn and_hms(&self, hour: u32, min: u32, sec: u32) -> NaiveDateTime { self.and_hms_opt(hour, min, sec).expect("invalid time") } @@ -743,6 +810,7 @@ impl NaiveDate { /// assert!(d.and_hms_opt(24, 34, 56).is_none()); /// ``` #[inline] + #[must_use] pub fn and_hms_opt(&self, hour: u32, min: u32, sec: u32) -> Option { NaiveTime::from_hms_opt(hour, min, sec).map(|time| self.and_time(time)) } @@ -755,6 +823,7 @@ impl NaiveDate { /// Panics on invalid hour, minute, second and/or millisecond. #[deprecated(since = "0.4.23", note = "use `and_hms_milli_opt()` instead")] #[inline] + #[must_use] pub fn and_hms_milli(&self, hour: u32, min: u32, sec: u32, milli: u32) -> NaiveDateTime { self.and_hms_milli_opt(hour, min, sec, milli).expect("invalid time") } @@ -780,6 +849,7 @@ impl NaiveDate { /// assert!(d.and_hms_milli_opt(24, 34, 56, 789).is_none()); /// ``` #[inline] + #[must_use] pub fn and_hms_milli_opt( &self, hour: u32, @@ -804,7 +874,7 @@ impl NaiveDate { /// /// let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap(); /// - /// let dt: NaiveDateTime = d.and_hms_micro(12, 34, 56, 789_012); + /// let dt: NaiveDateTime = d.and_hms_micro_opt(12, 34, 56, 789_012).unwrap(); /// assert_eq!(dt.year(), 2015); /// assert_eq!(dt.weekday(), Weekday::Wed); /// assert_eq!(dt.second(), 56); @@ -812,6 +882,7 @@ impl NaiveDate { /// ``` #[deprecated(since = "0.4.23", note = "use `and_hms_micro_opt()` instead")] #[inline] + #[must_use] pub fn and_hms_micro(&self, hour: u32, min: u32, sec: u32, micro: u32) -> NaiveDateTime { self.and_hms_micro_opt(hour, min, sec, micro).expect("invalid time") } @@ -837,6 +908,7 @@ impl NaiveDate { /// assert!(d.and_hms_micro_opt(24, 34, 56, 789_012).is_none()); /// ``` #[inline] + #[must_use] pub fn and_hms_micro_opt( &self, hour: u32, @@ -855,6 +927,7 @@ impl NaiveDate { /// Panics on invalid hour, minute, second and/or nanosecond. #[deprecated(since = "0.4.23", note = "use `and_hms_nano_opt()` instead")] #[inline] + #[must_use] pub fn and_hms_nano(&self, hour: u32, min: u32, sec: u32, nano: u32) -> NaiveDateTime { self.and_hms_nano_opt(hour, min, sec, nano).expect("invalid time") } @@ -880,6 +953,7 @@ impl NaiveDate { /// assert!(d.and_hms_nano_opt(24, 34, 56, 789_012_345).is_none()); /// ``` #[inline] + #[must_use] pub fn and_hms_nano_opt( &self, hour: u32, @@ -899,7 +973,7 @@ impl NaiveDate { /// Returns the packed ordinal-flags. #[inline] const fn of(&self) -> Of { - Of((self.ymdf & 0b1_1111_1111_1111) as u32) + Of::from_date_impl(self.ymdf) } /// Makes a new `NaiveDate` with the packed month-day-flags changed. @@ -907,20 +981,16 @@ impl NaiveDate { /// Returns `None` when the resulting `NaiveDate` would be invalid. #[inline] fn with_mdf(&self, mdf: Mdf) -> Option { - self.with_of(mdf.to_of()) + Some(self.with_of(mdf.to_of()?)) } /// Makes a new `NaiveDate` with the packed ordinal-flags changed. /// /// Returns `None` when the resulting `NaiveDate` would be invalid. + /// Does not check if the year flags match the year. #[inline] - fn with_of(&self, of: Of) -> Option { - if of.valid() { - let Of(of) = of; - Some(NaiveDate { ymdf: (self.ymdf & !0b1_1111_1111_1111) | of as DateImpl }) - } else { - None - } + const fn with_of(&self, of: Of) -> NaiveDate { + NaiveDate { ymdf: (self.ymdf & !0b1_1111_1111_1111) | of.inner() as DateImpl } } /// Makes a new `NaiveDate` for the next calendar date. @@ -928,6 +998,7 @@ impl NaiveDate { /// Panics when `self` is the last representable date. #[deprecated(since = "0.4.23", note = "use `succ_opt()` instead")] #[inline] + #[must_use] pub fn succ(&self) -> NaiveDate { self.succ_opt().expect("out of bound") } @@ -946,8 +1017,12 @@ impl NaiveDate { /// assert_eq!(NaiveDate::MAX.succ_opt(), None); /// ``` #[inline] + #[must_use] pub fn succ_opt(&self) -> Option { - self.with_of(self.of().succ()).or_else(|| NaiveDate::from_ymd_opt(self.year() + 1, 1, 1)) + match self.of().succ() { + Some(of) => Some(self.with_of(of)), + None => NaiveDate::from_ymd_opt(self.year() + 1, 1, 1), + } } /// Makes a new `NaiveDate` for the previous calendar date. @@ -955,6 +1030,7 @@ impl NaiveDate { /// Panics when `self` is the first representable date. #[deprecated(since = "0.4.23", note = "use `pred_opt()` instead")] #[inline] + #[must_use] pub fn pred(&self) -> NaiveDate { self.pred_opt().expect("out of bound") } @@ -973,8 +1049,12 @@ impl NaiveDate { /// assert_eq!(NaiveDate::MIN.pred_opt(), None); /// ``` #[inline] + #[must_use] pub fn pred_opt(&self) -> Option { - self.with_of(self.of().pred()).or_else(|| NaiveDate::from_ymd_opt(self.year() - 1, 12, 31)) + match self.of().pred() { + Some(of) => Some(self.with_of(of)), + None => NaiveDate::from_ymd_opt(self.year() - 1, 12, 31), + } } /// Adds the `days` part of given `Duration` to the current date. @@ -995,17 +1075,18 @@ impl NaiveDate { /// assert_eq!(d.checked_add_signed(Duration::days(-1_000_000_000)), None); /// assert_eq!(NaiveDate::MAX.checked_add_signed(Duration::days(1)), None); /// ``` + #[must_use] pub fn checked_add_signed(self, rhs: OldDuration) -> Option { let year = self.year(); let (mut year_div_400, year_mod_400) = div_mod_floor(year, 400); let cycle = internals::yo_to_cycle(year_mod_400 as u32, self.of().ordinal()); - let cycle = (cycle as i32).checked_add(rhs.num_days().to_i32()?)?; + let cycle = (cycle as i32).checked_add(i32::try_from(rhs.num_days()).ok()?)?; let (cycle_div_400y, cycle) = div_mod_floor(cycle, 146_097); year_div_400 += cycle_div_400y; let (year_mod_400, ordinal) = internals::cycle_to_yo(cycle as u32); let flags = YearFlags::from_year_mod_400(year_mod_400 as i32); - NaiveDate::from_of(year_div_400 * 400 + year_mod_400 as i32, Of::new(ordinal, flags)?) + NaiveDate::from_ordinal_and_flags(year_div_400 * 400 + year_mod_400 as i32, ordinal, flags) } /// Subtracts the `days` part of given `Duration` from the current date. @@ -1026,17 +1107,18 @@ impl NaiveDate { /// assert_eq!(d.checked_sub_signed(Duration::days(-1_000_000_000)), None); /// assert_eq!(NaiveDate::MIN.checked_sub_signed(Duration::days(1)), None); /// ``` + #[must_use] pub fn checked_sub_signed(self, rhs: OldDuration) -> Option { let year = self.year(); let (mut year_div_400, year_mod_400) = div_mod_floor(year, 400); let cycle = internals::yo_to_cycle(year_mod_400 as u32, self.of().ordinal()); - let cycle = (cycle as i32).checked_sub(rhs.num_days().to_i32()?)?; + let cycle = (cycle as i32).checked_sub(i32::try_from(rhs.num_days()).ok()?)?; let (cycle_div_400y, cycle) = div_mod_floor(cycle, 146_097); year_div_400 += cycle_div_400y; let (year_mod_400, ordinal) = internals::cycle_to_yo(cycle as u32); let flags = YearFlags::from_year_mod_400(year_mod_400 as i32); - NaiveDate::from_of(year_div_400 * 400 + year_mod_400 as i32, Of::new(ordinal, flags)?) + NaiveDate::from_ordinal_and_flags(year_div_400 * 400 + year_mod_400 as i32, ordinal, flags) } /// Subtracts another `NaiveDate` from the current date. @@ -1050,7 +1132,7 @@ impl NaiveDate { /// ``` /// use chrono::{Duration, NaiveDate}; /// - /// let from_ymd = NaiveDate::from_ymd; + /// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); /// let since = NaiveDate::signed_duration_since; /// /// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2014, 1, 1)), Duration::zero()); @@ -1061,6 +1143,7 @@ impl NaiveDate { /// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2010, 1, 1)), Duration::days(365*4 + 1)); /// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(1614, 1, 1)), Duration::days(365*400 + 97)); /// ``` + #[must_use] pub fn signed_duration_since(self, rhs: NaiveDate) -> OldDuration { let year1 = self.year(); let year2 = rhs.year(); @@ -1074,6 +1157,7 @@ impl NaiveDate { } /// Returns the number of whole years from the given `base` until `self`. + #[must_use] pub fn years_since(&self, base: Self) -> Option { let mut years = self.year() - base.year(); if (self.month(), self.day()) < (base.month(), base.day()) { @@ -1116,6 +1200,7 @@ impl NaiveDate { #[cfg(any(feature = "alloc", feature = "std", test))] #[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))] #[inline] + #[must_use] pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat where I: Iterator + Clone, @@ -1159,6 +1244,7 @@ impl NaiveDate { #[cfg(any(feature = "alloc", feature = "std", test))] #[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))] #[inline] + #[must_use] pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat> { self.format_with_items(StrftimeItems::new(fmt)) } @@ -1167,6 +1253,7 @@ impl NaiveDate { #[cfg(feature = "unstable-locales")] #[cfg_attr(docsrs, doc(cfg(feature = "unstable-locales")))] #[inline] + #[must_use] pub fn format_localized_with_items<'a, I, B>( &self, items: I, @@ -1186,6 +1273,7 @@ impl NaiveDate { #[cfg(feature = "unstable-locales")] #[cfg_attr(docsrs, doc(cfg(feature = "unstable-locales")))] #[inline] + #[must_use] pub fn format_localized<'a>( &self, fmt: &'a str, @@ -1345,7 +1433,7 @@ impl Datelike for NaiveDate { /// let d = NaiveDate::from_ymd_opt(y, m, 1).unwrap(); /// /// // ...is preceded by the last day of the original month - /// d.pred().day() + /// d.pred_opt().unwrap().day() /// } /// /// assert_eq!(ndays_in_month(2015, 8), 31); @@ -1401,7 +1489,7 @@ impl Datelike for NaiveDate { /// let d = NaiveDate::from_ymd_opt(year + 1, 1, 1).unwrap(); /// /// // ...is preceded by the last day of the original year - /// d.pred().ordinal() + /// d.pred_opt().unwrap().ordinal() /// } /// /// assert_eq!(ndays_in_year(2015), 365); @@ -1521,7 +1609,8 @@ impl Datelike for NaiveDate { /// ``` #[inline] fn with_month0(&self, month0: u32) -> Option { - self.with_mdf(self.mdf().with_month(month0 + 1)?) + let month = month0.checked_add(1)?; + self.with_mdf(self.mdf().with_month(month)?) } /// Makes a new `NaiveDate` with the day of month (starting from 1) changed. @@ -1559,7 +1648,8 @@ impl Datelike for NaiveDate { /// ``` #[inline] fn with_day0(&self, day0: u32) -> Option { - self.with_mdf(self.mdf().with_day(day0 + 1)?) + let day = day0.checked_add(1)?; + self.with_mdf(self.mdf().with_day(day)?) } /// Makes a new `NaiveDate` with the day of year (starting from 1) changed. @@ -1583,7 +1673,7 @@ impl Datelike for NaiveDate { /// ``` #[inline] fn with_ordinal(&self, ordinal: u32) -> Option { - self.with_of(self.of().with_ordinal(ordinal)?) + self.of().with_ordinal(ordinal).map(|of| self.with_of(of)) } /// Makes a new `NaiveDate` with the day of year (starting from 0) changed. @@ -1607,22 +1697,22 @@ impl Datelike for NaiveDate { /// ``` #[inline] fn with_ordinal0(&self, ordinal0: u32) -> Option { - self.with_of(self.of().with_ordinal(ordinal0 + 1)?) + let ordinal = ordinal0.checked_add(1)?; + self.with_ordinal(ordinal) } } /// An addition of `Duration` to `NaiveDate` discards the fractional days, /// rounding to the closest integral number of days towards `Duration::zero()`. /// -/// Panics on underflow or overflow. -/// Use [`NaiveDate::checked_add_signed`](#method.checked_add_signed) to detect that. +/// Panics on underflow or overflow. Use [`NaiveDate::checked_add_signed`] to detect that. /// /// # Example /// /// ``` /// use chrono::{Duration, NaiveDate}; /// -/// let from_ymd = NaiveDate::from_ymd; +/// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); /// /// assert_eq!(from_ymd(2014, 1, 1) + Duration::zero(), from_ymd(2014, 1, 1)); /// assert_eq!(from_ymd(2014, 1, 1) + Duration::seconds(86399), from_ymd(2014, 1, 1)); @@ -1633,6 +1723,8 @@ impl Datelike for NaiveDate { /// assert_eq!(from_ymd(2014, 1, 1) + Duration::days(365*4 + 1), from_ymd(2018, 1, 1)); /// assert_eq!(from_ymd(2014, 1, 1) + Duration::days(365*400 + 97), from_ymd(2414, 1, 1)); /// ``` +/// +/// [`NaiveDate::checked_add_signed`]: crate::NaiveDate::checked_add_signed impl Add for NaiveDate { type Output = NaiveDate; @@ -1661,9 +1753,9 @@ impl Add for NaiveDate { /// # Example /// /// ``` - /// use chrono::{Duration, NaiveDate, Months}; + /// use chrono::{NaiveDate, Months}; /// - /// let from_ymd = NaiveDate::from_ymd; + /// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); /// /// assert_eq!(from_ymd(2014, 1, 1) + Months::new(1), from_ymd(2014, 2, 1)); /// assert_eq!(from_ymd(2014, 1, 1) + Months::new(11), from_ymd(2014, 12, 1)); @@ -1689,9 +1781,9 @@ impl Sub for NaiveDate { /// # Example /// /// ``` - /// use chrono::{Duration, NaiveDate, Months}; + /// use chrono::{NaiveDate, Months}; /// - /// let from_ymd = NaiveDate::from_ymd; + /// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); /// /// assert_eq!(from_ymd(2014, 1, 1) - Months::new(11), from_ymd(2013, 2, 1)); /// assert_eq!(from_ymd(2014, 1, 1) - Months::new(12), from_ymd(2013, 1, 1)); @@ -1722,15 +1814,14 @@ impl Sub for NaiveDate { /// rounding to the closest integral number of days towards `Duration::zero()`. /// It is the same as the addition with a negated `Duration`. /// -/// Panics on underflow or overflow. -/// Use [`NaiveDate::checked_sub_signed`](#method.checked_sub_signed) to detect that. +/// Panics on underflow or overflow. Use [`NaiveDate::checked_sub_signed`] to detect that. /// /// # Example /// /// ``` /// use chrono::{Duration, NaiveDate}; /// -/// let from_ymd = NaiveDate::from_ymd; +/// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); /// /// assert_eq!(from_ymd(2014, 1, 1) - Duration::zero(), from_ymd(2014, 1, 1)); /// assert_eq!(from_ymd(2014, 1, 1) - Duration::seconds(86399), from_ymd(2014, 1, 1)); @@ -1741,6 +1832,8 @@ impl Sub for NaiveDate { /// assert_eq!(from_ymd(2014, 1, 1) - Duration::days(365*4 + 1), from_ymd(2010, 1, 1)); /// assert_eq!(from_ymd(2014, 1, 1) - Duration::days(365*400 + 97), from_ymd(1614, 1, 1)); /// ``` +/// +/// [`NaiveDate::checked_sub_signed`]: crate::NaiveDate::checked_sub_signed impl Sub for NaiveDate { type Output = NaiveDate; @@ -1771,7 +1864,7 @@ impl SubAssign for NaiveDate { /// ``` /// use chrono::{Duration, NaiveDate}; /// -/// let from_ymd = NaiveDate::from_ymd; +/// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); /// /// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2014, 1, 1), Duration::zero()); /// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 12, 31), Duration::days(1)); @@ -1790,6 +1883,12 @@ impl Sub for NaiveDate { } } +impl From for NaiveDate { + fn from(naive_datetime: NaiveDateTime) -> Self { + naive_datetime.date() + } +} + /// Iterator over `NaiveDate` with a step size of one day. #[derive(Debug, Copy, Clone, Hash, PartialEq, PartialOrd, Eq, Ord)] pub struct NaiveDateDaysIterator { @@ -1993,6 +2092,10 @@ impl Default for NaiveDate { } } +fn div_mod_floor(val: i32, div: i32) -> (i32, i32) { + (val.div_euclid(div), val.rem_euclid(div)) +} + #[cfg(all(test, any(feature = "rustc-serialize", feature = "serde")))] fn test_encodable_json(to_string: F) where @@ -2183,10 +2286,7 @@ mod tests { }; use crate::oldtime::Duration; use crate::{Datelike, Weekday}; - use std::{ - convert::{TryFrom, TryInto}, - i32, u32, - }; + use std::{i32, u32}; #[test] fn diff_months() { @@ -2208,7 +2308,7 @@ mod tests { assert_eq!( NaiveDate::from_ymd_opt(2022, 8, 3) .unwrap() - .checked_sub_months(Months::new((i32::MIN as i64).abs() as u32 + 1)), + .checked_sub_months(Months::new(i32::MIN.unsigned_abs() + 1)), None ); @@ -2275,9 +2375,7 @@ mod tests { #[test] fn test_readme_doomsday() { - use num_iter::range_inclusive; - - for y in range_inclusive(NaiveDate::MIN.year(), NaiveDate::MAX.year()) { + for y in NaiveDate::MIN.year()..=NaiveDate::MAX.year() { // even months let d4 = NaiveDate::from_ymd_opt(y, 4, 4).unwrap(); let d6 = NaiveDate::from_ymd_opt(y, 6, 6).unwrap(); @@ -2459,6 +2557,9 @@ mod tests { assert_eq!(from_ndays_from_ce(NaiveDate::MIN.num_days_from_ce() - 1), None); assert_eq!(from_ndays_from_ce(NaiveDate::MAX.num_days_from_ce()), Some(NaiveDate::MAX)); assert_eq!(from_ndays_from_ce(NaiveDate::MAX.num_days_from_ce() + 1), None); + + assert_eq!(from_ndays_from_ce(i32::MIN), None); + assert_eq!(from_ndays_from_ce(i32::MAX), None); } #[test] @@ -2915,23 +3016,31 @@ mod tests { fn test_naiveweek() { let date = NaiveDate::from_ymd_opt(2022, 5, 18).unwrap(); let asserts = vec![ - (Weekday::Mon, "2022-05-16", "2022-05-22"), - (Weekday::Tue, "2022-05-17", "2022-05-23"), - (Weekday::Wed, "2022-05-18", "2022-05-24"), - (Weekday::Thu, "2022-05-12", "2022-05-18"), - (Weekday::Fri, "2022-05-13", "2022-05-19"), - (Weekday::Sat, "2022-05-14", "2022-05-20"), - (Weekday::Sun, "2022-05-15", "2022-05-21"), + (Weekday::Mon, "Mon 2022-05-16", "Sun 2022-05-22"), + (Weekday::Tue, "Tue 2022-05-17", "Mon 2022-05-23"), + (Weekday::Wed, "Wed 2022-05-18", "Tue 2022-05-24"), + (Weekday::Thu, "Thu 2022-05-12", "Wed 2022-05-18"), + (Weekday::Fri, "Fri 2022-05-13", "Thu 2022-05-19"), + (Weekday::Sat, "Sat 2022-05-14", "Fri 2022-05-20"), + (Weekday::Sun, "Sun 2022-05-15", "Sat 2022-05-21"), ]; for (start, first_day, last_day) in asserts { let week = date.week(start); let days = week.days(); - assert_eq!(Ok(week.first_day()), NaiveDate::parse_from_str(first_day, "%Y-%m-%d")); - assert_eq!(Ok(week.last_day()), NaiveDate::parse_from_str(last_day, "%Y-%m-%d")); + assert_eq!(Ok(week.first_day()), NaiveDate::parse_from_str(first_day, "%a %Y-%m-%d")); + assert_eq!(Ok(week.last_day()), NaiveDate::parse_from_str(last_day, "%a %Y-%m-%d")); assert!(days.contains(&date)); } } + #[test] + fn test_naiveweek_min_max() { + let date_max = NaiveDate::MAX; + assert!(date_max.week(Weekday::Mon).first_day() <= date_max); + let date_min = NaiveDate::MIN; + assert!(date_min.week(Weekday::Mon).last_day() >= date_min); + } + #[test] fn test_weeks_from() { // tests per: https://github.com/chronotope/chrono/issues/961 @@ -2994,4 +3103,12 @@ mod tests { } } } + + #[test] + fn test_with_0_overflow() { + let dt = NaiveDate::from_ymd_opt(2023, 4, 18).unwrap(); + assert!(dt.with_month0(4294967295).is_none()); + assert!(dt.with_day0(4294967295).is_none()); + assert!(dt.with_ordinal0(4294967295).is_none()); + } } diff --git a/vendor/chrono/src/naive/datetime/mod.rs b/vendor/chrono/src/naive/datetime/mod.rs index ec0d842c0..0a3f70380 100644 --- a/vendor/chrono/src/naive/datetime/mod.rs +++ b/vendor/chrono/src/naive/datetime/mod.rs @@ -5,24 +5,21 @@ #[cfg(any(feature = "alloc", feature = "std", test))] use core::borrow::Borrow; -use core::convert::TryFrom; use core::fmt::Write; use core::ops::{Add, AddAssign, Sub, SubAssign}; use core::{fmt, str}; -use num_integer::div_mod_floor; -use num_traits::ToPrimitive; #[cfg(feature = "rkyv")] use rkyv::{Archive, Deserialize, Serialize}; #[cfg(any(feature = "alloc", feature = "std", test))] use crate::format::DelayedFormat; -use crate::format::{parse, ParseError, ParseResult, Parsed, StrftimeItems}; +use crate::format::{parse, parse_and_remainder, ParseError, ParseResult, Parsed, StrftimeItems}; use crate::format::{Fixed, Item, Numeric, Pad}; use crate::naive::{Days, IsoWeek, NaiveDate, NaiveTime}; +use crate::offset::Utc; use crate::oldtime::Duration as OldDuration; use crate::{DateTime, Datelike, LocalResult, Months, TimeZone, Timelike, Weekday}; -use core::cmp::Ordering; #[cfg(feature = "rustc-serialize")] pub(super) mod rustc_serialize; @@ -42,11 +39,6 @@ mod tests; /// touching that call when we are already sure that it WILL overflow... const MAX_SECS_BITS: usize = 44; -/// Number of nanoseconds in a millisecond -const NANOS_IN_MILLISECOND: u32 = 1_000_000; -/// Number of nanoseconds in a second -const NANOS_IN_SECOND: u32 = 1000 * NANOS_IN_MILLISECOND; - /// The minimum possible `NaiveDateTime`. #[deprecated(since = "0.4.20", note = "Use NaiveDateTime::MIN instead")] pub const MIN_DATETIME: NaiveDateTime = NaiveDateTime::MIN; @@ -87,32 +79,6 @@ pub struct NaiveDateTime { time: NaiveTime, } -/// The unit of a timestamp expressed in fractions of a second. -/// Currently either milliseconds or microseconds. -/// -/// This is a private type, used in the implementation of -/// [NaiveDateTime::from_timestamp_millis] and [NaiveDateTime::from_timestamp_micros]. -#[derive(Clone, Copy, Debug)] -enum TimestampUnit { - Millis, - Micros, -} - -impl TimestampUnit { - fn per_second(self) -> u32 { - match self { - TimestampUnit::Millis => 1_000, - TimestampUnit::Micros => 1_000_000, - } - } - fn nanos_per(self) -> u32 { - match self { - TimestampUnit::Millis => 1_000_000, - TimestampUnit::Micros => 1_000, - } - } -} - impl NaiveDateTime { /// Makes a new `NaiveDateTime` from date and time components. /// Equivalent to [`date.and_time(time)`](./struct.NaiveDate.html#method.and_time) @@ -150,6 +116,7 @@ impl NaiveDateTime { /// Panics on the out-of-range number of seconds and/or invalid nanosecond. #[deprecated(since = "0.4.23", note = "use `from_timestamp_opt()` instead")] #[inline] + #[must_use] pub fn from_timestamp(secs: i64, nsecs: u32) -> NaiveDateTime { let datetime = NaiveDateTime::from_timestamp_opt(secs, nsecs); datetime.expect("invalid or out-of-range datetime") @@ -177,8 +144,11 @@ impl NaiveDateTime { /// assert_eq!(timestamp_millis, naive_datetime.unwrap().timestamp_millis()); /// ``` #[inline] + #[must_use] pub fn from_timestamp_millis(millis: i64) -> Option { - Self::from_timestamp_unit(millis, TimestampUnit::Millis) + let secs = millis.div_euclid(1000); + let nsecs = millis.rem_euclid(1000) as u32 * 1_000_000; + NaiveDateTime::from_timestamp_opt(secs, nsecs) } /// Creates a new [NaiveDateTime] from microseconds since the UNIX epoch. @@ -203,8 +173,11 @@ impl NaiveDateTime { /// assert_eq!(timestamp_micros, naive_datetime.unwrap().timestamp_micros()); /// ``` #[inline] + #[must_use] pub fn from_timestamp_micros(micros: i64) -> Option { - Self::from_timestamp_unit(micros, TimestampUnit::Micros) + let secs = micros.div_euclid(1_000_000); + let nsecs = micros.rem_euclid(1_000_000) as u32 * 1000; + NaiveDateTime::from_timestamp_opt(secs, nsecs) } /// Makes a new `NaiveDateTime` corresponding to a UTC date and time, @@ -222,7 +195,7 @@ impl NaiveDateTime { /// # Example /// /// ``` - /// use chrono::{NaiveDateTime, NaiveDate}; + /// use chrono::NaiveDateTime; /// use std::i64; /// /// let from_timestamp_opt = NaiveDateTime::from_timestamp_opt; @@ -234,10 +207,12 @@ impl NaiveDateTime { /// assert!(from_timestamp_opt(i64::MAX, 0).is_none()); /// ``` #[inline] + #[must_use] pub fn from_timestamp_opt(secs: i64, nsecs: u32) -> Option { - let (days, secs) = div_mod_floor(secs, 86_400); - let date = days - .to_i32() + let days = secs.div_euclid(86_400); + let secs = secs.rem_euclid(86_400); + let date = i32::try_from(days) + .ok() .and_then(|days| days.checked_add(719_163)) .and_then(NaiveDate::from_num_days_from_ce_opt); let time = NaiveTime::from_num_seconds_from_midnight_opt(secs as u32, nsecs); @@ -312,18 +287,43 @@ impl NaiveDateTime { /// Years before 1 BCE or after 9999 CE, require an initial sign /// ///``` - /// # use chrono::{NaiveDate, NaiveDateTime}; + /// # use chrono::NaiveDateTime; /// # let parse_from_str = NaiveDateTime::parse_from_str; /// let fmt = "%Y-%m-%d %H:%M:%S"; /// assert!(parse_from_str("10000-09-09 01:46:39", fmt).is_err()); /// assert!(parse_from_str("+10000-09-09 01:46:39", fmt).is_ok()); - ///``` + ///``` pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult { let mut parsed = Parsed::new(); parse(&mut parsed, s, StrftimeItems::new(fmt))?; parsed.to_naive_datetime_with_offset(0) // no offset adjustment } + /// Parses a string with the specified format string and returns a new `NaiveDateTime`, and a + /// slice with the remaining portion of the string. + /// See the [`format::strftime` module](../format/strftime/index.html) + /// on the supported escape sequences. + /// + /// Similar to [`parse_from_str`](#method.parse_from_str). + /// + /// # Example + /// + /// ```rust + /// # use chrono::{NaiveDate, NaiveDateTime}; + /// let (datetime, remainder) = NaiveDateTime::parse_and_remainder( + /// "2015-02-18 23:16:09 trailing text", "%Y-%m-%d %H:%M:%S").unwrap(); + /// assert_eq!( + /// datetime, + /// NaiveDate::from_ymd_opt(2015, 2, 18).unwrap().and_hms_opt(23, 16, 9).unwrap() + /// ); + /// assert_eq!(remainder, " trailing text"); + /// ``` + pub fn parse_and_remainder<'a>(s: &'a str, fmt: &str) -> ParseResult<(NaiveDateTime, &'a str)> { + let mut parsed = Parsed::new(); + let remainder = parse_and_remainder(&mut parsed, s, StrftimeItems::new(fmt))?; + parsed.to_naive_datetime_with_offset(0).map(|d| (d, remainder)) // no offset adjustment + } + /// Retrieves a date component. /// /// # Example @@ -377,6 +377,7 @@ impl NaiveDateTime { /// assert_eq!(dt.timestamp(), -62198755200); /// ``` #[inline] + #[must_use] pub fn timestamp(&self) -> i64 { const UNIX_EPOCH_DAY: i64 = 719_163; let gregorian_day = i64::from(self.date.num_days_from_ce()); @@ -409,6 +410,7 @@ impl NaiveDateTime { /// assert_eq!(dt.timestamp_millis(), -900); /// ``` #[inline] + #[must_use] pub fn timestamp_millis(&self) -> i64 { let as_ms = self.timestamp() * 1000; as_ms + i64::from(self.timestamp_subsec_millis()) @@ -436,6 +438,7 @@ impl NaiveDateTime { /// assert_eq!(dt.timestamp_micros(), 1_000_000_000_000_555); /// ``` #[inline] + #[must_use] pub fn timestamp_micros(&self) -> i64 { let as_us = self.timestamp() * 1_000_000; as_us + i64::from(self.timestamp_subsec_micros()) @@ -470,11 +473,12 @@ impl NaiveDateTime { /// let nanos = dt.timestamp_nanos(); /// assert_eq!(nanos, 1_000_000_000_000_000_555); /// assert_eq!( - /// dt, - /// NaiveDateTime::from_timestamp(nanos / A_BILLION, (nanos % A_BILLION) as u32) + /// Some(dt), + /// NaiveDateTime::from_timestamp_opt(nanos / A_BILLION, (nanos % A_BILLION) as u32) /// ); /// ``` #[inline] + #[must_use] pub fn timestamp_nanos(&self) -> i64 { let as_ns = self.timestamp() * 1_000_000_000; as_ns + i64::from(self.timestamp_subsec_nanos()) @@ -497,6 +501,7 @@ impl NaiveDateTime { /// assert_eq!(dt.timestamp_subsec_millis(), 1_234); /// ``` #[inline] + #[must_use] pub fn timestamp_subsec_millis(&self) -> u32 { self.timestamp_subsec_nanos() / 1_000_000 } @@ -518,6 +523,7 @@ impl NaiveDateTime { /// assert_eq!(dt.timestamp_subsec_micros(), 1_234_567); /// ``` #[inline] + #[must_use] pub fn timestamp_subsec_micros(&self) -> u32 { self.timestamp_subsec_nanos() / 1_000 } @@ -539,6 +545,7 @@ impl NaiveDateTime { /// assert_eq!(dt.timestamp_subsec_nanos(), 1_234_567_890); /// ``` #[inline] + #[must_use] pub fn timestamp_subsec_nanos(&self) -> u32 { self.time.nanosecond() } @@ -557,7 +564,7 @@ impl NaiveDateTime { /// ``` /// use chrono::{Duration, NaiveDate}; /// - /// let from_ymd = NaiveDate::from_ymd; + /// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); /// /// let d = from_ymd(2016, 7, 8); /// let hms = |h, m, s| d.and_hms_opt(h, m, s).unwrap(); @@ -590,7 +597,7 @@ impl NaiveDateTime { /// /// ``` /// # use chrono::{Duration, NaiveDate}; - /// # let from_ymd = NaiveDate::from_ymd; + /// # let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); /// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli_opt(h, m, s, milli).unwrap(); /// let leap = hmsm(3, 5, 59, 1_300); /// assert_eq!(leap.checked_add_signed(Duration::zero()), @@ -608,6 +615,7 @@ impl NaiveDateTime { /// assert_eq!(leap.checked_add_signed(Duration::days(1)), /// Some(from_ymd(2016, 7, 9).and_hms_milli_opt(3, 5, 59, 300).unwrap())); /// ``` + #[must_use] pub fn checked_add_signed(self, rhs: OldDuration) -> Option { let (time, rhs) = self.time.overflowing_add_signed(rhs); @@ -629,8 +637,7 @@ impl NaiveDateTime { /// # Example /// /// ``` - /// use std::str::FromStr; - /// use chrono::{Months, NaiveDate, NaiveDateTime}; + /// use chrono::{Months, NaiveDate}; /// /// assert_eq!( /// NaiveDate::from_ymd_opt(2014, 1, 1).unwrap().and_hms_opt(1, 0, 0).unwrap() @@ -644,6 +651,7 @@ impl NaiveDateTime { /// None /// ); /// ``` + #[must_use] pub fn checked_add_months(self, rhs: Months) -> Option { Some(Self { date: self.date.checked_add_months(rhs)?, time: self.time }) } @@ -662,7 +670,7 @@ impl NaiveDateTime { /// ``` /// use chrono::{Duration, NaiveDate}; /// - /// let from_ymd = NaiveDate::from_ymd; + /// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); /// /// let d = from_ymd(2016, 7, 8); /// let hms = |h, m, s| d.and_hms_opt(h, m, s).unwrap(); @@ -695,7 +703,7 @@ impl NaiveDateTime { /// /// ``` /// # use chrono::{Duration, NaiveDate}; - /// # let from_ymd = NaiveDate::from_ymd; + /// # let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); /// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli_opt(h, m, s, milli).unwrap(); /// let leap = hmsm(3, 5, 59, 1_300); /// assert_eq!(leap.checked_sub_signed(Duration::zero()), @@ -709,6 +717,7 @@ impl NaiveDateTime { /// assert_eq!(leap.checked_sub_signed(Duration::days(1)), /// Some(from_ymd(2016, 7, 7).and_hms_milli_opt(3, 6, 0, 300).unwrap())); /// ``` + #[must_use] pub fn checked_sub_signed(self, rhs: OldDuration) -> Option { let (time, rhs) = self.time.overflowing_sub_signed(rhs); @@ -730,8 +739,7 @@ impl NaiveDateTime { /// # Example /// /// ``` - /// use std::str::FromStr; - /// use chrono::{Months, NaiveDate, NaiveDateTime}; + /// use chrono::{Months, NaiveDate}; /// /// assert_eq!( /// NaiveDate::from_ymd_opt(2014, 1, 1).unwrap().and_hms_opt(1, 0, 0).unwrap() @@ -745,6 +753,7 @@ impl NaiveDateTime { /// None /// ); /// ``` + #[must_use] pub fn checked_sub_months(self, rhs: Months) -> Option { Some(Self { date: self.date.checked_sub_months(rhs)?, time: self.time }) } @@ -752,6 +761,7 @@ impl NaiveDateTime { /// Add a duration in [`Days`] to the date part of the `NaiveDateTime` /// /// Returns `None` if the resulting date would be out of range. + #[must_use] pub fn checked_add_days(self, days: Days) -> Option { Some(Self { date: self.date.checked_add_days(days)?, ..self }) } @@ -759,6 +769,7 @@ impl NaiveDateTime { /// Subtract a duration in [`Days`] from the date part of the `NaiveDateTime` /// /// Returns `None` if the resulting date would be out of range. + #[must_use] pub fn checked_sub_days(self, days: Days) -> Option { Some(Self { date: self.date.checked_sub_days(days)?, ..self }) } @@ -777,7 +788,7 @@ impl NaiveDateTime { /// ``` /// use chrono::{Duration, NaiveDate}; /// - /// let from_ymd = NaiveDate::from_ymd; + /// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); /// /// let d = from_ymd(2016, 7, 8); /// assert_eq!(d.and_hms_opt(3, 5, 7).unwrap().signed_duration_since(d.and_hms_opt(2, 4, 6).unwrap()), @@ -794,13 +805,14 @@ impl NaiveDateTime { /// /// ``` /// # use chrono::{Duration, NaiveDate}; - /// # let from_ymd = NaiveDate::from_ymd; + /// # let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); /// let leap = from_ymd(2015, 6, 30).and_hms_milli_opt(23, 59, 59, 1_500).unwrap(); /// assert_eq!(leap.signed_duration_since(from_ymd(2015, 6, 30).and_hms_opt(23, 0, 0).unwrap()), /// Duration::seconds(3600) + Duration::milliseconds(500)); /// assert_eq!(from_ymd(2015, 7, 1).and_hms_opt(1, 0, 0).unwrap().signed_duration_since(leap), /// Duration::seconds(3600) - Duration::milliseconds(500)); /// ``` + #[must_use] pub fn signed_duration_since(self, rhs: NaiveDateTime) -> OldDuration { self.date.signed_duration_since(rhs.date) + self.time.signed_duration_since(rhs.time) } @@ -835,6 +847,7 @@ impl NaiveDateTime { #[cfg(any(feature = "alloc", feature = "std", test))] #[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))] #[inline] + #[must_use] pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat where I: Iterator + Clone, @@ -878,6 +891,7 @@ impl NaiveDateTime { #[cfg(any(feature = "alloc", feature = "std", test))] #[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))] #[inline] + #[must_use] pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat> { self.format_with_items(StrftimeItems::new(fmt)) } @@ -896,51 +910,39 @@ impl NaiveDateTime { /// # Example /// /// ``` - /// use chrono::{NaiveDate, Utc}; - /// let dt = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap().and_hms_opt(23, 56, 4).unwrap().and_local_timezone(Utc).unwrap(); - /// assert_eq!(dt.timezone(), Utc); + /// use chrono::{NaiveDate, FixedOffset}; + /// let hour = 3600; + /// let tz = FixedOffset::east_opt(5 * hour).unwrap(); + /// let dt = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap().and_hms_opt(23, 56, 4).unwrap().and_local_timezone(tz).unwrap(); + /// assert_eq!(dt.timezone(), tz); + /// ``` + #[must_use] pub fn and_local_timezone(&self, tz: Tz) -> LocalResult> { tz.from_local_datetime(self) } + /// Converts the `NaiveDateTime` into the timezone-aware `DateTime`. + /// + /// # Example + /// + /// ``` + /// use chrono::{NaiveDate, Utc}; + /// let dt = NaiveDate::from_ymd_opt(2023, 1, 30).unwrap().and_hms_opt(19, 32, 33).unwrap().and_utc(); + /// assert_eq!(dt.timezone(), Utc); + /// ``` + #[must_use] + pub fn and_utc(&self) -> DateTime { + Utc.from_utc_datetime(self) + } + /// The minimum possible `NaiveDateTime`. pub const MIN: Self = Self { date: NaiveDate::MIN, time: NaiveTime::MIN }; /// The maximum possible `NaiveDateTime`. pub const MAX: Self = Self { date: NaiveDate::MAX, time: NaiveTime::MAX }; - - /// Creates a new [NaiveDateTime] from milliseconds or microseconds since the UNIX epoch. - /// - /// This is a private function used by [from_timestamp_millis] and [from_timestamp_micros]. - #[inline] - fn from_timestamp_unit(value: i64, unit: TimestampUnit) -> Option { - let (secs, subsecs) = - (value / i64::from(unit.per_second()), value % i64::from(unit.per_second())); - - match subsecs.cmp(&0) { - Ordering::Less => { - // in the case where our subsec part is negative, then we are actually in the earlier second - // hence we subtract one from the seconds part, and we then add a whole second worth of nanos - // to our nanos part. Due to the use of u32 datatype, it is more convenient to subtract - // the absolute value of the subsec nanos from a whole second worth of nanos - let nsecs = u32::try_from(subsecs.abs()).ok()? * unit.nanos_per(); - NaiveDateTime::from_timestamp_opt( - secs.checked_sub(1)?, - NANOS_IN_SECOND.checked_sub(nsecs)?, - ) - } - Ordering::Equal => NaiveDateTime::from_timestamp_opt(secs, 0), - Ordering::Greater => { - // convert the subsec millis into nanosecond scale so they can be supplied - // as the nanoseconds parameter - let nsecs = u32::try_from(subsecs).ok()? * unit.nanos_per(); - NaiveDateTime::from_timestamp_opt(secs, nsecs) - } - } - } } impl Datelike for NaiveDateTime { - /// Returns the year number in the [calendar date](./index.html#calendar-date). + /// Returns the year number in the [calendar date](./struct.NaiveDate.html#calendar-date). /// /// See also the [`NaiveDate::year`] method. /// @@ -1415,10 +1417,9 @@ impl Timelike for NaiveDateTime { /// An addition of `Duration` to `NaiveDateTime` yields another `NaiveDateTime`. /// -/// As a part of Chrono's [leap second handling](./struct.NaiveTime.html#leap-second-handling), -/// the addition assumes that **there is no leap second ever**, -/// except when the `NaiveDateTime` itself represents a leap second -/// in which case the assumption becomes that **there is exactly a single leap second ever**. +/// As a part of Chrono's [leap second handling], the addition assumes that **there is no leap +/// second ever**, except when the `NaiveDateTime` itself represents a leap second in which case +/// the assumption becomes that **there is exactly a single leap second ever**. /// /// Panics on underflow or overflow. Use [`NaiveDateTime::checked_add_signed`] /// to detect that. @@ -1428,7 +1429,7 @@ impl Timelike for NaiveDateTime { /// ``` /// use chrono::{Duration, NaiveDate}; /// -/// let from_ymd = NaiveDate::from_ymd; +/// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); /// /// let d = from_ymd(2016, 7, 8); /// let hms = |h, m, s| d.and_hms_opt(h, m, s).unwrap(); @@ -1450,7 +1451,7 @@ impl Timelike for NaiveDateTime { /// /// ``` /// # use chrono::{Duration, NaiveDate}; -/// # let from_ymd = NaiveDate::from_ymd; +/// # let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); /// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli_opt(h, m, s, milli).unwrap(); /// let leap = hmsm(3, 5, 59, 1_300); /// assert_eq!(leap + Duration::zero(), hmsm(3, 5, 59, 1_300)); @@ -1462,6 +1463,8 @@ impl Timelike for NaiveDateTime { /// assert_eq!(leap + Duration::days(1), /// from_ymd(2016, 7, 9).and_hms_milli_opt(3, 5, 59, 300).unwrap()); /// ``` +/// +/// [leap second handling]: crate::NaiveTime#leap-second-handling impl Add for NaiveDateTime { type Output = NaiveDateTime; @@ -1490,8 +1493,7 @@ impl Add for NaiveDateTime { /// # Example /// /// ``` - /// use chrono::{Duration, NaiveDateTime, Months, NaiveDate}; - /// use std::str::FromStr; + /// use chrono::{Months, NaiveDate}; /// /// assert_eq!( /// NaiveDate::from_ymd_opt(2014, 1, 1).unwrap().and_hms_opt(1, 0, 0).unwrap() + Months::new(1), @@ -1526,10 +1528,9 @@ impl Add for NaiveDateTime { /// A subtraction of `Duration` from `NaiveDateTime` yields another `NaiveDateTime`. /// It is the same as the addition with a negated `Duration`. /// -/// As a part of Chrono's [leap second handling](./struct.NaiveTime.html#leap-second-handling), -/// the addition assumes that **there is no leap second ever**, -/// except when the `NaiveDateTime` itself represents a leap second -/// in which case the assumption becomes that **there is exactly a single leap second ever**. +/// As a part of Chrono's [leap second handling] the subtraction assumes that **there is no leap +/// second ever**, except when the `NaiveDateTime` itself represents a leap second in which case +/// the assumption becomes that **there is exactly a single leap second ever**. /// /// Panics on underflow or overflow. Use [`NaiveDateTime::checked_sub_signed`] /// to detect that. @@ -1539,7 +1540,7 @@ impl Add for NaiveDateTime { /// ``` /// use chrono::{Duration, NaiveDate}; /// -/// let from_ymd = NaiveDate::from_ymd; +/// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); /// /// let d = from_ymd(2016, 7, 8); /// let hms = |h, m, s| d.and_hms_opt(h, m, s).unwrap(); @@ -1561,7 +1562,7 @@ impl Add for NaiveDateTime { /// /// ``` /// # use chrono::{Duration, NaiveDate}; -/// # let from_ymd = NaiveDate::from_ymd; +/// # let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); /// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli_opt(h, m, s, milli).unwrap(); /// let leap = hmsm(3, 5, 59, 1_300); /// assert_eq!(leap - Duration::zero(), hmsm(3, 5, 59, 1_300)); @@ -1571,6 +1572,8 @@ impl Add for NaiveDateTime { /// assert_eq!(leap - Duration::days(1), /// from_ymd(2016, 7, 7).and_hms_milli_opt(3, 6, 0, 300).unwrap()); /// ``` +/// +/// [leap second handling]: crate::NaiveTime#leap-second-handling impl Sub for NaiveDateTime { type Output = NaiveDateTime; @@ -1596,8 +1599,7 @@ impl SubAssign for NaiveDateTime { /// # Example /// /// ``` -/// use chrono::{Duration, NaiveDateTime, Months, NaiveDate}; -/// use std::str::FromStr; +/// use chrono::{Months, NaiveDate}; /// /// assert_eq!( /// NaiveDate::from_ymd_opt(2014, 01, 01).unwrap().and_hms_opt(01, 00, 00).unwrap() - Months::new(11), @@ -1636,7 +1638,7 @@ impl Sub for NaiveDateTime { /// ``` /// use chrono::{Duration, NaiveDate}; /// -/// let from_ymd = NaiveDate::from_ymd; +/// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); /// /// let d = from_ymd(2016, 7, 8); /// assert_eq!(d.and_hms_opt(3, 5, 7).unwrap() - d.and_hms_opt(2, 4, 6).unwrap(), Duration::seconds(3600 + 60 + 1)); @@ -1652,7 +1654,7 @@ impl Sub for NaiveDateTime { /// /// ``` /// # use chrono::{Duration, NaiveDate}; -/// # let from_ymd = NaiveDate::from_ymd; +/// # let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap(); /// let leap = from_ymd(2015, 6, 30).and_hms_milli_opt(23, 59, 59, 1_500).unwrap(); /// assert_eq!(leap - from_ymd(2015, 6, 30).and_hms_opt(23, 0, 0).unwrap(), /// Duration::seconds(3600) + Duration::milliseconds(500)); @@ -1808,7 +1810,7 @@ impl str::FromStr for NaiveDateTime { /// use chrono::NaiveDateTime; /// /// let default_date = NaiveDateTime::default(); -/// assert_eq!(default_date, NaiveDateTime::from_timestamp(0, 0)); +/// assert_eq!(Some(default_date), NaiveDateTime::from_timestamp_opt(0, 0)); /// ``` impl Default for NaiveDateTime { fn default() -> Self { diff --git a/vendor/chrono/src/naive/datetime/serde.rs b/vendor/chrono/src/naive/datetime/serde.rs index 40695fa74..8107f384d 100644 --- a/vendor/chrono/src/naive/datetime/serde.rs +++ b/vendor/chrono/src/naive/datetime/serde.rs @@ -110,6 +110,7 @@ pub mod ts_nanoseconds { /// assert_eq!(as_string, r#"{"time":1526522699918355733}"#); /// # Ok::<(), serde_json::Error>(()) /// ``` + #[must_use] pub fn serialize(dt: &NaiveDateTime, serializer: S) -> Result where S: ser::Serializer, @@ -127,15 +128,17 @@ pub mod ts_nanoseconds { /// # use chrono::NaiveDateTime; /// # use serde_derive::Deserialize; /// use chrono::naive::serde::ts_nanoseconds::deserialize as from_nano_ts; - /// #[derive(Deserialize)] + /// #[derive(Debug, PartialEq, Deserialize)] /// struct S { /// #[serde(deserialize_with = "from_nano_ts")] /// time: NaiveDateTime /// } /// /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355733 }"#)?; + /// assert_eq!(my_s, S { time: NaiveDateTime::from_timestamp_opt(1526522699, 918355733).unwrap() }); /// # Ok::<(), serde_json::Error>(()) /// ``` + #[must_use] pub fn deserialize<'de, D>(d: D) -> Result where D: de::Deserializer<'de>, @@ -230,6 +233,7 @@ pub mod ts_nanoseconds_option { /// assert_eq!(as_string, r#"{"time":1526522699918355733}"#); /// # Ok::<(), serde_json::Error>(()) /// ``` + #[must_use] pub fn serialize(opt: &Option, serializer: S) -> Result where S: ser::Serializer, @@ -247,18 +251,20 @@ pub mod ts_nanoseconds_option { /// # Example: /// /// ```rust - /// # use chrono::naive::{NaiveDate, NaiveDateTime}; + /// # use chrono::naive::NaiveDateTime; /// # use serde_derive::Deserialize; /// use chrono::naive::serde::ts_nanoseconds_option::deserialize as from_nano_tsopt; - /// #[derive(Deserialize)] + /// #[derive(Debug, PartialEq, Deserialize)] /// struct S { /// #[serde(deserialize_with = "from_nano_tsopt")] /// time: Option /// } /// /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355733 }"#)?; + /// assert_eq!(my_s, S { time: NaiveDateTime::from_timestamp_opt(1526522699, 918355733) }); /// # Ok::<(), serde_json::Error>(()) /// ``` + #[must_use] pub fn deserialize<'de, D>(d: D) -> Result, D::Error> where D: de::Deserializer<'de>, @@ -356,6 +362,7 @@ pub mod ts_microseconds { /// assert_eq!(as_string, r#"{"time":1526522699918355}"#); /// # Ok::<(), serde_json::Error>(()) /// ``` + #[must_use] pub fn serialize(dt: &NaiveDateTime, serializer: S) -> Result where S: ser::Serializer, @@ -373,15 +380,17 @@ pub mod ts_microseconds { /// # use chrono::NaiveDateTime; /// # use serde_derive::Deserialize; /// use chrono::naive::serde::ts_microseconds::deserialize as from_micro_ts; - /// #[derive(Deserialize)] + /// #[derive(Debug, PartialEq, Deserialize)] /// struct S { /// #[serde(deserialize_with = "from_micro_ts")] /// time: NaiveDateTime /// } /// /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355 }"#)?; + /// assert_eq!(my_s, S { time: NaiveDateTime::from_timestamp_opt(1526522699, 918355000).unwrap() }); /// # Ok::<(), serde_json::Error>(()) /// ``` + #[must_use] pub fn deserialize<'de, D>(d: D) -> Result where D: de::Deserializer<'de>, @@ -479,6 +488,7 @@ pub mod ts_microseconds_option { /// assert_eq!(as_string, r#"{"time":1526522699918355}"#); /// # Ok::<(), serde_json::Error>(()) /// ``` + #[must_use] pub fn serialize(opt: &Option, serializer: S) -> Result where S: ser::Serializer, @@ -496,18 +506,20 @@ pub mod ts_microseconds_option { /// # Example: /// /// ```rust - /// # use chrono::naive::{NaiveDate, NaiveDateTime}; + /// # use chrono::naive::NaiveDateTime; /// # use serde_derive::Deserialize; /// use chrono::naive::serde::ts_microseconds_option::deserialize as from_micro_tsopt; - /// #[derive(Deserialize)] + /// #[derive(Debug, PartialEq, Deserialize)] /// struct S { /// #[serde(deserialize_with = "from_micro_tsopt")] /// time: Option /// } /// /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355 }"#)?; + /// assert_eq!(my_s, S { time: NaiveDateTime::from_timestamp_opt(1526522699, 918355000) }); /// # Ok::<(), serde_json::Error>(()) /// ``` + #[must_use] pub fn deserialize<'de, D>(d: D) -> Result, D::Error> where D: de::Deserializer<'de>, @@ -605,6 +617,7 @@ pub mod ts_milliseconds { /// assert_eq!(as_string, r#"{"time":1526522699918}"#); /// # Ok::<(), serde_json::Error>(()) /// ``` + #[must_use] pub fn serialize(dt: &NaiveDateTime, serializer: S) -> Result where S: ser::Serializer, @@ -622,15 +635,17 @@ pub mod ts_milliseconds { /// # use chrono::NaiveDateTime; /// # use serde_derive::Deserialize; /// use chrono::naive::serde::ts_milliseconds::deserialize as from_milli_ts; - /// #[derive(Deserialize)] + /// #[derive(Debug, PartialEq, Deserialize)] /// struct S { /// #[serde(deserialize_with = "from_milli_ts")] /// time: NaiveDateTime /// } /// /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918 }"#)?; + /// assert_eq!(my_s, S { time: NaiveDateTime::from_timestamp_opt(1526522699, 918000000).unwrap() }); /// # Ok::<(), serde_json::Error>(()) /// ``` + #[must_use] pub fn deserialize<'de, D>(d: D) -> Result where D: de::Deserializer<'de>, @@ -725,6 +740,7 @@ pub mod ts_milliseconds_option { /// assert_eq!(as_string, r#"{"time":1526522699918}"#); /// # Ok::<(), serde_json::Error>(()) /// ``` + #[must_use] pub fn serialize(opt: &Option, serializer: S) -> Result where S: ser::Serializer, @@ -735,25 +751,27 @@ pub mod ts_milliseconds_option { } } - /// Deserialize a `NaiveDateTime` from a nanosecond timestamp or none + /// Deserialize a `NaiveDateTime` from a millisecond timestamp or none /// /// Intended for use with `serde`s `deserialize_with` attribute. /// /// # Example: /// /// ```rust - /// # use chrono::naive::{NaiveDate, NaiveDateTime}; + /// # use chrono::naive::NaiveDateTime; /// # use serde_derive::Deserialize; /// use chrono::naive::serde::ts_milliseconds_option::deserialize as from_milli_tsopt; - /// #[derive(Deserialize)] + /// #[derive(Debug, PartialEq, Deserialize)] /// struct S { /// #[serde(deserialize_with = "from_milli_tsopt")] /// time: Option /// } /// - /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355 }"#)?; + /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918 }"#)?; + /// assert_eq!(my_s, S { time: NaiveDateTime::from_timestamp_opt(1526522699, 918000000) }); /// # Ok::<(), serde_json::Error>(()) /// ``` + #[must_use] pub fn deserialize<'de, D>(d: D) -> Result, D::Error> where D: de::Deserializer<'de>, @@ -851,6 +869,7 @@ pub mod ts_seconds { /// assert_eq!(as_string, r#"{"time":1431684000}"#); /// # Ok::<(), serde_json::Error>(()) /// ``` + #[must_use] pub fn serialize(dt: &NaiveDateTime, serializer: S) -> Result where S: ser::Serializer, @@ -868,15 +887,17 @@ pub mod ts_seconds { /// # use chrono::NaiveDateTime; /// # use serde_derive::Deserialize; /// use chrono::naive::serde::ts_seconds::deserialize as from_ts; - /// #[derive(Deserialize)] + /// #[derive(Debug, PartialEq, Deserialize)] /// struct S { /// #[serde(deserialize_with = "from_ts")] /// time: NaiveDateTime /// } /// /// let my_s: S = serde_json::from_str(r#"{ "time": 1431684000 }"#)?; + /// assert_eq!(my_s, S { time: NaiveDateTime::from_timestamp_opt(1431684000, 0).unwrap() }); /// # Ok::<(), serde_json::Error>(()) /// ``` + #[must_use] pub fn deserialize<'de, D>(d: D) -> Result where D: de::Deserializer<'de>, @@ -968,6 +989,7 @@ pub mod ts_seconds_option { /// assert_eq!(as_string, r#"{"time":1526522699}"#); /// # Ok::<(), serde_json::Error>(()) /// ``` + #[must_use] pub fn serialize(opt: &Option, serializer: S) -> Result where S: ser::Serializer, @@ -985,18 +1007,20 @@ pub mod ts_seconds_option { /// # Example: /// /// ```rust - /// # use chrono::naive::{NaiveDate, NaiveDateTime}; + /// # use chrono::naive::NaiveDateTime; /// # use serde_derive::Deserialize; /// use chrono::naive::serde::ts_seconds_option::deserialize as from_tsopt; - /// #[derive(Deserialize)] + /// #[derive(Debug, PartialEq, Deserialize)] /// struct S { /// #[serde(deserialize_with = "from_tsopt")] /// time: Option /// } /// /// let my_s: S = serde_json::from_str(r#"{ "time": 1431684000 }"#)?; + /// assert_eq!(my_s, S { time: NaiveDateTime::from_timestamp_opt(1431684000, 0) }); /// # Ok::<(), serde_json::Error>(()) /// ``` + #[must_use] pub fn deserialize<'de, D>(d: D) -> Result, D::Error> where D: de::Deserializer<'de>, diff --git a/vendor/chrono/src/naive/datetime/tests.rs b/vendor/chrono/src/naive/datetime/tests.rs index 202bdb34d..07309a48a 100644 --- a/vendor/chrono/src/naive/datetime/tests.rs +++ b/vendor/chrono/src/naive/datetime/tests.rs @@ -330,7 +330,7 @@ fn test_nanosecond_range() { } #[test] -fn test_and_timezone() { +fn test_and_local_timezone() { let ndt = NaiveDate::from_ymd_opt(2022, 6, 15).unwrap().and_hms_opt(18, 59, 36).unwrap(); let dt_utc = ndt.and_local_timezone(Utc).unwrap(); assert_eq!(dt_utc.naive_local(), ndt); @@ -341,3 +341,11 @@ fn test_and_timezone() { assert_eq!(dt_offset.naive_local(), ndt); assert_eq!(dt_offset.timezone(), offset_tz); } + +#[test] +fn test_and_utc() { + let ndt = NaiveDate::from_ymd_opt(2023, 1, 30).unwrap().and_hms_opt(19, 32, 33).unwrap(); + let dt_utc = ndt.and_utc(); + assert_eq!(dt_utc.naive_local(), ndt); + assert_eq!(dt_utc.timezone(), Utc); +} diff --git a/vendor/chrono/src/naive/internals.rs b/vendor/chrono/src/naive/internals.rs index 05305b506..65b47ae73 100644 --- a/vendor/chrono/src/naive/internals.rs +++ b/vendor/chrono/src/naive/internals.rs @@ -17,10 +17,8 @@ use crate::Weekday; use core::{fmt, i32}; -use num_integer::{div_rem, mod_floor}; -use num_traits::FromPrimitive; -/// The internal date representation. This also includes the packed `Mdf` value. +/// The internal date representation: `year << 13 | Of` pub(super) type DateImpl = i32; pub(super) const MAX_YEAR: DateImpl = i32::MAX >> 13; @@ -53,7 +51,7 @@ pub(super) const FE: YearFlags = YearFlags(0o07); pub(super) const G: YearFlags = YearFlags(0o16); pub(super) const GF: YearFlags = YearFlags(0o06); -static YEAR_TO_FLAGS: [YearFlags; 400] = [ +const YEAR_TO_FLAGS: &[YearFlags; 400] = &[ BA, G, F, E, DC, B, A, G, FE, D, C, B, AG, F, E, D, CB, A, G, F, ED, C, B, A, GF, E, D, C, BA, G, F, E, DC, B, A, G, FE, D, C, B, AG, F, E, D, CB, A, G, F, ED, C, B, A, GF, E, D, C, BA, G, F, E, DC, B, A, G, FE, D, C, B, AG, F, E, D, CB, A, G, F, ED, C, B, A, GF, E, D, C, BA, G, F, @@ -72,7 +70,7 @@ static YEAR_TO_FLAGS: [YearFlags; 400] = [ D, CB, A, G, F, ED, C, B, A, GF, E, D, C, // 400 ]; -static YEAR_DELTAS: [u8; 401] = [ +const YEAR_DELTAS: &[u8; 401] = &[ 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, @@ -94,46 +92,48 @@ static YEAR_DELTAS: [u8; 401] = [ 96, 97, 97, 97, 97, // 400+1 ]; -pub(super) fn cycle_to_yo(cycle: u32) -> (u32, u32) { - let (mut year_mod_400, mut ordinal0) = div_rem(cycle, 365); - let delta = u32::from(YEAR_DELTAS[year_mod_400 as usize]); +pub(super) const fn cycle_to_yo(cycle: u32) -> (u32, u32) { + let mut year_mod_400 = cycle / 365; + let mut ordinal0 = cycle % 365; + let delta = YEAR_DELTAS[year_mod_400 as usize] as u32; if ordinal0 < delta { year_mod_400 -= 1; - ordinal0 += 365 - u32::from(YEAR_DELTAS[year_mod_400 as usize]); + ordinal0 += 365 - YEAR_DELTAS[year_mod_400 as usize] as u32; } else { ordinal0 -= delta; } (year_mod_400, ordinal0 + 1) } -pub(super) fn yo_to_cycle(year_mod_400: u32, ordinal: u32) -> u32 { - year_mod_400 * 365 + u32::from(YEAR_DELTAS[year_mod_400 as usize]) + ordinal - 1 +pub(super) const fn yo_to_cycle(year_mod_400: u32, ordinal: u32) -> u32 { + year_mod_400 * 365 + YEAR_DELTAS[year_mod_400 as usize] as u32 + ordinal - 1 } impl YearFlags { #[allow(unreachable_pub)] // public as an alias for benchmarks only #[doc(hidden)] // for benchmarks only #[inline] - pub fn from_year(year: i32) -> YearFlags { - let year = mod_floor(year, 400); + #[must_use] + pub const fn from_year(year: i32) -> YearFlags { + let year = year.rem_euclid(400); YearFlags::from_year_mod_400(year) } #[inline] - pub(super) fn from_year_mod_400(year: i32) -> YearFlags { + pub(super) const fn from_year_mod_400(year: i32) -> YearFlags { YEAR_TO_FLAGS[year as usize] } #[inline] - pub(super) fn ndays(&self) -> u32 { + pub(super) const fn ndays(&self) -> u32 { let YearFlags(flags) = *self; - 366 - u32::from(flags >> 3) + 366 - (flags >> 3) as u32 } #[inline] - pub(super) fn isoweek_delta(&self) -> u32 { + pub(super) const fn isoweek_delta(&self) -> u32 { let YearFlags(flags) = *self; - let mut delta = u32::from(flags) & 0b0111; + let mut delta = (flags & 0b0111) as u32; if delta < 3 { delta += 7; } @@ -172,12 +172,13 @@ impl fmt::Debug for YearFlags { } } +// OL: (ordinal << 1) | leap year flag pub(super) const MIN_OL: u32 = 1 << 1; -pub(super) const MAX_OL: u32 = 366 << 1; // larger than the non-leap last day `(365 << 1) | 1` +pub(super) const MAX_OL: u32 = 366 << 1; // `(366 << 1) | 1` would be day 366 in a non-leap year pub(super) const MAX_MDL: u32 = (12 << 6) | (31 << 1) | 1; const XX: i8 = -128; -static MDL_TO_OL: [i8; MAX_MDL as usize + 1] = [ +const MDL_TO_OL: &[i8; MAX_MDL as usize + 1] = &[ XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, // 0 @@ -220,7 +221,7 @@ static MDL_TO_OL: [i8; MAX_MDL as usize + 1] = [ 100, // 12 ]; -static OL_TO_MDL: [u8; MAX_OL as usize + 1] = [ +const OL_TO_MDL: &[u8; MAX_OL as usize + 1] = &[ 0, 0, // 0 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, @@ -265,60 +266,76 @@ static OL_TO_MDL: [u8; MAX_OL as usize + 1] = [ /// /// The whole bits except for the least 3 bits are referred as `Ol` (ordinal and leap flag), /// which is an index to the `OL_TO_MDL` lookup table. +/// +/// The methods implemented on `Of` always return a valid value. #[derive(PartialEq, PartialOrd, Copy, Clone)] -pub(super) struct Of(pub(crate) u32); +pub(super) struct Of(u32); impl Of { #[inline] - pub(super) fn new(ordinal: u32, YearFlags(flags): YearFlags) -> Option { - match ordinal <= 366 { - true => Some(Of((ordinal << 4) | u32::from(flags))), - false => None, - } + pub(super) const fn new(ordinal: u32, YearFlags(flags): YearFlags) -> Option { + let of = Of((ordinal << 4) | flags as u32); + of.validate() + } + + pub(super) const fn from_date_impl(date_impl: DateImpl) -> Of { + // We assume the value in the `DateImpl` is valid. + Of((date_impl & 0b1_1111_1111_1111) as u32) } #[inline] - pub(super) fn from_mdf(Mdf(mdf): Mdf) -> Of { + pub(super) const fn from_mdf(Mdf(mdf): Mdf) -> Option { let mdl = mdf >> 3; - match MDL_TO_OL.get(mdl as usize) { - Some(&v) => Of(mdf.wrapping_sub((i32::from(v) as u32 & 0x3ff) << 3)), - None => Of(0), + if mdl > MAX_MDL { + // Panicking on out-of-bounds indexing would be reasonable, but just return `None`. + return None; } + // Array is indexed from `[1..=MAX_MDL]`, with a `0` index having a meaningless value. + let v = MDL_TO_OL[mdl as usize]; + let of = Of(mdf.wrapping_sub((v as i32 as u32 & 0x3ff) << 3)); + of.validate() } #[inline] - pub(super) fn valid(&self) -> bool { - let Of(of) = *self; - let ol = of >> 3; - (MIN_OL..=MAX_OL).contains(&ol) + pub(super) const fn inner(&self) -> u32 { + self.0 } + /// Returns `(ordinal << 1) | leap-year-flag`. #[inline] - pub(super) const fn ordinal(&self) -> u32 { - let Of(of) = *self; - of >> 4 + const fn ol(&self) -> u32 { + self.0 >> 3 } #[inline] - pub(super) fn with_ordinal(&self, ordinal: u32) -> Option { - if ordinal > 366 { - return None; + const fn validate(self) -> Option { + let ol = self.ol(); + match ol >= MIN_OL && ol <= MAX_OL { + true => Some(self), + false => None, } + } - let Of(of) = *self; - Some(Of((of & 0b1111) | (ordinal << 4))) + #[inline] + pub(super) const fn ordinal(&self) -> u32 { + self.0 >> 4 + } + + #[inline] + pub(super) const fn with_ordinal(&self, ordinal: u32) -> Option { + let of = Of((ordinal << 4) | (self.0 & 0b1111)); + of.validate() } #[inline] pub(super) const fn flags(&self) -> YearFlags { - let Of(of) = *self; - YearFlags((of & 0b1111) as u8) + YearFlags((self.0 & 0b1111) as u8) } #[inline] - pub(super) fn weekday(&self) -> Weekday { + pub(super) const fn weekday(&self) -> Weekday { let Of(of) = *self; - Weekday::from_u32(((of >> 4) + (of & 0b111)) % 7).unwrap() + weekday_from_u32_mod7((of >> 4) + (of & 0b111)) } #[inline] @@ -326,25 +343,29 @@ impl Of { // week ordinal = ordinal + delta let Of(of) = *self; let weekord = (of >> 4).wrapping_add(self.flags().isoweek_delta()); - (weekord / 7, Weekday::from_u32(weekord % 7).unwrap()) + (weekord / 7, weekday_from_u32_mod7(weekord)) } #[cfg_attr(feature = "cargo-clippy", allow(clippy::wrong_self_convention))] #[inline] - pub(super) fn to_mdf(&self) -> Mdf { + pub(super) const fn to_mdf(&self) -> Mdf { Mdf::from_of(*self) } + /// Returns an `Of` with the next day, or `None` if this is the last day of the year. #[inline] - pub(super) const fn succ(&self) -> Of { - let Of(of) = *self; - Of(of + (1 << 4)) + pub(super) const fn succ(&self) -> Option { + let of = Of(self.0 + (1 << 4)); + of.validate() } + /// Returns an `Of` with the previous day, or `None` if this is the first day of the year. #[inline] - pub(super) const fn pred(&self) -> Of { - let Of(of) = *self; - Of(of - (1 << 4)) + pub(super) const fn pred(&self) -> Option { + match self.ordinal() { + 1 => None, + _ => Some(Of(self.0 - (1 << 4))), + } } } @@ -366,34 +387,44 @@ impl fmt::Debug for Of { /// The whole bits except for the least 3 bits are referred as `Mdl` /// (month, day of month and leap flag), /// which is an index to the `MDL_TO_OL` lookup table. +/// +/// The methods implemented on `Mdf` do not always return a valid value. +/// Dates that can't exist, like February 30, can still be represented. +/// Use `Mdl::valid` to check whether the date is valid. #[derive(PartialEq, PartialOrd, Copy, Clone)] -pub(super) struct Mdf(pub(super) u32); +pub(super) struct Mdf(u32); impl Mdf { #[inline] - pub(super) fn new(month: u32, day: u32, YearFlags(flags): YearFlags) -> Option { - match month <= 12 && day <= 31 { - true => Some(Mdf((month << 9) | (day << 4) | u32::from(flags))), + pub(super) const fn new(month: u32, day: u32, YearFlags(flags): YearFlags) -> Option { + match month >= 1 && month <= 12 && day >= 1 && day <= 31 { + true => Some(Mdf((month << 9) | (day << 4) | flags as u32)), false => None, } } #[inline] - pub(super) fn from_of(Of(of): Of) -> Mdf { + pub(super) const fn from_of(Of(of): Of) -> Mdf { let ol = of >> 3; - match OL_TO_MDL.get(ol as usize) { - Some(&v) => Mdf(of + (u32::from(v) << 3)), - None => Mdf(0), + if ol <= MAX_OL { + // Array is indexed from `[1..=MAX_OL]`, with a `0` index having a meaningless value. + Mdf(of + ((OL_TO_MDL[ol as usize] as u32) << 3)) + } else { + // Panicking here would be reasonable, but we are just going on with a safe value. + Mdf(0) } } #[cfg(test)] - pub(super) fn valid(&self) -> bool { + pub(super) const fn valid(&self) -> bool { let Mdf(mdf) = *self; let mdl = mdf >> 3; - match MDL_TO_OL.get(mdl as usize) { - Some(&v) => v >= 0, - None => false, + if mdl <= MAX_MDL { + // Array is indexed from `[1..=MAX_MDL]`, with a `0` index having a meaningless value. + MDL_TO_OL[mdl as usize] >= 0 + } else { + // Panicking here would be reasonable, but we are just going on with a safe value. + false } } @@ -404,7 +435,7 @@ impl Mdf { } #[inline] - pub(super) fn with_month(&self, month: u32) -> Option { + pub(super) const fn with_month(&self, month: u32) -> Option { if month > 12 { return None; } @@ -420,7 +451,7 @@ impl Mdf { } #[inline] - pub(super) fn with_day(&self, day: u32) -> Option { + pub(super) const fn with_day(&self, day: u32) -> Option { if day > 31 { return None; } @@ -430,14 +461,14 @@ impl Mdf { } #[inline] - pub(super) fn with_flags(&self, YearFlags(flags): YearFlags) -> Mdf { + pub(super) const fn with_flags(&self, YearFlags(flags): YearFlags) -> Mdf { let Mdf(mdf) = *self; - Mdf((mdf & !0b1111) | u32::from(flags)) + Mdf((mdf & !0b1111) | flags as u32) } #[cfg_attr(feature = "cargo-clippy", allow(clippy::wrong_self_convention))] #[inline] - pub(super) fn to_of(&self) -> Of { + pub(super) const fn to_of(&self) -> Option { Of::from_mdf(*self) } } @@ -456,11 +487,26 @@ impl fmt::Debug for Mdf { } } +/// Create a `Weekday` from an `u32`, with Monday = 0. +/// Infallible, takes any `n` and applies `% 7`. +#[inline] +const fn weekday_from_u32_mod7(n: u32) -> Weekday { + match n % 7 { + 0 => Weekday::Mon, + 1 => Weekday::Tue, + 2 => Weekday::Wed, + 3 => Weekday::Thu, + 4 => Weekday::Fri, + 5 => Weekday::Sat, + _ => Weekday::Sun, + } +} + #[cfg(test)] mod tests { - use num_iter::range_inclusive; use std::u32; + use super::weekday_from_u32_mod7; use super::{Mdf, Of}; use super::{YearFlags, A, AG, B, BA, C, CB, D, DC, E, ED, F, FE, G, GF}; use crate::Weekday; @@ -507,7 +553,7 @@ mod tests { #[test] fn test_of() { fn check(expected: bool, flags: YearFlags, ordinal1: u32, ordinal2: u32) { - for ordinal in range_inclusive(ordinal1, ordinal2) { + for ordinal in ordinal1..=ordinal2 { let of = match Of::new(ordinal, flags) { Some(of) => of, None if !expected => continue, @@ -515,7 +561,7 @@ mod tests { }; assert!( - of.valid() == expected, + of.validate().is_some() == expected, "ordinal {} = {:?} should be {} for dominical year {:?}", ordinal, of, @@ -543,8 +589,8 @@ mod tests { #[test] fn test_mdf_valid() { fn check(expected: bool, flags: YearFlags, month1: u32, day1: u32, month2: u32, day2: u32) { - for month in range_inclusive(month1, month2) { - for day in range_inclusive(day1, day2) { + for month in month1..=month2 { + for day in day1..=day2 { let mdf = match Mdf::new(month, day, flags) { Some(mdf) => mdf, None if !expected => continue, @@ -634,9 +680,8 @@ mod tests { #[test] fn test_of_fields() { for &flags in FLAGS.iter() { - for ordinal in range_inclusive(1u32, 366) { - let of = Of::new(ordinal, flags).unwrap(); - if of.valid() { + for ordinal in 1u32..=366 { + if let Some(of) = Of::new(ordinal, flags) { assert_eq!(of.ordinal(), ordinal); } } @@ -648,15 +693,10 @@ mod tests { fn check(flags: YearFlags, ordinal: u32) { let of = Of::new(ordinal, flags).unwrap(); - for ordinal in range_inclusive(0u32, 1024) { - let of = match of.with_ordinal(ordinal) { - Some(of) => of, - None if ordinal > 366 => continue, - None => panic!("failed to create Of with ordinal {}", ordinal), - }; - - assert_eq!(of.valid(), Of::new(ordinal, flags).unwrap().valid()); - if of.valid() { + for ordinal in 0u32..=1024 { + let of = of.with_ordinal(ordinal); + assert_eq!(of, Of::new(ordinal, flags)); + if let Some(of) = of { assert_eq!(of.ordinal(), ordinal); } } @@ -691,7 +731,7 @@ mod tests { for &flags in FLAGS.iter() { let mut prev = Of::new(1, flags).unwrap().weekday(); - for ordinal in range_inclusive(2u32, flags.ndays()) { + for ordinal in 2u32..=flags.ndays() { let of = Of::new(ordinal, flags).unwrap(); let expected = prev.succ(); assert_eq!(of.weekday(), expected); @@ -703,8 +743,8 @@ mod tests { #[test] fn test_mdf_fields() { for &flags in FLAGS.iter() { - for month in range_inclusive(1u32, 12) { - for day in range_inclusive(1u32, 31) { + for month in 1u32..=12 { + for day in 1u32..31 { let mdf = match Mdf::new(month, day, flags) { Some(mdf) => mdf, None => continue, @@ -724,7 +764,7 @@ mod tests { fn check(flags: YearFlags, month: u32, day: u32) { let mdf = Mdf::new(month, day, flags).unwrap(); - for month in range_inclusive(0u32, 16) { + for month in 0u32..=16 { let mdf = match mdf.with_month(month) { Some(mdf) => mdf, None if month > 12 => continue, @@ -737,7 +777,7 @@ mod tests { } } - for day in range_inclusive(0u32, 1024) { + for day in 0u32..=1024 { let mdf = match mdf.with_day(day) { Some(mdf) => mdf, None if day > 31 => continue, @@ -780,37 +820,74 @@ mod tests { #[test] fn test_of_to_mdf() { - for i in range_inclusive(0u32, 8192) { - let of = Of(i); - assert_eq!(of.valid(), of.to_mdf().valid()); + for i in 0u32..=8192 { + if let Some(of) = Of(i).validate() { + assert!(of.to_mdf().valid()); + } } } #[test] fn test_mdf_to_of() { - for i in range_inclusive(0u32, 8192) { + for i in 0u32..=8192 { let mdf = Mdf(i); - assert_eq!(mdf.valid(), mdf.to_of().valid()); + assert_eq!(mdf.valid(), mdf.to_of().is_some()); } } #[test] fn test_of_to_mdf_to_of() { - for i in range_inclusive(0u32, 8192) { - let of = Of(i); - if of.valid() { - assert_eq!(of, of.to_mdf().to_of()); + for i in 0u32..=8192 { + if let Some(of) = Of(i).validate() { + assert_eq!(of, of.to_mdf().to_of().unwrap()); } } } #[test] fn test_mdf_to_of_to_mdf() { - for i in range_inclusive(0u32, 8192) { + for i in 0u32..=8192 { let mdf = Mdf(i); if mdf.valid() { - assert_eq!(mdf, mdf.to_of().to_mdf()); + assert_eq!(mdf, mdf.to_of().unwrap().to_mdf()); } } } + + #[test] + fn test_invalid_returns_none() { + let regular_year = YearFlags::from_year(2023); + let leap_year = YearFlags::from_year(2024); + assert!(Of::new(0, regular_year).is_none()); + assert!(Of::new(366, regular_year).is_none()); + assert!(Of::new(366, leap_year).is_some()); + assert!(Of::new(367, regular_year).is_none()); + + assert!(Mdf::new(0, 1, regular_year).is_none()); + assert!(Mdf::new(13, 1, regular_year).is_none()); + assert!(Mdf::new(1, 0, regular_year).is_none()); + assert!(Mdf::new(1, 32, regular_year).is_none()); + assert!(Mdf::new(2, 31, regular_year).is_some()); + + assert!(Of::from_mdf(Mdf::new(2, 30, regular_year).unwrap()).is_none()); + assert!(Of::from_mdf(Mdf::new(2, 30, leap_year).unwrap()).is_none()); + assert!(Of::from_mdf(Mdf::new(2, 29, regular_year).unwrap()).is_none()); + assert!(Of::from_mdf(Mdf::new(2, 29, leap_year).unwrap()).is_some()); + assert!(Of::from_mdf(Mdf::new(2, 28, regular_year).unwrap()).is_some()); + + assert!(Of::new(365, regular_year).unwrap().succ().is_none()); + assert!(Of::new(365, leap_year).unwrap().succ().is_some()); + assert!(Of::new(366, leap_year).unwrap().succ().is_none()); + + assert!(Of::new(1, regular_year).unwrap().pred().is_none()); + assert!(Of::new(1, leap_year).unwrap().pred().is_none()); + } + + #[test] + fn test_weekday_from_u32_mod7() { + for i in 0..=1000 { + assert_eq!(weekday_from_u32_mod7(i), Weekday::try_from((i % 7) as u8).unwrap()); + } + assert_eq!(weekday_from_u32_mod7(u32::MAX), Weekday::Thu); + } } diff --git a/vendor/chrono/src/naive/isoweek.rs b/vendor/chrono/src/naive/isoweek.rs index 6a4fcfd11..df5556a12 100644 --- a/vendor/chrono/src/naive/isoweek.rs +++ b/vendor/chrono/src/naive/isoweek.rs @@ -46,7 +46,8 @@ pub(super) fn iso_week_from_yof(year: i32, of: Of) -> IsoWeek { (year, rawweek) } }; - IsoWeek { ywf: (year << 10) | (week << 4) as DateImpl | DateImpl::from(of.flags().0) } + let flags = YearFlags::from_year(year); + IsoWeek { ywf: (year << 10) | (week << 4) as DateImpl | DateImpl::from(flags.0) } } impl IsoWeek { @@ -57,7 +58,7 @@ impl IsoWeek { /// ``` /// use chrono::{NaiveDate, Datelike, Weekday}; /// - /// let d = NaiveDate::from_isoywd(2015, 1, Weekday::Mon); + /// let d = NaiveDate::from_isoywd_opt(2015, 1, Weekday::Mon).unwrap(); /// assert_eq!(d.iso_week().year(), 2015); /// ``` /// @@ -66,7 +67,7 @@ impl IsoWeek { /// /// ``` /// # use chrono::{NaiveDate, Datelike, Weekday}; - /// # let d = NaiveDate::from_isoywd(2015, 1, Weekday::Mon); + /// # let d = NaiveDate::from_isoywd_opt(2015, 1, Weekday::Mon).unwrap(); /// assert_eq!(d.year(), 2014); /// assert_eq!(d, NaiveDate::from_ymd_opt(2014, 12, 29).unwrap()); /// ``` @@ -84,7 +85,7 @@ impl IsoWeek { /// ``` /// use chrono::{NaiveDate, Datelike, Weekday}; /// - /// let d = NaiveDate::from_isoywd(2015, 15, Weekday::Mon); + /// let d = NaiveDate::from_isoywd_opt(2015, 15, Weekday::Mon).unwrap(); /// assert_eq!(d.iso_week().week(), 15); /// ``` #[inline] @@ -101,7 +102,7 @@ impl IsoWeek { /// ``` /// use chrono::{NaiveDate, Datelike, Weekday}; /// - /// let d = NaiveDate::from_isoywd(2015, 15, Weekday::Mon); + /// let d = NaiveDate::from_isoywd_opt(2015, 15, Weekday::Mon).unwrap(); /// assert_eq!(d.iso_week().week0(), 14); /// ``` #[inline] @@ -164,4 +165,38 @@ mod tests { assert_eq!(maxweek.week0(), 0); assert_eq!(format!("{:?}", maxweek), NaiveDate::MAX.format("%G-W%V").to_string()); } + + #[test] + fn test_iso_week_equivalence_for_first_week() { + let monday = NaiveDate::from_ymd_opt(2024, 12, 30).unwrap(); + let friday = NaiveDate::from_ymd_opt(2025, 1, 3).unwrap(); + + assert_eq!(monday.iso_week(), friday.iso_week()); + } + + #[test] + fn test_iso_week_equivalence_for_last_week() { + let monday = NaiveDate::from_ymd_opt(2026, 12, 28).unwrap(); + let friday = NaiveDate::from_ymd_opt(2027, 1, 1).unwrap(); + + assert_eq!(monday.iso_week(), friday.iso_week()); + } + + #[test] + fn test_iso_week_ordering_for_first_week() { + let monday = NaiveDate::from_ymd_opt(2024, 12, 30).unwrap(); + let friday = NaiveDate::from_ymd_opt(2025, 1, 3).unwrap(); + + assert!(monday.iso_week() >= friday.iso_week()); + assert!(monday.iso_week() <= friday.iso_week()); + } + + #[test] + fn test_iso_week_ordering_for_last_week() { + let monday = NaiveDate::from_ymd_opt(2026, 12, 28).unwrap(); + let friday = NaiveDate::from_ymd_opt(2027, 1, 1).unwrap(); + + assert!(monday.iso_week() >= friday.iso_week()); + assert!(monday.iso_week() <= friday.iso_week()); + } } diff --git a/vendor/chrono/src/naive/time/mod.rs b/vendor/chrono/src/naive/time/mod.rs index 1d36583aa..3700c5cba 100644 --- a/vendor/chrono/src/naive/time/mod.rs +++ b/vendor/chrono/src/naive/time/mod.rs @@ -8,14 +8,15 @@ use core::borrow::Borrow; use core::ops::{Add, AddAssign, Sub, SubAssign}; use core::{fmt, str}; -use num_integer::div_mod_floor; #[cfg(feature = "rkyv")] use rkyv::{Archive, Deserialize, Serialize}; #[cfg(any(feature = "alloc", feature = "std", test))] use crate::format::DelayedFormat; -use crate::format::{parse, write_hundreds, ParseError, ParseResult, Parsed, StrftimeItems}; -use crate::format::{Fixed, Item, Numeric, Pad}; +use crate::format::{ + parse, parse_and_remainder, write_hundreds, Fixed, Item, Numeric, Pad, ParseError, ParseResult, + Parsed, StrftimeItems, +}; use crate::oldtime::Duration as OldDuration; use crate::Timelike; @@ -74,7 +75,7 @@ mod tests; /// All methods accepting fractional seconds will accept such values. /// /// ``` -/// use chrono::{NaiveDate, NaiveTime, Utc, TimeZone}; +/// use chrono::{NaiveDate, NaiveTime, Utc}; /// /// let t = NaiveTime::from_hms_milli_opt(8, 59, 59, 1_000).unwrap(); /// @@ -161,7 +162,7 @@ mod tests; /// will be represented as the second part being 60, as required by ISO 8601. /// /// ``` -/// use chrono::{Utc, TimeZone, NaiveDate}; +/// use chrono::{Utc, NaiveDate}; /// /// let dt = NaiveDate::from_ymd_opt(2015, 6, 30).unwrap().and_hms_milli_opt(23, 59, 59, 1_000).unwrap().and_local_timezone(Utc).unwrap(); /// assert_eq!(format!("{:?}", dt), "2015-06-30T23:59:60Z"); @@ -214,6 +215,7 @@ impl NaiveTime { /// Panics on invalid hour, minute and/or second. #[deprecated(since = "0.4.23", note = "use `from_hms_opt()` instead")] #[inline] + #[must_use] pub fn from_hms(hour: u32, min: u32, sec: u32) -> NaiveTime { NaiveTime::from_hms_opt(hour, min, sec).expect("invalid time") } @@ -239,7 +241,8 @@ impl NaiveTime { /// assert!(from_hms_opt(23, 59, 60).is_none()); /// ``` #[inline] - pub fn from_hms_opt(hour: u32, min: u32, sec: u32) -> Option { + #[must_use] + pub const fn from_hms_opt(hour: u32, min: u32, sec: u32) -> Option { NaiveTime::from_hms_nano_opt(hour, min, sec, 0) } @@ -251,6 +254,7 @@ impl NaiveTime { /// Panics on invalid hour, minute, second and/or millisecond. #[deprecated(since = "0.4.23", note = "use `from_hms_milli_opt()` instead")] #[inline] + #[must_use] pub fn from_hms_milli(hour: u32, min: u32, sec: u32, milli: u32) -> NaiveTime { NaiveTime::from_hms_milli_opt(hour, min, sec, milli).expect("invalid time") } @@ -278,6 +282,7 @@ impl NaiveTime { /// assert!(from_hmsm_opt(23, 59, 59, 2_000).is_none()); /// ``` #[inline] + #[must_use] pub fn from_hms_milli_opt(hour: u32, min: u32, sec: u32, milli: u32) -> Option { milli .checked_mul(1_000_000) @@ -292,6 +297,7 @@ impl NaiveTime { /// Panics on invalid hour, minute, second and/or microsecond. #[deprecated(since = "0.4.23", note = "use `from_hms_micro_opt()` instead")] #[inline] + #[must_use] pub fn from_hms_micro(hour: u32, min: u32, sec: u32, micro: u32) -> NaiveTime { NaiveTime::from_hms_micro_opt(hour, min, sec, micro).expect("invalid time") } @@ -319,6 +325,7 @@ impl NaiveTime { /// assert!(from_hmsu_opt(23, 59, 59, 2_000_000).is_none()); /// ``` #[inline] + #[must_use] pub fn from_hms_micro_opt(hour: u32, min: u32, sec: u32, micro: u32) -> Option { micro.checked_mul(1_000).and_then(|nano| NaiveTime::from_hms_nano_opt(hour, min, sec, nano)) } @@ -331,6 +338,7 @@ impl NaiveTime { /// Panics on invalid hour, minute, second and/or nanosecond. #[deprecated(since = "0.4.23", note = "use `from_hms_nano_opt()` instead")] #[inline] + #[must_use] pub fn from_hms_nano(hour: u32, min: u32, sec: u32, nano: u32) -> NaiveTime { NaiveTime::from_hms_nano_opt(hour, min, sec, nano).expect("invalid time") } @@ -358,7 +366,8 @@ impl NaiveTime { /// assert!(from_hmsn_opt(23, 59, 59, 2_000_000_000).is_none()); /// ``` #[inline] - pub fn from_hms_nano_opt(hour: u32, min: u32, sec: u32, nano: u32) -> Option { + #[must_use] + pub const fn from_hms_nano_opt(hour: u32, min: u32, sec: u32, nano: u32) -> Option { if hour >= 24 || min >= 60 || sec >= 60 || nano >= 2_000_000_000 { return None; } @@ -374,6 +383,7 @@ impl NaiveTime { /// Panics on invalid number of seconds and/or nanosecond. #[deprecated(since = "0.4.23", note = "use `from_num_seconds_from_midnight_opt()` instead")] #[inline] + #[must_use] pub fn from_num_seconds_from_midnight(secs: u32, nano: u32) -> NaiveTime { NaiveTime::from_num_seconds_from_midnight_opt(secs, nano).expect("invalid time") } @@ -399,7 +409,8 @@ impl NaiveTime { /// assert!(from_nsecs_opt(86399, 2_000_000_000).is_none()); /// ``` #[inline] - pub fn from_num_seconds_from_midnight_opt(secs: u32, nano: u32) -> Option { + #[must_use] + pub const fn from_num_seconds_from_midnight_opt(secs: u32, nano: u32) -> Option { if secs >= 86_400 || nano >= 2_000_000_000 { return None; } @@ -473,6 +484,28 @@ impl NaiveTime { parsed.to_naive_time() } + /// Parses a string from a user-specified format into a new `NaiveTime` value, and a slice with + /// the remaining portion of the string. + /// See the [`format::strftime` module](../format/strftime/index.html) + /// on the supported escape sequences. + /// + /// Similar to [`parse_from_str`](#method.parse_from_str). + /// + /// # Example + /// + /// ```rust + /// # use chrono::{NaiveTime}; + /// let (time, remainder) = NaiveTime::parse_and_remainder( + /// "3h4m33s trailing text", "%-Hh%-Mm%-Ss").unwrap(); + /// assert_eq!(time, NaiveTime::from_hms_opt(3, 4, 33).unwrap()); + /// assert_eq!(remainder, " trailing text"); + /// ``` + pub fn parse_and_remainder<'a>(s: &'a str, fmt: &str) -> ParseResult<(NaiveTime, &'a str)> { + let mut parsed = Parsed::new(); + let remainder = parse_and_remainder(&mut parsed, s, StrftimeItems::new(fmt))?; + parsed.to_naive_time().map(|t| (t, remainder)) + } + /// Adds given `Duration` to the current time, /// and also returns the number of *seconds* /// in the integral number of days ignored from the addition. @@ -483,7 +516,7 @@ impl NaiveTime { /// ``` /// use chrono::{Duration, NaiveTime}; /// - /// let from_hms = NaiveTime::from_hms; + /// let from_hms = |h, m, s| { NaiveTime::from_hms_opt(h, m, s).unwrap() }; /// /// assert_eq!(from_hms(3, 4, 5).overflowing_add_signed(Duration::hours(11)), /// (from_hms(14, 4, 5), 0)); @@ -492,6 +525,7 @@ impl NaiveTime { /// assert_eq!(from_hms(3, 4, 5).overflowing_add_signed(Duration::hours(-7)), /// (from_hms(20, 4, 5), -86_400)); /// ``` + #[must_use] pub fn overflowing_add_signed(&self, mut rhs: OldDuration) -> (NaiveTime, i64) { let mut secs = self.secs; let mut frac = self.frac; @@ -565,7 +599,7 @@ impl NaiveTime { /// ``` /// use chrono::{Duration, NaiveTime}; /// - /// let from_hms = NaiveTime::from_hms; + /// let from_hms = |h, m, s| { NaiveTime::from_hms_opt(h, m, s).unwrap() }; /// /// assert_eq!(from_hms(3, 4, 5).overflowing_sub_signed(Duration::hours(2)), /// (from_hms(1, 4, 5), 0)); @@ -575,6 +609,7 @@ impl NaiveTime { /// (from_hms(1, 4, 5), -86_400)); /// ``` #[inline] + #[must_use] pub fn overflowing_sub_signed(&self, rhs: OldDuration) -> (NaiveTime, i64) { let (time, rhs) = self.overflowing_add_signed(-rhs); (time, -rhs) // safe to negate, rhs is within +/- (2^63 / 1000) @@ -595,7 +630,7 @@ impl NaiveTime { /// ``` /// use chrono::{Duration, NaiveTime}; /// - /// let from_hmsm = NaiveTime::from_hms_milli; + /// let from_hmsm = |h, m, s, milli| { NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap() }; /// let since = NaiveTime::signed_duration_since; /// /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 7, 900)), @@ -621,7 +656,7 @@ impl NaiveTime { /// /// ``` /// # use chrono::{Duration, NaiveTime}; - /// # let from_hmsm = NaiveTime::from_hms_milli; + /// # let from_hmsm = |h, m, s, milli| { NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap() }; /// # let since = NaiveTime::signed_duration_since; /// assert_eq!(since(from_hmsm(3, 0, 59, 1_000), from_hmsm(3, 0, 59, 0)), /// Duration::seconds(1)); @@ -634,6 +669,7 @@ impl NaiveTime { /// assert_eq!(since(from_hmsm(3, 0, 59, 1_000), from_hmsm(2, 59, 59, 1_000)), /// Duration::seconds(61)); /// ``` + #[must_use] pub fn signed_duration_since(self, rhs: NaiveTime) -> OldDuration { // | | :leap| | | | | | | :leap| | // | | : | | | | | | | : | | @@ -696,6 +732,7 @@ impl NaiveTime { #[cfg(any(feature = "alloc", feature = "std", test))] #[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))] #[inline] + #[must_use] pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat where I: Iterator + Clone, @@ -741,14 +778,17 @@ impl NaiveTime { #[cfg(any(feature = "alloc", feature = "std", test))] #[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))] #[inline] + #[must_use] pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat> { self.format_with_items(StrftimeItems::new(fmt)) } /// Returns a triple of the hour, minute and second numbers. fn hms(&self) -> (u32, u32, u32) { - let (mins, sec) = div_mod_floor(self.secs, 60); - let (hour, min) = div_mod_floor(mins, 60); + let sec = self.secs % 60; + let mins = self.secs / 60; + let min = mins % 60; + let hour = mins / 60; (hour, min, sec) } @@ -803,7 +843,8 @@ impl Timelike for NaiveTime { /// ([Why?](#leap-second-handling)) /// Use the proper [formatting method](#method.format) to get a human-readable representation. /// - /// ``` + #[cfg_attr(not(feature = "std"), doc = "```ignore")] + #[cfg_attr(feature = "std", doc = "```")] /// # use chrono::{NaiveTime, Timelike}; /// let leap = NaiveTime::from_hms_milli_opt(23, 59, 59, 1_000).unwrap(); /// assert_eq!(leap.second(), 59); @@ -831,7 +872,8 @@ impl Timelike for NaiveTime { /// You can reduce the range with `time.nanosecond() % 1_000_000_000`, or /// use the proper [formatting method](#method.format) to get a human-readable representation. /// - /// ``` + #[cfg_attr(not(feature = "std"), doc = "```ignore")] + #[cfg_attr(feature = "std", doc = "```")] /// # use chrono::{NaiveTime, Timelike}; /// let leap = NaiveTime::from_hms_milli_opt(23, 59, 59, 1_000).unwrap(); /// assert_eq!(leap.nanosecond(), 1_000_000_000); @@ -969,17 +1011,16 @@ impl Timelike for NaiveTime { /// An addition of `Duration` to `NaiveTime` wraps around and never overflows or underflows. /// In particular the addition ignores integral number of days. /// -/// As a part of Chrono's [leap second handling](#leap-second-handling), -/// the addition assumes that **there is no leap second ever**, -/// except when the `NaiveTime` itself represents a leap second -/// in which case the assumption becomes that **there is exactly a single leap second ever**. +/// As a part of Chrono's [leap second handling], the addition assumes that **there is no leap +/// second ever**, except when the `NaiveTime` itself represents a leap second in which case the +/// assumption becomes that **there is exactly a single leap second ever**. /// /// # Example /// /// ``` /// use chrono::{Duration, NaiveTime}; /// -/// let from_hmsm = NaiveTime::from_hms_milli; +/// let from_hmsm = |h, m, s, milli| { NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap() }; /// /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::zero(), from_hmsm(3, 5, 7, 0)); /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(1), from_hmsm(3, 5, 8, 0)); @@ -995,7 +1036,7 @@ impl Timelike for NaiveTime { /// /// ``` /// # use chrono::{Duration, NaiveTime}; -/// # let from_hmsm = NaiveTime::from_hms_milli; +/// # let from_hmsm = |h, m, s, milli| { NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap() }; /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(22*60*60), from_hmsm(1, 5, 7, 0)); /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(-8*60*60), from_hmsm(19, 5, 7, 0)); /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::days(800), from_hmsm(3, 5, 7, 0)); @@ -1005,7 +1046,7 @@ impl Timelike for NaiveTime { /// /// ``` /// # use chrono::{Duration, NaiveTime}; -/// # let from_hmsm = NaiveTime::from_hms_milli; +/// # let from_hmsm = |h, m, s, milli| { NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap() }; /// let leap = from_hmsm(3, 5, 59, 1_300); /// assert_eq!(leap + Duration::zero(), from_hmsm(3, 5, 59, 1_300)); /// assert_eq!(leap + Duration::milliseconds(-500), from_hmsm(3, 5, 59, 800)); @@ -1015,6 +1056,8 @@ impl Timelike for NaiveTime { /// assert_eq!(leap + Duration::seconds(-10), from_hmsm(3, 5, 50, 300)); /// assert_eq!(leap + Duration::days(1), from_hmsm(3, 5, 59, 300)); /// ``` +/// +/// [leap second handling]: crate::NaiveTime#leap-second-handling impl Add for NaiveTime { type Output = NaiveTime; @@ -1035,17 +1078,16 @@ impl AddAssign for NaiveTime { /// In particular the addition ignores integral number of days. /// It is the same as the addition with a negated `Duration`. /// -/// As a part of Chrono's [leap second handling](#leap-second-handling), -/// the addition assumes that **there is no leap second ever**, -/// except when the `NaiveTime` itself represents a leap second -/// in which case the assumption becomes that **there is exactly a single leap second ever**. +/// As a part of Chrono's [leap second handling], the subtraction assumes that **there is no leap +/// second ever**, except when the `NaiveTime` itself represents a leap second in which case the +/// assumption becomes that **there is exactly a single leap second ever**. /// /// # Example /// /// ``` /// use chrono::{Duration, NaiveTime}; /// -/// let from_hmsm = NaiveTime::from_hms_milli; +/// let from_hmsm = |h, m, s, milli| { NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap() }; /// /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::zero(), from_hmsm(3, 5, 7, 0)); /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::seconds(1), from_hmsm(3, 5, 6, 0)); @@ -1059,7 +1101,7 @@ impl AddAssign for NaiveTime { /// /// ``` /// # use chrono::{Duration, NaiveTime}; -/// # let from_hmsm = NaiveTime::from_hms_milli; +/// # let from_hmsm = |h, m, s, milli| { NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap() }; /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::seconds(8*60*60), from_hmsm(19, 5, 7, 0)); /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::days(800), from_hmsm(3, 5, 7, 0)); /// ``` @@ -1068,7 +1110,7 @@ impl AddAssign for NaiveTime { /// /// ``` /// # use chrono::{Duration, NaiveTime}; -/// # let from_hmsm = NaiveTime::from_hms_milli; +/// # let from_hmsm = |h, m, s, milli| { NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap() }; /// let leap = from_hmsm(3, 5, 59, 1_300); /// assert_eq!(leap - Duration::zero(), from_hmsm(3, 5, 59, 1_300)); /// assert_eq!(leap - Duration::milliseconds(200), from_hmsm(3, 5, 59, 1_100)); @@ -1076,6 +1118,8 @@ impl AddAssign for NaiveTime { /// assert_eq!(leap - Duration::seconds(60), from_hmsm(3, 5, 0, 300)); /// assert_eq!(leap - Duration::days(1), from_hmsm(3, 6, 0, 300)); /// ``` +/// +/// [leap second handling]: crate::NaiveTime#leap-second-handling impl Sub for NaiveTime { type Output = NaiveTime; @@ -1110,7 +1154,7 @@ impl SubAssign for NaiveTime { /// ``` /// use chrono::{Duration, NaiveTime}; /// -/// let from_hmsm = NaiveTime::from_hms_milli; +/// let from_hmsm = |h, m, s, milli| { NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap() }; /// /// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(3, 5, 7, 900), Duration::zero()); /// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(3, 5, 7, 875), Duration::milliseconds(25)); @@ -1128,7 +1172,7 @@ impl SubAssign for NaiveTime { /// /// ``` /// # use chrono::{Duration, NaiveTime}; -/// # let from_hmsm = NaiveTime::from_hms_milli; +/// # let from_hmsm = |h, m, s, milli| { NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap() }; /// assert_eq!(from_hmsm(3, 0, 59, 1_000) - from_hmsm(3, 0, 59, 0), Duration::seconds(1)); /// assert_eq!(from_hmsm(3, 0, 59, 1_500) - from_hmsm(3, 0, 59, 0), /// Duration::milliseconds(1500)); -- cgit v1.2.3