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.
This commit is contained in:
Brandon W Maister 2016-11-12 16:09:08 -05:00
parent 2dea325524
commit a4c1cc6ed2
6 changed files with 118 additions and 4 deletions

View File

@ -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<Tz: TimeZone> {
datetime: NaiveDateTime,
@ -32,6 +36,15 @@ pub struct DateTime<Tz: TimeZone> {
impl<Tz: TimeZone> DateTime<Tz> {
/// 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::<UTC>::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]

View File

@ -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.
///

View File

@ -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<FixedOffset>` 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")
}

View File

@ -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<Local>`
/// instances.
///
/// # Example
///
/// ~~~~
/// use chrono::{Local, DateTime, TimeZone};
///
/// let dt: DateTime<Local> = Local::now();
/// let dt: DateTime<Local> = Local.timestamp(0, 0);
/// ~~~~
#[derive(Copy, Clone)]
#[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))]
pub struct Local;

View File

@ -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<Tz>`
* 2. Converting the UTC `NaiveDateTime` to `DateTime<Tz>`
* 3. Converting `DateTime<Tz>` to the local `NaiveDateTime`
* 4. Constructing `DateTime<Tz>` 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> {
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<Date<Self>> {
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> {
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> {
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> {
self.timestamp_opt(secs, nsecs).unwrap()
}

View File

@ -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<UTC>`
/// instances.
///
/// # Example
///
/// ~~~~
/// use chrono::{DateTime, TimeZone, NaiveDateTime, UTC};
///
/// let dt = DateTime::<UTC>::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;