more documentation for `NaiveTime`; some terminology updates.

This commit is contained in:
Kang Seonghoon 2015-09-12 02:41:38 +09:00
parent ed3727931f
commit 24bc15fdd3
6 changed files with 360 additions and 50 deletions

View File

@ -46,7 +46,7 @@ impl<Tz: TimeZone> Date<Tz> {
/// Makes a new `DateTime` from the current date and given `NaiveTime`. /// Makes a new `DateTime` from the current date and given `NaiveTime`.
/// The offset in the current date is preserved. /// The offset in the current date is preserved.
/// ///
/// Fails on invalid datetime. /// Panics on invalid datetime.
#[inline] #[inline]
pub fn and_time(&self, time: NaiveTime) -> Option<DateTime<Tz>> { pub fn and_time(&self, time: NaiveTime) -> Option<DateTime<Tz>> {
let localdt = self.naive_local().and_time(time); let localdt = self.naive_local().and_time(time);
@ -56,7 +56,7 @@ impl<Tz: TimeZone> Date<Tz> {
/// Makes a new `DateTime` from the current date, hour, minute and second. /// Makes a new `DateTime` from the current date, hour, minute and second.
/// The offset in the current date is preserved. /// 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] #[inline]
pub fn and_hms(&self, hour: u32, min: u32, sec: u32) -> DateTime<Tz> { pub fn and_hms(&self, hour: u32, min: u32, sec: u32) -> DateTime<Tz> {
self.and_hms_opt(hour, min, sec).expect("invalid time") self.and_hms_opt(hour, min, sec).expect("invalid time")
@ -75,7 +75,7 @@ impl<Tz: TimeZone> Date<Tz> {
/// 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.
/// The offset in the current date is preserved. /// 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] #[inline]
pub fn and_hms_milli(&self, hour: u32, min: u32, sec: u32, milli: u32) -> DateTime<Tz> { pub fn and_hms_milli(&self, hour: u32, min: u32, sec: u32, milli: u32) -> DateTime<Tz> {
self.and_hms_milli_opt(hour, min, sec, milli).expect("invalid time") self.and_hms_milli_opt(hour, min, sec, milli).expect("invalid time")
@ -96,7 +96,7 @@ impl<Tz: TimeZone> Date<Tz> {
/// 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.
/// The offset in the current date is preserved. /// 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] #[inline]
pub fn and_hms_micro(&self, hour: u32, min: u32, sec: u32, micro: u32) -> DateTime<Tz> { pub fn and_hms_micro(&self, hour: u32, min: u32, sec: u32, micro: u32) -> DateTime<Tz> {
self.and_hms_micro_opt(hour, min, sec, micro).expect("invalid time") self.and_hms_micro_opt(hour, min, sec, micro).expect("invalid time")
@ -117,7 +117,7 @@ impl<Tz: TimeZone> Date<Tz> {
/// 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.
/// The offset in the current date is preserved. /// 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] #[inline]
pub fn and_hms_nano(&self, hour: u32, min: u32, sec: u32, nano: u32) -> DateTime<Tz> { pub fn and_hms_nano(&self, hour: u32, min: u32, sec: u32, nano: u32) -> DateTime<Tz> {
self.and_hms_nano_opt(hour, min, sec, nano).expect("invalid time") self.and_hms_nano_opt(hour, min, sec, nano).expect("invalid time")
@ -136,7 +136,7 @@ impl<Tz: TimeZone> Date<Tz> {
/// Makes a new `Date` for the next 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] #[inline]
pub fn succ(&self) -> Date<Tz> { pub fn succ(&self) -> Date<Tz> {
self.succ_opt().expect("out of bound") self.succ_opt().expect("out of bound")
@ -152,7 +152,7 @@ impl<Tz: TimeZone> Date<Tz> {
/// Makes a new `Date` for the prior 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] #[inline]
pub fn pred(&self) -> Date<Tz> { pub fn pred(&self) -> Date<Tz> {
self.pred_opt().expect("out of bound") self.pred_opt().expect("out of bound")

View File

@ -89,7 +89,7 @@ impl NaiveDate {
/// Makes a new `NaiveDate` from year, month and day. /// Makes a new `NaiveDate` from year, month and day.
/// This assumes the proleptic Gregorian calendar, with the year 0 being 1 BCE. /// 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 /// # Example
/// ///
@ -134,7 +134,7 @@ impl NaiveDate {
/// Makes a new `NaiveDate` from year and day of year (DOY or "ordinal"). /// 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. /// 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 /// # Example
/// ///
@ -181,7 +181,7 @@ impl NaiveDate {
/// This assumes the proleptic Gregorian calendar, with the year 0 being 1 BCE. /// 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. /// 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 /// # Example
/// ///
@ -269,7 +269,7 @@ impl NaiveDate {
/// Makes a new `NaiveDate` from the number of days since January 1, 1 (Day 1) /// Makes a new `NaiveDate` from the number of days since January 1, 1 (Day 1)
/// in the proleptic Gregorian calendar. /// in the proleptic Gregorian calendar.
/// ///
/// Fails on the out-of-range date. /// Panics on the out-of-range date.
/// ///
/// # Example /// # Example
/// ///
@ -329,16 +329,28 @@ impl NaiveDate {
/// Ok(NaiveDate::from_ymd(2015, 9, 5))); /// Ok(NaiveDate::from_ymd(2015, 9, 5)));
/// assert_eq!(NaiveDate::parse_from_str("5sep2015", "%d%b%Y"), /// assert_eq!(NaiveDate::parse_from_str("5sep2015", "%d%b%Y"),
/// Ok(NaiveDate::from_ymd(2015, 9, 5))); /// 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"), /// 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))); /// 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", "%Y/%m").is_err());
/// assert!(NaiveDate::parse_from_str("2015/9/31", "%Y/%m/%d").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()); /// 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<NaiveDate> { pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveDate> {
@ -368,7 +380,10 @@ impl NaiveDate {
/// Makes a new `NaiveDateTime` from the current date, hour, minute and second. /// 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 /// # Example
/// ///
@ -389,6 +404,9 @@ impl NaiveDate {
/// Makes a new `NaiveDateTime` from the current date, hour, minute and second. /// 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. /// Returns `None` on invalid hour, minute and/or second.
/// ///
/// # Example /// # Example
@ -408,9 +426,11 @@ impl NaiveDate {
} }
/// Makes a new `NaiveDateTime` from the current date, hour, minute, second and millisecond. /// 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 /// # Example
/// ///
@ -431,7 +451,9 @@ impl NaiveDate {
} }
/// Makes a new `NaiveDateTime` from the current date, hour, minute, second and millisecond. /// 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. /// 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. /// 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 /// # Example
/// ///
@ -478,7 +502,9 @@ impl NaiveDate {
} }
/// Makes a new `NaiveDateTime` from the current date, hour, minute, second and microsecond. /// 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. /// 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. /// 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 /// # Example
/// ///
@ -525,7 +553,9 @@ impl NaiveDate {
} }
/// Makes a new `NaiveDateTime` from the current date, hour, minute, second and nanosecond. /// 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. /// Returns `None` on invalid hour, minute, second and/or nanosecond.
/// ///
@ -583,7 +613,7 @@ impl NaiveDate {
/// Makes a new `NaiveDate` for the next date. /// 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 /// # Example
/// ///
@ -620,7 +650,7 @@ impl NaiveDate {
/// Makes a new `NaiveDate` for the prior date. /// 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 /// # Example
/// ///
@ -748,7 +778,7 @@ impl NaiveDate {
/// which gets converted to a string only when actual formatting happens. /// which gets converted to a string only when actual formatting happens.
/// You may use the `to_string` method to get a `String`, /// You may use the `to_string` method to get a `String`,
/// or just feed it into `print!` and other formatting macros. /// 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. /// A wrong format string does *not* issue an error immediately.
/// Rather, converting or formatting the `DelayedFormat` fails. /// 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, /// An addition of `Duration` to `NaiveDate` discards the fractional days,
/// rounding to the closest integral number of days towards `Duration::zero()`. /// 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. /// Use `NaiveDate::checked_add` for detecting that.
/// ///
/// # Example /// # Example
@ -907,7 +937,7 @@ impl Sub<NaiveDate> for NaiveDate {
/// A subtraction of `Duration` from `NaiveDate` discards the fractional days, /// A subtraction of `Duration` from `NaiveDate` discards the fractional days,
/// rounding to the closest integral number of days towards `Duration::zero()`. /// 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. /// Use `NaiveDate::checked_sub` for detecting that.
/// ///
/// # Example /// # Example

View File

@ -38,7 +38,7 @@ impl NaiveDateTime {
/// since January 1, 1970 0:00:00 UTC (aka "UNIX timestamp") /// since January 1, 1970 0:00:00 UTC (aka "UNIX timestamp")
/// and the number of nanoseconds since the last whole non-leap second. /// 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] #[inline]
pub fn from_timestamp(secs: i64, nsecs: u32) -> NaiveDateTime { pub fn from_timestamp(secs: i64, nsecs: u32) -> NaiveDateTime {
let datetime = NaiveDateTime::from_timestamp_opt(secs, nsecs); let datetime = NaiveDateTime::from_timestamp_opt(secs, nsecs);

View File

@ -17,6 +17,44 @@ use format::{parse, Parsed, ParseError, ParseResult, DelayedFormat, StrftimeItem
/// ISO 8601 time without timezone. /// ISO 8601 time without timezone.
/// Allows for the nanosecond precision and optional leap second representation. /// 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)] #[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
#[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))] #[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))]
pub struct NaiveTime { pub struct NaiveTime {
@ -27,7 +65,22 @@ pub struct NaiveTime {
impl NaiveTime { impl NaiveTime {
/// Makes a new `NaiveTime` from hour, minute and second. /// 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] #[inline]
pub fn from_hms(hour: u32, min: u32, sec: u32) -> NaiveTime { pub fn from_hms(hour: u32, min: u32, sec: u32) -> NaiveTime {
NaiveTime::from_hms_opt(hour, min, sec).expect("invalid time") 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. /// 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. /// 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] #[inline]
pub fn from_hms_opt(hour: u32, min: u32, sec: u32) -> Option<NaiveTime> { pub fn from_hms_opt(hour: u32, min: u32, sec: u32) -> Option<NaiveTime> {
NaiveTime::from_hms_nano_opt(hour, min, sec, 0) NaiveTime::from_hms_nano_opt(hour, min, sec, 0)
} }
/// Makes a new `NaiveTime` from hour, minute, second and millisecond. /// 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] #[inline]
pub fn from_hms_milli(hour: u32, min: u32, sec: u32, milli: u32) -> NaiveTime { 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") NaiveTime::from_hms_milli_opt(hour, min, sec, milli).expect("invalid time")
} }
/// Makes a new `NaiveTime` from hour, minute, second and millisecond. /// 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. /// 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] #[inline]
pub fn from_hms_milli_opt(hour: u32, min: u32, sec: u32, milli: u32) -> Option<NaiveTime> { pub fn from_hms_milli_opt(hour: u32, min: u32, sec: u32, milli: u32) -> Option<NaiveTime> {
milli.checked_mul(1_000_000) milli.checked_mul(1_000_000)
@ -61,18 +161,49 @@ impl NaiveTime {
} }
/// Makes a new `NaiveTime` from hour, minute, second and microsecond. /// 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] #[inline]
pub fn from_hms_micro(hour: u32, min: u32, sec: u32, micro: u32) -> NaiveTime { 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") NaiveTime::from_hms_micro_opt(hour, min, sec, micro).expect("invalid time")
} }
/// Makes a new `NaiveTime` from hour, minute, second and microsecond. /// 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. /// 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] #[inline]
pub fn from_hms_micro_opt(hour: u32, min: u32, sec: u32, micro: u32) -> Option<NaiveTime> { pub fn from_hms_micro_opt(hour: u32, min: u32, sec: u32, micro: u32) -> Option<NaiveTime> {
micro.checked_mul(1_000) micro.checked_mul(1_000)
@ -80,18 +211,49 @@ impl NaiveTime {
} }
/// Makes a new `NaiveTime` from hour, minute, second and nanosecond. /// 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] #[inline]
pub fn from_hms_nano(hour: u32, min: u32, sec: u32, nano: u32) -> NaiveTime { 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") NaiveTime::from_hms_nano_opt(hour, min, sec, nano).expect("invalid time")
} }
/// Makes a new `NaiveTime` from hour, minute, second and nanosecond. /// 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. /// 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] #[inline]
pub fn from_hms_nano_opt(hour: u32, min: u32, sec: u32, nano: u32) -> Option<NaiveTime> { pub fn from_hms_nano_opt(hour: u32, min: u32, sec: u32, nano: u32) -> Option<NaiveTime> {
if hour >= 24 || min >= 60 || sec >= 60 || nano >= 2_000_000_000 { return None; } 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. /// 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] #[inline]
pub fn from_num_seconds_from_midnight(secs: u32, nano: u32) -> NaiveTime { pub fn from_num_seconds_from_midnight(secs: u32, nano: u32) -> NaiveTime {
NaiveTime::from_num_seconds_from_midnight_opt(secs, nano).expect("invalid time") 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. /// 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. /// 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] #[inline]
pub fn from_num_seconds_from_midnight_opt(secs: u32, nano: u32) -> Option<NaiveTime> { pub fn from_num_seconds_from_midnight_opt(secs: u32, nano: u32) -> Option<NaiveTime> {
if secs >= 86400 || nano >= 2_000_000_000 { return None; } 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`. /// Parses a string with the specified format string and returns a new `NaiveTime`.
/// See the [`format::strftime` module](../../format/strftime/index.html) /// See the [`format::strftime` module](../../format/strftime/index.html)
/// on the supported escape sequences. /// 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<NaiveTime> { pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveTime> {
let mut parsed = Parsed::new(); let mut parsed = Parsed::new();
try!(parse(&mut parsed, s, StrftimeItems::new(fmt))); try!(parse(&mut parsed, s, StrftimeItems::new(fmt)));
@ -128,6 +371,22 @@ impl NaiveTime {
} }
/// Formats the time with the specified formatting items. /// 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] #[inline]
pub fn format_with_items<'a, I>(&self, items: I) -> DelayedFormat<I> pub fn format_with_items<'a, I>(&self, items: I) -> DelayedFormat<I>
where I: Iterator<Item=Item<'a>> + Clone { where I: Iterator<Item=Item<'a>> + Clone {
@ -137,6 +396,27 @@ impl NaiveTime {
/// Formats the time with the specified format string. /// Formats the time with the specified format string.
/// See the [`format::strftime` module](../../format/strftime/index.html) /// See the [`format::strftime` module](../../format/strftime/index.html)
/// on the supported escape sequences. /// 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] #[inline]
pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>> { pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>> {
self.format_with_items(StrftimeItems::new(fmt)) self.format_with_items(StrftimeItems::new(fmt))

View File

@ -25,7 +25,7 @@ impl FixedOffset {
/// Makes a new `FixedOffset` for the Eastern Hemisphere with given timezone difference. /// Makes a new `FixedOffset` for the Eastern Hemisphere with given timezone difference.
/// The negative `secs` means the Western Hemisphere. /// 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 { pub fn east(secs: i32) -> FixedOffset {
FixedOffset::east_opt(secs).expect("FixedOffset::east out of bounds") 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. /// Makes a new `FixedOffset` for the Western Hemisphere with given timezone difference.
/// The negative `secs` means the Eastern Hemisphere. /// 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 { pub fn west(secs: i32) -> FixedOffset {
FixedOffset::west_opt(secs).expect("FixedOffset::west out of bounds") FixedOffset::west_opt(secs).expect("FixedOffset::west out of bounds")
} }

View File

@ -145,7 +145,7 @@ impl<Tz: TimeZone> LocalResult<Date<Tz>> {
} }
impl<T: fmt::Debug> LocalResult<T> { impl<T: fmt::Debug> LocalResult<T> {
/// Returns the single unique conversion result, or fails accordingly. /// Returns the single unique conversion result, or panics accordingly.
pub fn unwrap(self) -> T { pub fn unwrap(self) -> T {
match self { match self {
LocalResult::None => panic!("No such local time"), 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), /// 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. /// 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> { fn ymd(&self, year: i32, month: u32, day: u32) -> Date<Self> {
self.ymd_opt(year, month, day).unwrap() 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), /// 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. /// 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> { fn yo(&self, year: i32, ordinal: u32) -> Date<Self> {
self.yo_opt(year, ordinal).unwrap() 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), /// 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. /// 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> { fn isoywd(&self, year: i32, week: u32, weekday: Weekday) -> Date<Self> {
self.isoywd_opt(year, week, weekday).unwrap() 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") /// since January 1, 1970 0:00:00 UTC (aka "UNIX timestamp")
/// and the number of nanoseconds since the last whole non-leap second. /// 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> { fn timestamp(&self, secs: i64, nsecs: u32) -> DateTime<Self> {
self.timestamp_opt(secs, nsecs).unwrap() self.timestamp_opt(secs, nsecs).unwrap()
} }