Incremental doc updates for `NaiveDateTime`.
Also moved the leap second arithmetic examples to `chrono::naive::time`, as it became hard to link from other pages.
This commit is contained in:
parent
0393cae36d
commit
8b382fca45
|
@ -17,6 +17,30 @@ use format::{Item, Numeric, Pad, Fixed};
|
||||||
use format::{parse, Parsed, ParseError, ParseResult, DelayedFormat, StrftimeItems};
|
use format::{parse, Parsed, ParseError, ParseResult, DelayedFormat, StrftimeItems};
|
||||||
|
|
||||||
/// ISO 8601 combined date and time without timezone.
|
/// ISO 8601 combined date and time without timezone.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// `NaiveDateTime` is commonly created from [`NaiveDate`](../date/struct.NaiveDate.html).
|
||||||
|
///
|
||||||
|
/// ~~~~
|
||||||
|
/// use chrono::{NaiveDate, NaiveDateTime};
|
||||||
|
///
|
||||||
|
/// let dt: NaiveDateTime = NaiveDate::from_ymd(2016, 7, 8).and_hms(9, 10, 11);
|
||||||
|
/// # let _ = dt;
|
||||||
|
/// ~~~~
|
||||||
|
///
|
||||||
|
/// You can use typical [date-like](../../trait.Datelike.html) and
|
||||||
|
/// [time-like](../../trait.Timelike.html) methods,
|
||||||
|
/// provided that relevant traits are in the scope.
|
||||||
|
///
|
||||||
|
/// ~~~~
|
||||||
|
/// # use chrono::{NaiveDate, NaiveDateTime};
|
||||||
|
/// # let dt: NaiveDateTime = NaiveDate::from_ymd(2016, 7, 8).and_hms(9, 10, 11);
|
||||||
|
/// use chrono::{Datelike, Timelike, Weekday};
|
||||||
|
///
|
||||||
|
/// assert_eq!(dt.weekday(), Weekday::Fri);
|
||||||
|
/// assert_eq!(dt.num_seconds_from_midnight(), 33011);
|
||||||
|
/// ~~~~
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
|
||||||
pub struct NaiveDateTime {
|
pub struct NaiveDateTime {
|
||||||
date: NaiveDate,
|
date: NaiveDate,
|
||||||
|
@ -190,12 +214,30 @@ impl NaiveDateTime {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves a date component.
|
/// Retrieves a date component.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ~~~~
|
||||||
|
/// use chrono::NaiveDate;
|
||||||
|
///
|
||||||
|
/// let dt = NaiveDate::from_ymd(2016, 7, 8).and_hms(9, 10, 11);
|
||||||
|
/// assert_eq!(dt.date(), NaiveDate::from_ymd(2016, 7, 8));
|
||||||
|
/// ~~~~
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn date(&self) -> NaiveDate {
|
pub fn date(&self) -> NaiveDate {
|
||||||
self.date
|
self.date
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves a time component.
|
/// Retrieves a time component.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ~~~~
|
||||||
|
/// use chrono::{NaiveDate, NaiveTime};
|
||||||
|
///
|
||||||
|
/// let dt = NaiveDate::from_ymd(2016, 7, 8).and_hms(9, 10, 11);
|
||||||
|
/// assert_eq!(dt.time(), NaiveTime::from_hms(9, 10, 11));
|
||||||
|
/// ~~~~
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn time(&self) -> NaiveTime {
|
pub fn time(&self) -> NaiveTime {
|
||||||
self.time
|
self.time
|
||||||
|
@ -205,6 +247,18 @@ impl NaiveDateTime {
|
||||||
///
|
///
|
||||||
/// Note that this does *not* account for the timezone!
|
/// Note that this does *not* account for the timezone!
|
||||||
/// The true "UNIX timestamp" would count seconds since the midnight *UTC* on the epoch.
|
/// The true "UNIX timestamp" would count seconds since the midnight *UTC* on the epoch.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ~~~~
|
||||||
|
/// use chrono::NaiveDate;
|
||||||
|
///
|
||||||
|
/// let dt = NaiveDate::from_ymd(1970, 1, 1).and_hms_milli(0, 0, 1, 980);
|
||||||
|
/// assert_eq!(dt.timestamp(), 1);
|
||||||
|
///
|
||||||
|
/// let dt = NaiveDate::from_ymd(2001, 9, 9).and_hms(1, 46, 40);
|
||||||
|
/// assert_eq!(dt.timestamp(), 1_000_000_000);
|
||||||
|
/// ~~~~
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn timestamp(&self) -> i64 {
|
pub fn timestamp(&self) -> i64 {
|
||||||
let ndays = self.date.num_days_from_ce() as i64;
|
let ndays = self.date.num_days_from_ce() as i64;
|
||||||
|
@ -216,6 +270,18 @@ impl NaiveDateTime {
|
||||||
///
|
///
|
||||||
/// The return value ranges from 0 to 999,
|
/// The return value ranges from 0 to 999,
|
||||||
/// or for [leap seconds](../time/index.html#leap-second-handling), to 1,999.
|
/// or for [leap seconds](../time/index.html#leap-second-handling), to 1,999.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ~~~~
|
||||||
|
/// use chrono::NaiveDate;
|
||||||
|
///
|
||||||
|
/// let dt = NaiveDate::from_ymd(2016, 7, 8).and_hms_nano(9, 10, 11, 123_456_789);
|
||||||
|
/// assert_eq!(dt.timestamp_subsec_millis(), 123);
|
||||||
|
///
|
||||||
|
/// let dt = NaiveDate::from_ymd(2015, 7, 1).and_hms_nano(8, 59, 59, 1_234_567_890);
|
||||||
|
/// assert_eq!(dt.timestamp_subsec_millis(), 1_234);
|
||||||
|
/// ~~~~
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn timestamp_subsec_millis(&self) -> u32 {
|
pub fn timestamp_subsec_millis(&self) -> u32 {
|
||||||
self.timestamp_subsec_nanos() / 1_000_000
|
self.timestamp_subsec_nanos() / 1_000_000
|
||||||
|
@ -225,6 +291,18 @@ impl NaiveDateTime {
|
||||||
///
|
///
|
||||||
/// The return value ranges from 0 to 999,999,
|
/// The return value ranges from 0 to 999,999,
|
||||||
/// or for [leap seconds](../time/index.html#leap-second-handling), to 1,999,999.
|
/// or for [leap seconds](../time/index.html#leap-second-handling), to 1,999,999.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ~~~~
|
||||||
|
/// use chrono::NaiveDate;
|
||||||
|
///
|
||||||
|
/// let dt = NaiveDate::from_ymd(2016, 7, 8).and_hms_nano(9, 10, 11, 123_456_789);
|
||||||
|
/// assert_eq!(dt.timestamp_subsec_micros(), 123_456);
|
||||||
|
///
|
||||||
|
/// let dt = NaiveDate::from_ymd(2015, 7, 1).and_hms_nano(8, 59, 59, 1_234_567_890);
|
||||||
|
/// assert_eq!(dt.timestamp_subsec_micros(), 1_234_567);
|
||||||
|
/// ~~~~
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn timestamp_subsec_micros(&self) -> u32 {
|
pub fn timestamp_subsec_micros(&self) -> u32 {
|
||||||
self.timestamp_subsec_nanos() / 1_000
|
self.timestamp_subsec_nanos() / 1_000
|
||||||
|
@ -234,6 +312,18 @@ impl NaiveDateTime {
|
||||||
///
|
///
|
||||||
/// The return value ranges from 0 to 999,999,999,
|
/// The return value ranges from 0 to 999,999,999,
|
||||||
/// or for [leap seconds](../time/index.html#leap-second-handling), to 1,999,999,999.
|
/// or for [leap seconds](../time/index.html#leap-second-handling), to 1,999,999,999.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ~~~~
|
||||||
|
/// use chrono::NaiveDate;
|
||||||
|
///
|
||||||
|
/// let dt = NaiveDate::from_ymd(2016, 7, 8).and_hms_nano(9, 10, 11, 123_456_789);
|
||||||
|
/// assert_eq!(dt.timestamp_subsec_nanos(), 123_456_789);
|
||||||
|
///
|
||||||
|
/// let dt = NaiveDate::from_ymd(2015, 7, 1).and_hms_nano(8, 59, 59, 1_234_567_890);
|
||||||
|
/// assert_eq!(dt.timestamp_subsec_nanos(), 1_234_567_890);
|
||||||
|
/// ~~~~
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn timestamp_subsec_nanos(&self) -> u32 {
|
pub fn timestamp_subsec_nanos(&self) -> u32 {
|
||||||
self.time.nanosecond()
|
self.time.nanosecond()
|
||||||
|
|
|
@ -29,18 +29,115 @@
|
||||||
//!
|
//!
|
||||||
//! Chrono does not try to accurately implement leap seconds; it is impossible.
|
//! 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.**
|
//! 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)
|
//! Various operations will ignore any possible leap second(s)
|
||||||
//! except when the operand were actually a leap second.
|
//! except when any of the operands were actually leap seconds.
|
||||||
//! 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,
|
//! If you cannot tolerate this behavior,
|
||||||
//! you must use a separate `TimeZone` for the International Atomic Time (TAI).
|
//! 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.
|
//! 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.
|
//! Chrono 0.2 does not provide such implementation, but it is planned for 0.3.
|
||||||
|
//!
|
||||||
|
//! ## Representing Leap Seconds
|
||||||
|
//!
|
||||||
|
//! The leap second is indicated via fractional seconds more than 1 second.
|
||||||
|
//! This makes possible to treat a leap second as the prior non-leap second
|
||||||
|
//! if you don't care about sub-second accuracy.
|
||||||
|
//! You should use the proper formatting to get the raw leap second.
|
||||||
|
//!
|
||||||
|
//! All methods accepting fractional seconds will accept such values.
|
||||||
|
//!
|
||||||
|
//! ~~~~
|
||||||
|
//! use chrono::{NaiveDate, NaiveTime, UTC, TimeZone};
|
||||||
|
//!
|
||||||
|
//! let t = NaiveTime::from_hms_milli(8, 59, 59, 1_000);
|
||||||
|
//!
|
||||||
|
//! let dt1 = NaiveDate::from_ymd(2015, 7, 1).and_hms_micro(8, 59, 59, 1_000_000);
|
||||||
|
//!
|
||||||
|
//! let dt2 = UTC.ymd(2015, 6, 30).and_hms_nano(23, 59, 59, 1_000_000_000);
|
||||||
|
//! # let _ = (t, dt1, dt2);
|
||||||
|
//! ~~~~
|
||||||
|
//!
|
||||||
|
//! Note that the leap second can happen anytime given an appropriate time zone;
|
||||||
|
//! 2015-07-01 01:23:60 would be a proper leap second if UTC+01:24 had existed.
|
||||||
|
//! Practically speaking, though, by the time of the first leap second on 1972-06-30,
|
||||||
|
//! every time zone offset around the world has standardized to the 5-minute alignment.
|
||||||
|
//!
|
||||||
|
//! ## Date And Time Arithmetics
|
||||||
|
//!
|
||||||
|
//! As a concrete example, let's assume that `03:00:60` and `04:00:60` are leap seconds.
|
||||||
|
//! (In reality, of course, leap seconds are separated by at least 6 months.)
|
||||||
|
//!
|
||||||
|
//! `Time + Duration`:
|
||||||
|
//!
|
||||||
|
//! - `03:00:00 + 1s = 03:00:01`.
|
||||||
|
//! - `03:00:59 + 60s = 03:02:00`.
|
||||||
|
//! - `03:00:59 + 1s = 03:01:00`.
|
||||||
|
//! - `03:00:60 + 1s = 03:01:00`.
|
||||||
|
//! Note that the sum is identical to the previous.
|
||||||
|
//! - `03:00:60 + 60s = 03:01:59`.
|
||||||
|
//! - `03:00:60 + 61s = 03:02:00`.
|
||||||
|
//! - `03:00:60.1 + 0.8s = 03:00:60.9`.
|
||||||
|
//!
|
||||||
|
//! `Time - Duration`:
|
||||||
|
//!
|
||||||
|
//! - `03:00:00 - 1s = 02:59:59`.
|
||||||
|
//! - `03:01:00 - 1s = 03:00:59`.
|
||||||
|
//! - `03:01:00 - 60s = 03:00:00`.
|
||||||
|
//! - `03:00:60 - 60s = 03:00:00`.
|
||||||
|
//! Note that the result is identical to the previous.
|
||||||
|
//! - `03:00:60.7 - 0.4s = 03:00:60.3`.
|
||||||
|
//! - `03:00:60.7 - 0.9s = 03:00:59.8`.
|
||||||
|
//!
|
||||||
|
//! `Time - Time`:
|
||||||
|
//!
|
||||||
|
//! - `04:00:00 - 03:00:00 = 3600s`.
|
||||||
|
//! - `03:01:00 - 03:00:00 = 60s`.
|
||||||
|
//! - `03:00:60 - 03:00:00 = 60s`.
|
||||||
|
//! Note that the difference is identical to the previous.
|
||||||
|
//! - `03:00:60.6 - 03:00:59.4 = 1.2s`.
|
||||||
|
//! - `03:01:00 - 03:00:59.8 = 0.2s`.
|
||||||
|
//! - `03:01:00 - 03:00:60.5 = 0.5s`.
|
||||||
|
//! Note that the difference is larger than the previous,
|
||||||
|
//! even though the leap second clearly follows the previous whole second.
|
||||||
|
//! - `04:00:60.9 - 03:00:60.1 =
|
||||||
|
//! (04:00:60.9 - 04:00:00) + (04:00:00 - 03:01:00) + (03:01:00 - 03:00:60.1) =
|
||||||
|
//! 60.9s + 3540s + 0.9s = 3601.8s`.
|
||||||
|
//!
|
||||||
|
//! In general,
|
||||||
|
//!
|
||||||
|
//! - `Time + Duration` unconditionally equals to `Duration + Time`.
|
||||||
|
//!
|
||||||
|
//! - `Time - Duration` unconditionally equals to `Time + (-Duration)`.
|
||||||
|
//!
|
||||||
|
//! - `Time1 - Time2` unconditionally equals to `-(Time2 - Time1)`.
|
||||||
|
//!
|
||||||
|
//! - Associativity does not generally hold, because
|
||||||
|
//! `(Time + Duration1) - Duration2` no longer equals to `Time + (Duration1 - Duration2)`
|
||||||
|
//! for two positive durations.
|
||||||
|
//!
|
||||||
|
//! - As a special case, `(Time + Duration) - Duration` also does not equal to `Time`.
|
||||||
|
//!
|
||||||
|
//! - If you can assume that all durations have the same sign, however,
|
||||||
|
//! then the associativity holds:
|
||||||
|
//! `(Time + Duration1) + Duration2` equals to `Time + (Duration1 + Duration2)`
|
||||||
|
//! for two positive durations.
|
||||||
|
//!
|
||||||
|
//! ## Reading And Writing Leap Seconds
|
||||||
|
//!
|
||||||
|
//! The "typical" leap seconds on the minute boundary are
|
||||||
|
//! correctly handled both in the formatting and parsing.
|
||||||
|
//! The leap second in the human-readable representation
|
||||||
|
//! will be represented as the second part being 60, as required by ISO 8601.
|
||||||
|
//!
|
||||||
|
//! There are hypothetical leap seconds not on the minute boundary
|
||||||
|
//! nevertheless supported by Chrono.
|
||||||
|
//! They are allowed for the sake of completeness and consistency;
|
||||||
|
//! there were several "exotic" time zone offsets with fractional minutes prior to UTC after all.
|
||||||
|
//! For such cases the human-readable representation is ambiguous
|
||||||
|
//! and would be read back to the next non-leap second.
|
||||||
|
//!
|
||||||
|
//! Since Chrono alone cannot determine any existence of leap seconds,
|
||||||
|
//! **there is absolutely no guarantee that the leap second read has actually happened**.
|
||||||
|
|
||||||
use std::{str, fmt, hash};
|
use std::{str, fmt, hash};
|
||||||
use std::ops::{Add, Sub};
|
use std::ops::{Add, Sub};
|
||||||
|
@ -700,19 +797,6 @@ impl hash::Hash for NaiveTime {
|
||||||
/// except when the `NaiveTime` itself represents a leap second
|
/// except when the `NaiveTime` itself represents a leap second
|
||||||
/// in which case the assumption becomes that **there is exactly a single leap second ever**.
|
/// in which case the assumption becomes that **there is exactly a single leap second ever**.
|
||||||
///
|
///
|
||||||
/// Therefore, assuming that `03:00:60` is a leap second:
|
|
||||||
///
|
|
||||||
/// - `03:00:00 + 1s = 03:00:01`.
|
|
||||||
/// - `03:00:59 + 1s = 03:01:00`.
|
|
||||||
/// - `03:00:59 + 60s = 03:02:00`.
|
|
||||||
/// - `03:00:60 + 1s = 03:01:00`.
|
|
||||||
/// Note that the sum is identical to the previous; the associativity would no longer hold.
|
|
||||||
/// - `03:00:60 + 60s = 03:01:59`.
|
|
||||||
/// - `03:00:60 + 61s = 03:02:00`.
|
|
||||||
/// - `03:00:60.1 + 0.8s = 03:00:60.9`.
|
|
||||||
///
|
|
||||||
/// It can be thought that the clock *forgets* a leap second once it ticked any direction.
|
|
||||||
///
|
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ~~~~
|
/// ~~~~
|
||||||
|
@ -828,23 +912,6 @@ impl Add<Duration> for NaiveTime {
|
||||||
/// in which case the assumption becomes that
|
/// in which case the assumption becomes that
|
||||||
/// **there are exactly one (or two) leap second(s) ever**.
|
/// **there are exactly one (or two) leap second(s) ever**.
|
||||||
///
|
///
|
||||||
/// Therefore, assuming that `03:00:60` and `04:00:60` are leap seconds:
|
|
||||||
///
|
|
||||||
/// - `04:00:00 - 03:00:00 = 3600s`.
|
|
||||||
/// - `03:01:00 - 03:00:00 = 60s`.
|
|
||||||
/// - `03:00:60 - 03:00:00 = 60s`.
|
|
||||||
/// Note that the difference is identical to the previous.
|
|
||||||
/// - `03:00:60.6 - 03:00:59.4 = 1.2s`.
|
|
||||||
/// - `03:01:00 - 03:00:59.8 = 0.2s`.
|
|
||||||
/// - `03:01:00 - 03:00:60.5 = 0.5s`.
|
|
||||||
/// Note that the difference is larger than the previous,
|
|
||||||
/// even though the leap second clearly follows the previous whole second.
|
|
||||||
/// - `04:00:60.9 - 03:00:60.1 =
|
|
||||||
/// (04:00:60.9 - 04:00:00) + (04:00:00 - 03:01:00) + (03:01:00 - 03:00:60.1) =
|
|
||||||
/// 60.9s + 3540s + 0.9s = 3601.8s`.
|
|
||||||
///
|
|
||||||
/// Note that `a - b` and `-(b - a)` are still same even under this principle.
|
|
||||||
///
|
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ~~~~
|
/// ~~~~
|
||||||
|
@ -914,16 +981,6 @@ impl Sub<NaiveTime> for NaiveTime {
|
||||||
/// except when the `NaiveTime` itself represents a leap second
|
/// except when the `NaiveTime` itself represents a leap second
|
||||||
/// in which case the assumption becomes that **there is exactly a single leap second ever**.
|
/// in which case the assumption becomes that **there is exactly a single leap second ever**.
|
||||||
///
|
///
|
||||||
/// Therefore, assuming that `03:00:60` is a leap second:
|
|
||||||
///
|
|
||||||
/// - `03:00:00 - 1s = 02:59:59`.
|
|
||||||
/// - `03:01:00 - 1s = 03:00:59`.
|
|
||||||
/// - `03:01:00 - 60s = 03:00:00`.
|
|
||||||
/// - `03:00:60 - 60s = 03:00:00`.
|
|
||||||
/// Note that the result is identical to the previous; the associativity would no longer hold.
|
|
||||||
/// - `03:00:60.7 - 0.4s = 03:00:60.3`.
|
|
||||||
/// - `03:00:60.7 - 0.9s = 03:00:59.8`.
|
|
||||||
///
|
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ~~~~
|
/// ~~~~
|
||||||
|
|
Loading…
Reference in New Issue