From a4c1cc6ed21e5fc67725064d452c03ae8c265216 Mon Sep 17 00:00:00 2001 From: Brandon W Maister Date: Sat, 12 Nov 2016 16:09:08 -0500 Subject: [PATCH] Improve docs around constructing DateTime objects This provides examples for most of the constructor-like methods on `TimeZone`, examples on the various `Offset` impls, and links `NaiveDateTime` to `TimeZone` so that it's more obvious how you're supposed to do things. This is related to #88, which is something that I ran into when I started using rust-chrono. --- src/datetime.rs | 13 ++++++++++++ src/naive/datetime.rs | 9 ++++++--- src/offset/fixed.rs | 25 +++++++++++++++++++++++ src/offset/local.rs | 13 ++++++++++++ src/offset/mod.rs | 47 ++++++++++++++++++++++++++++++++++++++++++- src/offset/utc.rs | 15 ++++++++++++++ 6 files changed, 118 insertions(+), 4 deletions(-) diff --git a/src/datetime.rs b/src/datetime.rs index c0a5a19..55b69fd 100644 --- a/src/datetime.rs +++ b/src/datetime.rs @@ -23,6 +23,10 @@ use format::{Item, Numeric, Pad, Fixed}; use format::{parse, Parsed, ParseError, ParseResult, DelayedFormat, StrftimeItems}; /// ISO 8601 combined date and time with time zone. +/// +/// There are some constructors implemented here (the `from_*` methods), but +/// the general-purpose constructors are all via the methods on the +/// [`TimeZone`](../trait.TimeZone.html) implementations. #[derive(Clone)] pub struct DateTime { datetime: NaiveDateTime, @@ -32,6 +36,15 @@ pub struct DateTime { impl DateTime { /// Makes a new `DateTime` with given *UTC* datetime and offset. /// The local datetime should be constructed via the `TimeZone` trait. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::{DateTime, TimeZone, NaiveDateTime, UTC}; + /// + /// let dt = DateTime::::from_utc(NaiveDateTime::from_timestamp(61, 0), UTC); + /// assert_eq!(UTC.timestamp(61, 0), dt); + /// ~~~~ // // note: this constructor is purposedly not named to `new` to discourage the direct usage. #[inline] diff --git a/src/naive/datetime.rs b/src/naive/datetime.rs index c611f40..2beadee 100644 --- a/src/naive/datetime.rs +++ b/src/naive/datetime.rs @@ -82,9 +82,12 @@ impl NaiveDateTime { /// since the midnight UTC on January 1, 1970 (aka "UNIX timestamp") /// and the number of nanoseconds since the last whole non-leap second. /// - /// The nanosecond part can exceed 1,000,000,000 - /// in order to represent the [leap second](../time/index.html#leap-second-handling). - /// (The true "UNIX timestamp" cannot represent a leap second unambiguously.) + /// For a non-naive version of this function see + /// [`TimeZone::timestamp`](../../offset/trait.TimeZone.html#method.timestamp). + /// + /// The nanosecond part can exceed 1,000,000,000 in order to represent the + /// [leap second](../time/index.html#leap-second-handling). (The true "UNIX + /// timestamp" cannot represent a leap second unambiguously.) /// /// Panics on the out-of-range number of seconds and/or invalid nanosecond. /// diff --git a/src/offset/fixed.rs b/src/offset/fixed.rs index 7300427..c1a7d6d 100644 --- a/src/offset/fixed.rs +++ b/src/offset/fixed.rs @@ -15,6 +15,11 @@ use naive::datetime::NaiveDateTime; use super::{TimeZone, Offset, LocalResult}; /// The time zone with fixed offset, from UTC-23:59:59 to UTC+23:59:59. +/// +/// Using the [`TimeZone`](../../../chrono/offset/trait.TimeZone.html) methods +/// on a `FixedOffset` struct is the preferred way to construct +/// `DateTime` instances. See the [`east`](#method.east) and +/// [`west`](#method.west) methods for examples. #[derive(Copy, Clone, PartialEq, Eq)] pub struct FixedOffset { local_minus_utc: i32, @@ -42,6 +47,16 @@ impl FixedOffset { /// The negative `secs` means the Western Hemisphere. /// /// Panics on the out-of-bound `secs`. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::{FixedOffset, TimeZone}; + /// let hour = 3600; + /// let datetime = FixedOffset::east(5 * hour).ymd(2016, 11, 08) + /// .and_hms(0, 0, 0); + /// assert_eq!(&datetime.to_rfc3339(), "2016-11-08T00:00:00+05:00") + /// ~~~~ pub fn east(secs: i32) -> FixedOffset { FixedOffset::east_opt(secs).expect("FixedOffset::east out of bounds") } @@ -62,6 +77,16 @@ impl FixedOffset { /// The negative `secs` means the Eastern Hemisphere. /// /// Panics on the out-of-bound `secs`. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::{FixedOffset, TimeZone}; + /// let hour = 3600; + /// let datetime = FixedOffset::west(5 * hour).ymd(2016, 11, 08) + /// .and_hms(0, 0, 0); + /// assert_eq!(&datetime.to_rfc3339(), "2016-11-08T00:00:00-05:00") + /// ~~~~ pub fn west(secs: i32) -> FixedOffset { FixedOffset::west_opt(secs).expect("FixedOffset::west out of bounds") } diff --git a/src/offset/local.rs b/src/offset/local.rs index 594b6c9..2377168 100644 --- a/src/offset/local.rs +++ b/src/offset/local.rs @@ -69,6 +69,19 @@ fn datetime_to_timespec(d: &NaiveDateTime, local: bool) -> stdtime::Timespec { } /// The local timescale. This is implemented via the standard `time` crate. +/// +/// Using the [`TimeZone`](../../../chrono/offset/trait.TimeZone.html) methods +/// on the Local struct is the preferred way to construct `DateTime` +/// instances. +/// +/// # Example +/// +/// ~~~~ +/// use chrono::{Local, DateTime, TimeZone}; +/// +/// let dt: DateTime = Local::now(); +/// let dt: DateTime = Local.timestamp(0, 0); +/// ~~~~ #[derive(Copy, Clone)] #[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))] pub struct Local; diff --git a/src/offset/mod.rs b/src/offset/mod.rs index e0a102d..fdb2432 100644 --- a/src/offset/mod.rs +++ b/src/offset/mod.rs @@ -5,11 +5,12 @@ /*! * The time zone, which calculates offsets from the local time to UTC. * - * There are three operations provided by the `TimeZone` trait: + * There are four operations provided by the `TimeZone` trait: * * 1. Converting the local `NaiveDateTime` to `DateTime` * 2. Converting the UTC `NaiveDateTime` to `DateTime` * 3. Converting `DateTime` to the local `NaiveDateTime` + * 4. Constructing `DateTime` objects from various offsets * * 1 is used for constructors. 2 is used for the `with_timezone` method of date and time types. * 3 is used for other methods, e.g. `year()` or `format()`, and provided by an associated type @@ -178,6 +179,9 @@ pub trait Offset: Sized + Clone + fmt::Debug { } /// The time zone. +/// +/// The methods here are the primarily constructors for [`Date`](../date/struct.Date.html) and +/// [`DateTime`](../datetime/struct.DateTime.html) types. pub trait TimeZone: Sized + Clone { /// An associated offset type. /// This type is used to store the actual offset in date and time types. @@ -191,6 +195,14 @@ pub trait TimeZone: Sized + Clone { /// but it will propagate to the `DateTime` values constructed via this date. /// /// Panics on the out-of-range date, invalid month and/or day. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::{UTC, TimeZone}; + /// + /// assert_eq!(UTC.ymd(2015, 5, 15).to_string(), "2015-05-15UTC"); + /// ~~~~ fn ymd(&self, year: i32, month: u32, day: u32) -> Date { self.ymd_opt(year, month, day).unwrap() } @@ -202,6 +214,15 @@ pub trait TimeZone: Sized + Clone { /// but it will propagate to the `DateTime` values constructed via this date. /// /// Returns `None` on the out-of-range date, invalid month and/or day. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::{UTC, LocalResult, TimeZone}; + /// + /// assert_eq!(UTC.ymd_opt(2015, 5, 15).unwrap().to_string(), "2015-05-15UTC"); + /// assert_eq!(UTC.ymd_opt(2000, 0, 0), LocalResult::None); + /// ~~~~ fn ymd_opt(&self, year: i32, month: u32, day: u32) -> LocalResult> { match NaiveDate::from_ymd_opt(year, month, day) { Some(d) => self.from_local_date(&d), @@ -216,6 +237,14 @@ pub trait TimeZone: Sized + Clone { /// but it will propagate to the `DateTime` values constructed via this date. /// /// Panics on the out-of-range date and/or invalid DOY. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::{UTC, TimeZone}; + /// + /// assert_eq!(UTC.yo(2015, 135).to_string(), "2015-05-15UTC"); + /// ~~~~ fn yo(&self, year: i32, ordinal: u32) -> Date { self.yo_opt(year, ordinal).unwrap() } @@ -243,6 +272,14 @@ pub trait TimeZone: Sized + Clone { /// but it will propagate to the `DateTime` values constructed via this date. /// /// Panics on the out-of-range date and/or invalid week number. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::{UTC, Weekday, TimeZone}; + /// + /// assert_eq!(UTC.isoywd(2015, 20, Weekday::Fri).to_string(), "2015-05-15UTC"); + /// ~~~~ fn isoywd(&self, year: i32, week: u32, weekday: Weekday) -> Date { self.isoywd_opt(year, week, weekday).unwrap() } @@ -268,6 +305,14 @@ pub trait TimeZone: Sized + Clone { /// and the number of nanoseconds since the last whole non-leap second. /// /// Panics on the out-of-range number of seconds and/or invalid nanosecond. + /// + /// # Example + /// + /// ~~~~ + /// use chrono::{UTC, TimeZone}; + /// + /// assert_eq!(UTC.timestamp(1431648000, 0).to_string(), "2015-05-15 00:00:00 UTC"); + /// ~~~~ fn timestamp(&self, secs: i64, nsecs: u32) -> DateTime { self.timestamp_opt(secs, nsecs).unwrap() } diff --git a/src/offset/utc.rs b/src/offset/utc.rs index 0b2fbe8..4071397 100644 --- a/src/offset/utc.rs +++ b/src/offset/utc.rs @@ -18,6 +18,21 @@ use super::{TimeZone, Offset, LocalResult}; /// The UTC time zone. This is the most efficient time zone when you don't need the local time. /// It is also used as an offset (which is also a dummy type). +/// +/// Using the [`TimeZone`](../../../chrono/offset/trait.TimeZone.html) methods +/// on the UTC struct is the preferred way to construct `DateTime` +/// instances. +/// +/// # Example +/// +/// ~~~~ +/// use chrono::{DateTime, TimeZone, NaiveDateTime, UTC}; +/// +/// let dt = DateTime::::from_utc(NaiveDateTime::from_timestamp(61, 0), UTC); +/// +/// assert_eq!(UTC.timestamp(61, 0), dt); +/// assert_eq!(UTC.ymd(1970, 1, 1).and_hms(0, 1, 1), dt); +/// ~~~~ #[derive(Copy, Clone, PartialEq, Eq)] #[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))] pub struct UTC;