diff --git a/src/date.rs b/src/date.rs index eef2659..5dfa58d 100644 --- a/src/date.rs +++ b/src/date.rs @@ -46,7 +46,7 @@ impl Date { /// Makes a new `DateTime` from the current date and given `NaiveTime`. /// The offset in the current date is preserved. /// - /// Fails on invalid datetime. + /// Panics on invalid datetime. #[inline] pub fn and_time(&self, time: NaiveTime) -> Option> { let localdt = self.naive_local().and_time(time); @@ -56,7 +56,7 @@ impl Date { /// Makes a new `DateTime` from the current date, hour, minute and second. /// The offset in the current date is preserved. /// - /// Fails on invalid hour, minute and/or second. + /// Panics on invalid hour, minute and/or second. #[inline] pub fn and_hms(&self, hour: u32, min: u32, sec: u32) -> DateTime { self.and_hms_opt(hour, min, sec).expect("invalid time") @@ -75,7 +75,7 @@ impl Date { /// The millisecond part can exceed 1,000 in order to represent the leap second. /// The offset in the current date is preserved. /// - /// Fails on invalid hour, minute, second and/or millisecond. + /// Panics on invalid hour, minute, second and/or millisecond. #[inline] pub fn and_hms_milli(&self, hour: u32, min: u32, sec: u32, milli: u32) -> DateTime { self.and_hms_milli_opt(hour, min, sec, milli).expect("invalid time") @@ -96,7 +96,7 @@ impl Date { /// The microsecond part can exceed 1,000,000 in order to represent the leap second. /// The offset in the current date is preserved. /// - /// Fails on invalid hour, minute, second and/or microsecond. + /// Panics on invalid hour, minute, second and/or microsecond. #[inline] pub fn and_hms_micro(&self, hour: u32, min: u32, sec: u32, micro: u32) -> DateTime { self.and_hms_micro_opt(hour, min, sec, micro).expect("invalid time") @@ -117,7 +117,7 @@ impl Date { /// The nanosecond part can exceed 1,000,000,000 in order to represent the leap second. /// The offset in the current date is preserved. /// - /// Fails on invalid hour, minute, second and/or nanosecond. + /// Panics on invalid hour, minute, second and/or nanosecond. #[inline] pub fn and_hms_nano(&self, hour: u32, min: u32, sec: u32, nano: u32) -> DateTime { self.and_hms_nano_opt(hour, min, sec, nano).expect("invalid time") @@ -136,7 +136,7 @@ impl Date { /// Makes a new `Date` for the next date. /// - /// Fails when `self` is the last representable date. + /// Panics when `self` is the last representable date. #[inline] pub fn succ(&self) -> Date { self.succ_opt().expect("out of bound") @@ -152,7 +152,7 @@ impl Date { /// Makes a new `Date` for the prior date. /// - /// Fails when `self` is the first representable date. + /// Panics when `self` is the first representable date. #[inline] pub fn pred(&self) -> Date { self.pred_opt().expect("out of bound") diff --git a/src/naive/date.rs b/src/naive/date.rs index fbd928b..f42e9fc 100644 --- a/src/naive/date.rs +++ b/src/naive/date.rs @@ -89,7 +89,7 @@ impl NaiveDate { /// Makes a new `NaiveDate` from year, month and day. /// This assumes the proleptic Gregorian calendar, with the year 0 being 1 BCE. /// - /// Fails on the out-of-range date, invalid month and/or day. + /// Panics on the out-of-range date, invalid month and/or day. /// /// # Example /// @@ -134,7 +134,7 @@ impl NaiveDate { /// Makes a new `NaiveDate` from year and day of year (DOY or "ordinal"). /// This assumes the proleptic Gregorian calendar, with the year 0 being 1 BCE. /// - /// Fails on the out-of-range date and/or invalid DOY. + /// Panics on the out-of-range date and/or invalid DOY. /// /// # Example /// @@ -181,7 +181,7 @@ impl NaiveDate { /// This assumes the proleptic Gregorian calendar, with the year 0 being 1 BCE. /// The resulting `NaiveDate` may have a different year from the input year. /// - /// Fails on the out-of-range date and/or invalid week number. + /// Panics on the out-of-range date and/or invalid week number. /// /// # Example /// @@ -269,7 +269,7 @@ impl NaiveDate { /// Makes a new `NaiveDate` from the number of days since January 1, 1 (Day 1) /// in the proleptic Gregorian calendar. /// - /// Fails on the out-of-range date. + /// Panics on the out-of-range date. /// /// # Example /// @@ -329,16 +329,28 @@ impl NaiveDate { /// Ok(NaiveDate::from_ymd(2015, 9, 5))); /// assert_eq!(NaiveDate::parse_from_str("5sep2015", "%d%b%Y"), /// Ok(NaiveDate::from_ymd(2015, 9, 5))); + /// ~~~~ /// - /// // time and offset is ignored for the purpose of parsing + /// Time and offset is ignored for the purpose of parsing. + /// + /// ~~~~ + /// # use chrono::NaiveDate; /// assert_eq!(NaiveDate::parse_from_str("2014-5-17T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"), /// Ok(NaiveDate::from_ymd(2014, 5, 17))); + /// ~~~~ /// - /// // either out-of-bound dates or insufficient fields are errors + /// Out-of-bound dates or insufficient fields are errors. + /// + /// ~~~~ + /// # use chrono::NaiveDate; /// assert!(NaiveDate::parse_from_str("2015/9", "%Y/%m").is_err()); /// assert!(NaiveDate::parse_from_str("2015/9/31", "%Y/%m/%d").is_err()); + /// ~~~~ /// - /// // all parsed fields should be consistent to each other, otherwise it's an error + /// All parsed fields should be consistent to each other, otherwise it's an error. + /// + /// ~~~~ + /// # use chrono::NaiveDate; /// assert!(NaiveDate::parse_from_str("Sat, 09 Aug 2013", "%a, %d %b %Y").is_err()); /// ~~~~ pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult { @@ -368,7 +380,10 @@ impl NaiveDate { /// Makes a new `NaiveDateTime` from the current date, hour, minute and second. /// - /// Fails on invalid hour, minute and/or second. + /// No [leap second](../time/struct.NaiveTime.html#leap-second-what?) is allowed here; + /// use `NaiveDate::and_hms_*` methods with a subsecond parameter instead. + /// + /// Panics on invalid hour, minute and/or second. /// /// # Example /// @@ -389,6 +404,9 @@ impl NaiveDate { /// Makes a new `NaiveDateTime` from the current date, hour, minute and second. /// + /// No [leap second](../time/struct.NaiveTime.html#leap-second-what?) is allowed here; + /// use `NaiveDate::and_hms_*_opt` methods with a subsecond parameter instead. + /// /// Returns `None` on invalid hour, minute and/or second. /// /// # Example @@ -408,9 +426,11 @@ 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. /// - /// Fails on invalid hour, minute, second and/or millisecond. + /// The millisecond part can exceed 1,000 + /// in order to represent the [leap second](../time/struct.NaiveTime.html#leap-second-what?). + /// + /// Panics on invalid hour, minute, second and/or millisecond. /// /// # Example /// @@ -431,7 +451,9 @@ 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. + /// + /// The millisecond part can exceed 1,000 + /// in order to represent the [leap second](../time/struct.NaiveTime.html#leap-second-what?). /// /// Returns `None` on invalid hour, minute, second and/or millisecond. /// @@ -455,9 +477,11 @@ 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. /// - /// Fails on invalid hour, minute, second and/or microsecond. + /// The microsecond part can exceed 1,000,000 + /// in order to represent the [leap second](../time/struct.NaiveTime.html#leap-second-what?). + /// + /// Panics on invalid hour, minute, second and/or microsecond. /// /// # Example /// @@ -478,7 +502,9 @@ 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. + /// + /// The microsecond part can exceed 1,000,000 + /// in order to represent the [leap second](../time/struct.NaiveTime.html#leap-second-what?). /// /// Returns `None` on invalid hour, minute, second and/or microsecond. /// @@ -502,9 +528,11 @@ 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. /// - /// Fails on invalid hour, minute, second and/or nanosecond. + /// The nanosecond part can exceed 1,000,000,000 + /// in order to represent the [leap second](../time/struct.NaiveTime.html#leap-second-what?). + /// + /// Panics on invalid hour, minute, second and/or nanosecond. /// /// # Example /// @@ -525,7 +553,9 @@ 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. + /// + /// The nanosecond part can exceed 1,000,000,000 + /// in order to represent the [leap second](../time/struct.NaiveTime.html#leap-second-what?). /// /// Returns `None` on invalid hour, minute, second and/or nanosecond. /// @@ -583,7 +613,7 @@ impl NaiveDate { /// Makes a new `NaiveDate` for the next date. /// - /// Fails when `self` is the last representable date. + /// Panics when `self` is the last representable date. /// /// # Example /// @@ -620,7 +650,7 @@ impl NaiveDate { /// Makes a new `NaiveDate` for the prior date. /// - /// Fails when `self` is the first representable date. + /// Panics when `self` is the first representable date. /// /// # Example /// @@ -748,7 +778,7 @@ impl NaiveDate { /// which gets converted to a string only when actual formatting happens. /// You may use the `to_string` method to get a `String`, /// or just feed it into `print!` and other formatting macros. - /// (In this way it avoids the excees memory allocation.) + /// (In this way it avoids the redundant memory allocation.) /// /// A wrong format string does *not* issue an error immediately. /// Rather, converting or formatting the `DelayedFormat` fails. @@ -846,7 +876,7 @@ impl hash::Hash for NaiveDate { /// An addition of `Duration` to `NaiveDate` discards the fractional days, /// rounding to the closest integral number of days towards `Duration::zero()`. /// -/// Fails on underflow or overflow. +/// Panics on underflow or overflow. /// Use `NaiveDate::checked_add` for detecting that. /// /// # Example @@ -907,7 +937,7 @@ impl Sub for NaiveDate { /// A subtraction of `Duration` from `NaiveDate` discards the fractional days, /// rounding to the closest integral number of days towards `Duration::zero()`. /// -/// Fails on underflow or overflow. +/// Panics on underflow or overflow. /// Use `NaiveDate::checked_sub` for detecting that. /// /// # Example diff --git a/src/naive/datetime.rs b/src/naive/datetime.rs index b6170f0..e6b240f 100644 --- a/src/naive/datetime.rs +++ b/src/naive/datetime.rs @@ -38,7 +38,7 @@ impl NaiveDateTime { /// since January 1, 1970 0:00:00 UTC (aka "UNIX timestamp") /// and the number of nanoseconds since the last whole non-leap second. /// - /// Fails on the out-of-range number of seconds and/or invalid nanosecond. + /// Panics on the out-of-range number of seconds and/or invalid nanosecond. #[inline] pub fn from_timestamp(secs: i64, nsecs: u32) -> NaiveDateTime { let datetime = NaiveDateTime::from_timestamp_opt(secs, nsecs); diff --git a/src/naive/time.rs b/src/naive/time.rs index 9cb36d0..56baf26 100644 --- a/src/naive/time.rs +++ b/src/naive/time.rs @@ -17,6 +17,44 @@ use format::{parse, Parsed, ParseError, ParseResult, DelayedFormat, StrftimeItem /// ISO 8601 time without timezone. /// Allows for the nanosecond precision and optional leap second representation. +/// +/// # Leap second WHAT? +/// +/// Since 1960s, the manmade atomic clock has been so accurate that +/// it is much more accurate than Earth's own motion. +/// It became desirable to define the civil time in terms of the atomic clock, +/// but that risks the desynchronization of the civil time from Earth. +/// To account for this, the designers of the Coordinated Universal Time (UTC) +/// made that the UTC should be kept within 0.9 seconds of the observed Earth-bound time. +/// When the mean solar day is longer than the ideal (86,400 seconds), +/// the error slowly accumulates and it is necessary to add a **leap second** +/// to slow the UTC down a bit. +/// (We may also remove a second to speed the UTC up a bit, but it never happened.) +/// The leap second, if any, follows 23:59:59 of June 30 or December 31 in the UTC. +/// +/// Fast forward to the 21st century, +/// we have seen 26 leap seconds from January 1972 to December 2015. +/// Yes, 26 seconds. Probably you can read this paragraph within 26 seconds. +/// But those 26 seconds, and possibly more in the future, are never predictable, +/// and whether to add a leap second or not is known only before 6 months. +/// Internet-based clocks (via NTP) do account for known leap seconds, +/// but the system API normally doesn't (and often can't, with no network connection) +/// and there is no reliable way to retrieve leap second information. +/// +/// Chrono does not try to accurately implement leap seconds; it is impossible. +/// Rather, **it allows for leap seconds but behaves as if there are *no other* leap seconds.** +/// Various time arithmetics will ignore any possible leap second(s) +/// except when the operand were actually a leap second. +/// The leap second is indicated via fractional seconds more than 1 second, +/// so values like `NaiveTime::from_hms_milli(23, 56, 4, 1_005)` are allowed; +/// that value would mean 5ms after the beginning of a leap second following 23:56:04. +/// Parsing and formatting will correctly handle times that look like leap seconds, +/// and you can then conveniently ignore leap seconds if you are not prepared for them. +/// +/// If you cannot tolerate this behavior, +/// you must use a separate `TimeZone` for the International Atomic Time (TAI). +/// TAI is like UTC but has no leap seconds, and thus slightly differs from UTC. +/// Chrono 0.2 does not provide such implementation, but it is planned for 0.3. #[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone)] #[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))] pub struct NaiveTime { @@ -27,7 +65,22 @@ pub struct NaiveTime { impl NaiveTime { /// Makes a new `NaiveTime` from hour, minute and second. /// - /// Fails on invalid hour, minute and/or second. + /// No [leap second](#leap-second-what?) is allowed here; + /// use `NaiveTime::from_hms_*` methods with a subsecond parameter instead. + /// + /// Panics on invalid hour, minute and/or second. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::{NaiveTime, Timelike}; + /// + /// let t = NaiveTime::from_hms(23, 56, 4); + /// assert_eq!(t.hour(), 23); + /// assert_eq!(t.minute(), 56); + /// assert_eq!(t.second(), 4); + /// assert_eq!(t.nanosecond(), 0); + /// ~~~~ #[inline] pub fn from_hms(hour: u32, min: u32, sec: u32) -> NaiveTime { NaiveTime::from_hms_opt(hour, min, sec).expect("invalid time") @@ -35,25 +88,72 @@ impl NaiveTime { /// Makes a new `NaiveTime` from hour, minute and second. /// + /// No [leap second](#leap-second-what?) is allowed here; + /// use `NaiveTime::from_hms_*_opt` methods with a subsecond parameter instead. + /// /// Returns `None` on invalid hour, minute and/or second. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::NaiveTime; + /// + /// let hms = |h,m,s| NaiveTime::from_hms_opt(h, m, s); + /// assert!(hms(0, 0, 0).is_some()); + /// assert!(hms(23, 59, 59).is_some()); + /// assert!(hms(24, 0, 0).is_none()); + /// assert!(hms(23, 60, 0).is_none()); + /// assert!(hms(23, 59, 60).is_none()); + /// ~~~~ #[inline] pub fn from_hms_opt(hour: u32, min: u32, sec: u32) -> Option { NaiveTime::from_hms_nano_opt(hour, min, sec, 0) } /// Makes a new `NaiveTime` from hour, minute, second and millisecond. - /// The millisecond part can exceed 1,000 in order to represent the leap second. /// - /// Fails on invalid hour, minute, second and/or millisecond. + /// The millisecond part can exceed 1,000 + /// in order to represent the [leap second](#leap-second-what?). + /// + /// Panics on invalid hour, minute, second and/or millisecond. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::{NaiveTime, Timelike}; + /// + /// let t = NaiveTime::from_hms_milli(23, 56, 4, 12); + /// assert_eq!(t.hour(), 23); + /// assert_eq!(t.minute(), 56); + /// assert_eq!(t.second(), 4); + /// assert_eq!(t.nanosecond(), 12_000_000); + /// ~~~~ #[inline] 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") } /// Makes a new `NaiveTime` from hour, minute, second and millisecond. - /// The millisecond part can exceed 1,000 in order to represent the leap second. + /// + /// The millisecond part can exceed 1,000 + /// in order to represent the [leap second](#leap-second-what?). /// /// Returns `None` on invalid hour, minute, second and/or millisecond. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::NaiveTime; + /// + /// let hmsm = |h,m,s,milli| NaiveTime::from_hms_milli_opt(h, m, s, milli); + /// assert!(hmsm(0, 0, 0, 0).is_some()); + /// assert!(hmsm(23, 59, 59, 999).is_some()); + /// assert!(hmsm(23, 59, 59, 1_999).is_some()); // a leap second following 23:59:59 + /// assert!(hmsm(24, 0, 0, 0).is_none()); + /// assert!(hmsm(23, 60, 0, 0).is_none()); + /// assert!(hmsm(23, 59, 60, 0).is_none()); + /// assert!(hmsm(23, 59, 59, 2_000).is_none()); + /// ~~~~ #[inline] pub fn from_hms_milli_opt(hour: u32, min: u32, sec: u32, milli: u32) -> Option { milli.checked_mul(1_000_000) @@ -61,18 +161,49 @@ 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. /// - /// Fails on invalid hour, minute, second and/or microsecond. + /// The microsecond part can exceed 1,000,000 + /// in order to represent the [leap second](#leap-second-what?). + /// + /// Panics on invalid hour, minute, second and/or microsecond. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::{NaiveTime, Timelike}; + /// + /// let t = NaiveTime::from_hms_micro(23, 56, 4, 12_345); + /// assert_eq!(t.hour(), 23); + /// assert_eq!(t.minute(), 56); + /// assert_eq!(t.second(), 4); + /// assert_eq!(t.nanosecond(), 12_345_000); + /// ~~~~ #[inline] 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") } /// 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. + /// + /// The microsecond part can exceed 1,000,000 + /// in order to represent the [leap second](#leap-second-what?). /// /// Returns `None` on invalid hour, minute, second and/or microsecond. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::NaiveTime; + /// + /// let hmsu = |h,m,s,micro| NaiveTime::from_hms_micro_opt(h, m, s, micro); + /// assert!(hmsu(0, 0, 0, 0).is_some()); + /// assert!(hmsu(23, 59, 59, 999_999).is_some()); + /// assert!(hmsu(23, 59, 59, 1_999_999).is_some()); // a leap second following 23:59:59 + /// assert!(hmsu(24, 0, 0, 0).is_none()); + /// assert!(hmsu(23, 60, 0, 0).is_none()); + /// assert!(hmsu(23, 59, 60, 0).is_none()); + /// assert!(hmsu(23, 59, 59, 2_000_000).is_none()); + /// ~~~~ #[inline] pub fn from_hms_micro_opt(hour: u32, min: u32, sec: u32, micro: u32) -> Option { micro.checked_mul(1_000) @@ -80,18 +211,49 @@ 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. /// - /// Fails on invalid hour, minute, second and/or nanosecond. + /// The nanosecond part can exceed 1,000,000,000 + /// in order to represent the [leap second](#leap-second-what?). + /// + /// Panics on invalid hour, minute, second and/or nanosecond. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::{NaiveTime, Timelike}; + /// + /// let t = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678); + /// assert_eq!(t.hour(), 23); + /// assert_eq!(t.minute(), 56); + /// assert_eq!(t.second(), 4); + /// assert_eq!(t.nanosecond(), 12_345_678); + /// ~~~~ #[inline] 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") } /// 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. + /// + /// The nanosecond part can exceed 1,000,000,000 + /// in order to represent the [leap second](#leap-second-what?). /// /// Returns `None` on invalid hour, minute, second and/or nanosecond. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::NaiveTime; + /// + /// let hmsn = |h,m,s,nano| NaiveTime::from_hms_nano_opt(h, m, s, nano); + /// assert!(hmsn(0, 0, 0, 0).is_some()); + /// assert!(hmsn(23, 59, 59, 999_999_999).is_some()); + /// assert!(hmsn(23, 59, 59, 1_999_999_999).is_some()); // a leap second following 23:59:59 + /// assert!(hmsn(24, 0, 0, 0).is_none()); + /// assert!(hmsn(23, 60, 0, 0).is_none()); + /// assert!(hmsn(23, 59, 60, 0).is_none()); + /// assert!(hmsn(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 { if hour >= 24 || min >= 60 || sec >= 60 || nano >= 2_000_000_000 { return None; } @@ -100,18 +262,47 @@ impl NaiveTime { } /// Makes a new `NaiveTime` from the number of seconds since midnight and nanosecond. - /// The nanosecond part can exceed 1,000,000,000 in order to represent the leap second. /// - /// Fails on invalid number of seconds and/or nanosecond. + /// The nanosecond part can exceed 1,000,000,000 + /// in order to represent the [leap second](#leap-second-what?). + /// + /// Panics on invalid number of seconds and/or nanosecond. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::{NaiveTime, Timelike}; + /// + /// let t = NaiveTime::from_num_seconds_from_midnight(86164, 12_345_678); + /// assert_eq!(t.hour(), 23); + /// assert_eq!(t.minute(), 56); + /// assert_eq!(t.second(), 4); + /// assert_eq!(t.nanosecond(), 12_345_678); + /// ~~~~ #[inline] pub fn from_num_seconds_from_midnight(secs: u32, nano: u32) -> NaiveTime { NaiveTime::from_num_seconds_from_midnight_opt(secs, nano).expect("invalid time") } /// Makes a new `NaiveTime` from the number of seconds since midnight and nanosecond. - /// The nanosecond part can exceed 1,000,000,000 in order to represent the leap second. + /// + /// The nanosecond part can exceed 1,000,000,000 + /// in order to represent the [leap second](#leap-second-what?). /// /// Returns `None` on invalid number of seconds and/or nanosecond. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::NaiveTime; + /// + /// let secs = |secs,nano| NaiveTime::from_num_seconds_from_midnight_opt(secs, nano); + /// assert!(secs(0, 0).is_some()); + /// assert!(secs(86399, 999_999_999).is_some()); + /// assert!(secs(86399, 1_999_999_999).is_some()); // a leap second following 23:59:59 + /// assert!(secs(86400, 0).is_none()); + /// assert!(secs(86399, 2_000_000_000).is_none()); + /// ~~~~ #[inline] pub fn from_num_seconds_from_midnight_opt(secs: u32, nano: u32) -> Option { if secs >= 86400 || nano >= 2_000_000_000 { return None; } @@ -121,6 +312,58 @@ impl NaiveTime { /// Parses a string with the specified format string and returns a new `NaiveTime`. /// See the [`format::strftime` module](../../format/strftime/index.html) /// on the supported escape sequences. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::NaiveTime; + /// + /// assert_eq!(NaiveTime::parse_from_str("23:56:04", "%H:%M:%S"), + /// Ok(NaiveTime::from_hms(23, 56, 4))); + /// assert_eq!(NaiveTime::parse_from_str("pm012345.6789", "%p%I%M%S%.f"), + /// Ok(NaiveTime::from_hms_micro(13, 23, 45, 678_900))); + /// ~~~~ + /// + /// Date and offset is ignored for the purpose of parsing. + /// + /// ~~~~ + /// # use chrono::NaiveTime; + /// assert_eq!(NaiveTime::parse_from_str("2014-5-17T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"), + /// Ok(NaiveTime::from_hms(12, 34, 56))); + /// ~~~~ + /// + /// [Leap seconds](#leap-second-what?) are correctly handled by + /// treating any time of the form `hh:mm:60` as a leap second. + /// (This equally applies to the formatting, so the round trip is possible.) + /// + /// ~~~~ + /// # use chrono::NaiveTime; + /// assert_eq!(NaiveTime::parse_from_str("08:59:60.123", "%H:%M:%S%.f"), + /// Ok(NaiveTime::from_hms_milli(8, 59, 59, 1_123))); + /// ~~~~ + /// + /// Missing seconds are assumed to be zero, + /// but out-of-bound times or insufficient fields are errors otherwise. + /// + /// ~~~~ + /// # use chrono::NaiveTime; + /// assert_eq!(NaiveTime::parse_from_str("7:15", "%H:%M"), + /// Ok(NaiveTime::from_hms(7, 15, 0))); + /// + /// assert!(NaiveTime::parse_from_str("04m33s", "%Mm%Ss").is_err()); + /// assert!(NaiveTime::parse_from_str("12", "%H").is_err()); + /// assert!(NaiveTime::parse_from_str("17:60", "%H:%M").is_err()); + /// assert!(NaiveTime::parse_from_str("24:00:00", "%H:%M:%S").is_err()); + /// ~~~~ + /// + /// All parsed fields should be consistent to each other, otherwise it's an error. + /// Here `%H` is for 24-hour clocks, unlike `%I`, + /// and thus can be independently determined without AM/PM. + /// + /// ~~~~ + /// # use chrono::NaiveTime; + /// assert!(NaiveTime::parse_from_str("13:07 AM", "%H:%M %p").is_err()); + /// ~~~~ pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult { let mut parsed = Parsed::new(); try!(parse(&mut parsed, s, StrftimeItems::new(fmt))); @@ -128,6 +371,22 @@ impl NaiveTime { } /// Formats the time with the specified formatting items. + /// Otherwise it is same to the ordinary `format` method. + /// + /// The `Iterator` of items should be `Clone`able, + /// since the resulting `DelayedFormat` value may be formatted multiple times. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::NaiveTime; + /// use chrono::format::strftime::StrftimeItems; + /// + /// let fmt = StrftimeItems::new("%H:%M:%S"); + /// let t = NaiveTime::from_hms(23, 56, 4); + /// assert_eq!(t.format_with_items(fmt.clone()).to_string(), "23:56:04"); + /// assert_eq!(t.format("%H:%M:%S").to_string(), "23:56:04"); + /// ~~~~ #[inline] pub fn format_with_items<'a, I>(&self, items: I) -> DelayedFormat where I: Iterator> + Clone { @@ -137,6 +396,27 @@ impl NaiveTime { /// Formats the time with the specified format string. /// See the [`format::strftime` module](../../format/strftime/index.html) /// on the supported escape sequences. + /// + /// This returns a `DelayedFormat`, + /// which gets converted to a string only when actual formatting happens. + /// You may use the `to_string` method to get a `String`, + /// or just feed it into `print!` and other formatting macros. + /// (In this way it avoids the redundant memory allocation.) + /// + /// A wrong format string does *not* issue an error immediately. + /// Rather, converting or formatting the `DelayedFormat` fails. + /// You are recommended to immediately use `DelayedFormat` for this reason. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::NaiveTime; + /// + /// let t = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678); + /// assert_eq!(t.format("%H:%M:%S").to_string(), "23:56:04"); + /// assert_eq!(t.format("%H:%M:%S%.6f").to_string(), "23:56:04.012345"); + /// assert_eq!(t.format("%-I:%M %p").to_string(), "11:56 PM"); + /// ~~~~ #[inline] pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat> { self.format_with_items(StrftimeItems::new(fmt)) diff --git a/src/offset/fixed.rs b/src/offset/fixed.rs index 5745d5f..60ac2ee 100644 --- a/src/offset/fixed.rs +++ b/src/offset/fixed.rs @@ -25,7 +25,7 @@ impl FixedOffset { /// Makes a new `FixedOffset` for the Eastern Hemisphere with given timezone difference. /// The negative `secs` means the Western Hemisphere. /// - /// Fails on the out-of-bound `secs`. + /// Panics on the out-of-bound `secs`. pub fn east(secs: i32) -> FixedOffset { FixedOffset::east_opt(secs).expect("FixedOffset::east out of bounds") } @@ -45,7 +45,7 @@ impl FixedOffset { /// Makes a new `FixedOffset` for the Western Hemisphere with given timezone difference. /// The negative `secs` means the Eastern Hemisphere. /// - /// Fails on the out-of-bound `secs`. + /// Panics on the out-of-bound `secs`. pub fn west(secs: i32) -> FixedOffset { FixedOffset::west_opt(secs).expect("FixedOffset::west out of bounds") } diff --git a/src/offset/mod.rs b/src/offset/mod.rs index fec25b2..6e623b3 100644 --- a/src/offset/mod.rs +++ b/src/offset/mod.rs @@ -145,7 +145,7 @@ impl LocalResult> { } impl LocalResult { - /// Returns the single unique conversion result, or fails accordingly. + /// Returns the single unique conversion result, or panics accordingly. pub fn unwrap(self) -> T { match self { LocalResult::None => panic!("No such local time"), @@ -176,7 +176,7 @@ pub trait TimeZone: Sized + Clone { /// The time zone normally does not affect the date (unless it is between UTC-24 and UTC+24), /// but it will propagate to the `DateTime` values constructed via this date. /// - /// Fails on the out-of-range date, invalid month and/or day. + /// Panics on the out-of-range date, invalid month and/or day. fn ymd(&self, year: i32, month: u32, day: u32) -> Date { self.ymd_opt(year, month, day).unwrap() } @@ -201,7 +201,7 @@ pub trait TimeZone: Sized + Clone { /// The time zone normally does not affect the date (unless it is between UTC-24 and UTC+24), /// but it will propagate to the `DateTime` values constructed via this date. /// - /// Fails on the out-of-range date and/or invalid DOY. + /// Panics on the out-of-range date and/or invalid DOY. fn yo(&self, year: i32, ordinal: u32) -> Date { self.yo_opt(year, ordinal).unwrap() } @@ -228,7 +228,7 @@ pub trait TimeZone: Sized + Clone { /// The time zone normally does not affect the date (unless it is between UTC-24 and UTC+24), /// but it will propagate to the `DateTime` values constructed via this date. /// - /// Fails on the out-of-range date and/or invalid week number. + /// Panics on the out-of-range date and/or invalid week number. fn isoywd(&self, year: i32, week: u32, weekday: Weekday) -> Date { self.isoywd_opt(year, week, weekday).unwrap() } @@ -253,7 +253,7 @@ pub trait TimeZone: Sized + Clone { /// since January 1, 1970 0:00:00 UTC (aka "UNIX timestamp") /// and the number of nanoseconds since the last whole non-leap second. /// - /// Fails on the out-of-range number of seconds and/or invalid nanosecond. + /// Panics on the out-of-range number of seconds and/or invalid nanosecond. fn timestamp(&self, secs: i64, nsecs: u32) -> DateTime { self.timestamp_opt(secs, nsecs).unwrap() }