From 61b7ffbb7a95df577c308eb0f2ab5c68e1566cf1 Mon Sep 17 00:00:00 2001 From: Paul Dicker Date: Tue, 12 Sep 2023 08:31:00 +0200 Subject: [PATCH] Deny leap second if secs != 59 in `from_hms_nano_opt` --- src/naive/date.rs | 24 ++++++++++++------------ src/naive/time/mod.rs | 33 ++++++++++++++++++++------------- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/naive/date.rs b/src/naive/date.rs index 0dcb36fcda..677c5fa6f0 100644 --- a/src/naive/date.rs +++ b/src/naive/date.rs @@ -867,8 +867,8 @@ impl NaiveDate { /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and millisecond. /// - /// The millisecond part can exceed 1,000 - /// in order to represent the [leap second](./struct.NaiveTime.html#leap-second-handling). + /// The millisecond part is allowed to exceed 1,000,000,000 in order to represent a [leap second]( + /// ./struct.NaiveTime.html#leap-second-handling), but only when `sec == 59`. /// /// # Panics /// @@ -882,8 +882,8 @@ impl NaiveDate { /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and millisecond. /// - /// The millisecond part can exceed 1,000 - /// in order to represent the [leap second](./struct.NaiveTime.html#leap-second-handling). + /// The millisecond part is allowed to exceed 1,000,000,000 in order to represent a [leap second]( + /// ./struct.NaiveTime.html#leap-second-handling), but only when `sec == 59`. /// /// # Errors /// @@ -917,8 +917,8 @@ impl NaiveDate { /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and microsecond. /// - /// The microsecond part can exceed 1,000,000 - /// in order to represent the [leap second](./struct.NaiveTime.html#leap-second-handling). + /// The microsecond part is allowed to exceed 1,000,000,000 in order to represent a [leap second]( + /// ./struct.NaiveTime.html#leap-second-handling), but only when `sec == 59`. /// /// # Panics /// @@ -946,8 +946,8 @@ impl NaiveDate { /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and microsecond. /// - /// The microsecond part can exceed 1,000,000 - /// in order to represent the [leap second](./struct.NaiveTime.html#leap-second-handling). + /// The microsecond part is allowed to exceed 1,000,000,000 in order to represent a [leap second]( + /// ./struct.NaiveTime.html#leap-second-handling), but only when `sec == 59`. /// /// # Errors /// @@ -981,8 +981,8 @@ impl NaiveDate { /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and nanosecond. /// - /// The nanosecond part can exceed 1,000,000,000 - /// in order to represent the [leap second](./struct.NaiveTime.html#leap-second-handling). + /// The nanosecond part is allowed to exceed 1,000,000,000 in order to represent a [leap second]( + /// ./struct.NaiveTime.html#leap-second-handling), but only when `sec == 59`. /// /// # Panics /// @@ -996,8 +996,8 @@ impl NaiveDate { /// Makes a new `NaiveDateTime` from the current date, hour, minute, second and nanosecond. /// - /// The nanosecond part can exceed 1,000,000,000 - /// in order to represent the [leap second](./struct.NaiveTime.html#leap-second-handling). + /// The nanosecond part is allowed to exceed 1,000,000,000 in order to represent a [leap second]( + /// ./struct.NaiveTime.html#leap-second-handling), but only when `sec == 59`. /// /// # Errors /// diff --git a/src/naive/time/mod.rs b/src/naive/time/mod.rs index 88e9d50ce8..72644e2647 100644 --- a/src/naive/time/mod.rs +++ b/src/naive/time/mod.rs @@ -177,6 +177,10 @@ mod tests; /// For such cases the human-readable representation is ambiguous and would be read back to the next /// non-leap second. /// +/// A `NaiveTime` with a leap second that is not on a minute boundary can only be created from a +/// [`DateTime`](crate::DateTime) with fractional minutes as offset, or using +/// [`Timelike::with_nanosecond()`]. +/// /// ``` /// use chrono::{FixedOffset, NaiveDate, TimeZone}; /// @@ -239,8 +243,8 @@ impl NaiveTime { /// Makes a new `NaiveTime` from hour, minute and second. /// - /// No [leap second](#leap-second-handling) is allowed here; - /// use `NaiveTime::from_hms_*_opt` methods with a subsecond parameter instead. + /// The millisecond part is allowed to exceed 1,000,000,000 in order to represent a + /// [leap second](#leap-second-handling), but only when `sec == 59`. /// /// # Errors /// @@ -282,8 +286,8 @@ impl NaiveTime { /// Makes a new `NaiveTime` from hour, minute, second and millisecond. /// - /// The millisecond part can exceed 1,000 - /// in order to represent the [leap second](#leap-second-handling). + /// The millisecond part is allowed to exceed 1,000,000,000 in order to represent a + /// [leap second](#leap-second-handling), but only when `sec == 59`. /// /// # Errors /// @@ -318,8 +322,8 @@ impl NaiveTime { /// Makes a new `NaiveTime` from hour, minute, second and microsecond. /// - /// The microsecond part can exceed 1,000,000 - /// in order to represent the [leap second](#leap-second-handling). + /// The microsecond part is allowed to exceed 1,000,000,000 in order to represent a + /// [leap second](#leap-second-handling), but only when `sec == 59`. /// /// # Panics /// @@ -333,8 +337,8 @@ impl NaiveTime { /// Makes a new `NaiveTime` from hour, minute, second and microsecond. /// - /// The microsecond part can exceed 1,000,000 - /// in order to represent the [leap second](#leap-second-handling). + /// The microsecond part is allowed to exceed 1,000,000,000 in order to represent a + /// [leap second](#leap-second-handling), but only when `sec == 59`. /// /// # Errors /// @@ -369,8 +373,8 @@ impl NaiveTime { /// Makes a new `NaiveTime` from hour, minute, second and nanosecond. /// - /// The nanosecond part can exceed 1,000,000,000 - /// in order to represent the [leap second](#leap-second-handling). + /// The nanosecond part is allowed to exceed 1,000,000,000 in order to represent a + /// [leap second](#leap-second-handling), but only when `sec == 59`. /// /// # Panics /// @@ -384,8 +388,8 @@ impl NaiveTime { /// Makes a new `NaiveTime` from hour, minute, second and nanosecond. /// - /// The nanosecond part can exceed 1,000,000,000 - /// in order to represent the [leap second](#leap-second-handling). + /// The nanosecond part is allowed to exceed 1,000,000,000 in order to represent a + /// [leap second](#leap-second-handling), but only when `sec == 59`. /// /// # Errors /// @@ -409,7 +413,10 @@ impl NaiveTime { #[inline] #[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 { + if (hour >= 24 || min >= 60 || sec >= 60) + || (nano >= 1_000_000_000 && sec != 59) + || nano >= 2_000_000_000 + { return None; } let secs = hour * 3600 + min * 60 + sec;