mass renaming from offset/state to timezone/offset.

This commit is contained in:
Kang Seonghoon 2015-01-13 02:03:12 +09:00
parent e43cb62f10
commit a4f5d19d24
11 changed files with 284 additions and 283 deletions

View File

@ -38,14 +38,14 @@ Chrono simply reexports it.
Chrono provides a `DateTime` type for the combined date and time. Chrono provides a `DateTime` type for the combined date and time.
`DateTime`, among others, is timezone-aware and `DateTime`, among others, is timezone-aware and
must be constructed from the timezone object (`Offset`). must be constructed from the `TimeZone` object.
`DateTime`s with different offsets do not mix, but can be converted to each other. `DateTime`s with different time zones do not mix, but can be converted to each other.
You can get the current date and time in the UTC timezone (`UTC::now()`) You can get the current date and time in the UTC timezone (`UTC::now()`)
or in the local timezone (`Local::now()`). or in the local timezone (`Local::now()`).
~~~~ {.rust} ~~~~ {.rust}
use chrono::{UTC, Local, DateTime}; use chrono::*;
let utc: DateTime<UTC> = UTC::now(); // e.g. `2014-11-28T12:45:59.324310806Z` let utc: DateTime<UTC> = UTC::now(); // e.g. `2014-11-28T12:45:59.324310806Z`
let local: DateTime<Local> = Local::now(); // e.g. `2014-11-28T21:45:59.324310806+09:00` let local: DateTime<Local> = Local::now(); // e.g. `2014-11-28T21:45:59.324310806+09:00`
@ -56,7 +56,7 @@ This is a bit verbose due to Rust's lack of function and method overloading,
but in turn we get a rich combination of initialization methods. but in turn we get a rich combination of initialization methods.
~~~~ {.rust} ~~~~ {.rust}
use chrono::{UTC, Offset, Weekday, LocalResult}; use chrono::*;
let dt = UTC.ymd(2014, 7, 8).and_hms(9, 10, 11); // `2014-07-08T09:10:11Z` let dt = UTC.ymd(2014, 7, 8).and_hms(9, 10, 11); // `2014-07-08T09:10:11Z`
// July 8 is 188th day of the year 2014 (`o` for "ordinal") // July 8 is 188th day of the year 2014 (`o` for "ordinal")
@ -81,7 +81,7 @@ Addition and subtraction is also supported.
The following illustrates most supported operations to the date and time: The following illustrates most supported operations to the date and time:
~~~~ {.rust} ~~~~ {.rust}
use chrono::{UTC, Local, Datelike, Timelike, Weekday, Duration}; use chrono::*;
// assume this returned `2014-11-28T21:45:59.324310806+09:00`: // assume this returned `2014-11-28T21:45:59.324310806+09:00`:
let dt = Local::now(); let dt = Local::now();
@ -95,9 +95,10 @@ assert_eq!(dt.weekday().number_from_monday(), 5); // Mon=1, ..., Sat=7
assert_eq!(dt.ordinal(), 332); // the day of year assert_eq!(dt.ordinal(), 332); // the day of year
assert_eq!(dt.num_days_from_ce(), 735565); // the number of days from and including Jan 1, 1 assert_eq!(dt.num_days_from_ce(), 735565); // the number of days from and including Jan 1, 1
// offset accessor and manipulation // time zone accessor and manipulation
assert_eq!(dt.offset().local_minus_utc(), Duration::hours(9)); assert_eq!(dt.offset().local_minus_utc(), Duration::hours(9));
assert_eq!(dt.with_offset(UTC), UTC.ymd(2014, 11, 28).and_hms_nano(12, 45, 59, 324310806)); assert_eq!(dt.timezone(), FixedOffset::east(9 * 3600));
assert_eq!(dt.with_timezone(&UTC), UTC.ymd(2014, 11, 28).and_hms_nano(12, 45, 59, 324310806));
// a sample of property manipulations (validates dynamically) // a sample of property manipulations (validates dynamically)
assert_eq!(dt.with_day(29).unwrap().weekday(), Weekday::Sat); // 2014-11-29 is Saturday assert_eq!(dt.with_day(29).unwrap().weekday(), Weekday::Sat); // 2014-11-29 is Saturday
@ -118,7 +119,7 @@ which format is equivalent to the familiar `strftime` format.
The default `to_string` method and `{:?}` specifier also give a reasonable representation. The default `to_string` method and `{:?}` specifier also give a reasonable representation.
~~~~ {.rust} ~~~~ {.rust}
use chrono::{UTC, Offset}; use chrono::*;
let dt = UTC.ymd(2014, 11, 28).and_hms(12, 0, 9); let dt = UTC.ymd(2014, 11, 28).and_hms(12, 0, 9);
assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2014-11-28 12:00:09"); assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2014-11-28 12:00:09");
@ -132,12 +133,12 @@ assert_eq!(format!("{:?}", dt), "2014-11-28T12:00:09Z");
### Individual date and time ### Individual date and time
Chrono also provides an individual date type (`Date`) and time type (`Time`). Chrono also provides an individual date type (`Date`) and time type (`Time`).
They also have offsets attached, and have to be constructed via offsets. They also have time zones attached, and have to be constructed via time zones.
Most operations available to `DateTime` are also available to `Date` and `Time` Most operations available to `DateTime` are also available to `Date` and `Time`
whenever appropriate. whenever appropriate.
~~~~ {.rust} ~~~~ {.rust}
use chrono::{UTC, Local, Offset, LocalResult, Datelike, Weekday}; use chrono::*;
assert_eq!(UTC::today(), UTC::now().date()); assert_eq!(UTC::today(), UTC::now().date());
assert_eq!(Local::today(), Local::now().date()); assert_eq!(Local::today(), Local::now().date());
@ -156,7 +157,7 @@ Chrono provides naive counterparts to `Date`, `Time` and `DateTime`
as `NaiveDate`, `NaiveTime` and `NaiveDateTime` respectively. as `NaiveDate`, `NaiveTime` and `NaiveDateTime` respectively.
They have almost equivalent interfaces as their timezone-aware twins, They have almost equivalent interfaces as their timezone-aware twins,
but are not associated to offsets obviously and can be quite low-level. but are not associated to time zones obviously and can be quite low-level.
They are mostly useful for building blocks for higher-level types. They are mostly useful for building blocks for higher-level types.
## Limitations ## Limitations
@ -177,5 +178,5 @@ Any operation that can be ambiguous will return `None` in such cases.
For example, "a month later" of 2014-01-30 is not well-defined For example, "a month later" of 2014-01-30 is not well-defined
and consequently `UTC.ymd(2014, 1, 30).with_month(2)` returns `None`. and consequently `UTC.ymd(2014, 1, 30).with_month(2)` returns `None`.
Advanced offset handling and date/time parsing is not yet supported (but is planned). Advanced time zone handling and date/time parsing is not yet supported (but is planned).

View File

@ -3,7 +3,7 @@
// See README.md and LICENSE.txt for details. // See README.md and LICENSE.txt for details.
/*! /*!
* ISO 8601 calendar date with timezone. * ISO 8601 calendar date with time zone.
*/ */
use std::{fmt, hash}; use std::{fmt, hash};
@ -12,7 +12,7 @@ use std::ops::{Add, Sub};
use {Weekday, Datelike}; use {Weekday, Datelike};
use duration::Duration; use duration::Duration;
use offset::{Offset, OffsetState}; use offset::{TimeZone, Offset};
use offset::utc::UTC; use offset::utc::UTC;
use naive; use naive;
use naive::date::NaiveDate; use naive::date::NaiveDate;
@ -20,11 +20,11 @@ use naive::time::NaiveTime;
use datetime::DateTime; use datetime::DateTime;
use format::DelayedFormat; use format::DelayedFormat;
/// ISO 8601 calendar date with timezone. /// ISO 8601 calendar date with time zone.
#[derive(Clone)] #[derive(Clone)]
pub struct Date<Off: Offset> { pub struct Date<Tz: TimeZone> {
date: NaiveDate, date: NaiveDate,
offset: Off::State, offset: Tz::Offset,
} }
/// The minimum possible `Date`. /// The minimum possible `Date`.
@ -32,13 +32,13 @@ pub const MIN: Date<UTC> = Date { date: naive::date::MIN, offset: UTC };
/// The maximum possible `Date`. /// The maximum possible `Date`.
pub const MAX: Date<UTC> = Date { date: naive::date::MAX, offset: UTC }; pub const MAX: Date<UTC> = Date { date: naive::date::MAX, offset: UTC };
impl<Off: Offset> Date<Off> { impl<Tz: TimeZone> Date<Tz> {
/// Makes a new `Date` with given *UTC* date and offset. /// Makes a new `Date` with given *UTC* date and offset.
/// The local date should be constructed via the `Offset` trait. /// The local date should be constructed via the `TimeZone` trait.
// //
// note: this constructor is purposedly not named to `new` to discourage the direct usage. // note: this constructor is purposedly not named to `new` to discourage the direct usage.
#[inline] #[inline]
pub fn from_utc(date: NaiveDate, offset: Off::State) -> Date<Off> { pub fn from_utc(date: NaiveDate, offset: Tz::Offset) -> Date<Tz> {
Date { date: date, offset: offset } Date { date: date, offset: offset }
} }
@ -47,7 +47,7 @@ impl<Off: Offset> Date<Off> {
/// ///
/// Fails on invalid datetime. /// Fails on invalid datetime.
#[inline] #[inline]
pub fn and_time(&self, time: NaiveTime) -> Option<DateTime<Off>> { 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);
self.timezone().from_local_datetime(&localdt).single() self.timezone().from_local_datetime(&localdt).single()
} }
@ -57,7 +57,7 @@ impl<Off: Offset> Date<Off> {
/// ///
/// Fails on invalid hour, minute and/or second. /// Fails on invalid hour, minute and/or second.
#[inline] #[inline]
pub fn and_hms(&self, hour: u32, min: u32, sec: u32) -> DateTime<Off> { 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")
} }
@ -66,7 +66,7 @@ impl<Off: Offset> Date<Off> {
/// ///
/// Returns `None` on invalid hour, minute and/or second. /// Returns `None` on invalid hour, minute and/or second.
#[inline] #[inline]
pub fn and_hms_opt(&self, hour: u32, min: u32, sec: u32) -> Option<DateTime<Off>> { pub fn and_hms_opt(&self, hour: u32, min: u32, sec: u32) -> Option<DateTime<Tz>> {
NaiveTime::from_hms_opt(hour, min, sec).and_then(|time| self.and_time(time)) NaiveTime::from_hms_opt(hour, min, sec).and_then(|time| self.and_time(time))
} }
@ -76,7 +76,7 @@ impl<Off: Offset> Date<Off> {
/// ///
/// Fails on invalid hour, minute, second and/or millisecond. /// Fails 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<Off> { 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")
} }
@ -87,7 +87,7 @@ impl<Off: Offset> Date<Off> {
/// Returns `None` on invalid hour, minute, second and/or millisecond. /// Returns `None` on invalid hour, minute, second and/or millisecond.
#[inline] #[inline]
pub fn and_hms_milli_opt(&self, hour: u32, min: u32, sec: u32, pub fn and_hms_milli_opt(&self, hour: u32, min: u32, sec: u32,
milli: u32) -> Option<DateTime<Off>> { milli: u32) -> Option<DateTime<Tz>> {
NaiveTime::from_hms_milli_opt(hour, min, sec, milli).and_then(|time| self.and_time(time)) NaiveTime::from_hms_milli_opt(hour, min, sec, milli).and_then(|time| self.and_time(time))
} }
@ -97,7 +97,7 @@ impl<Off: Offset> Date<Off> {
/// ///
/// Fails on invalid hour, minute, second and/or microsecond. /// Fails 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<Off> { 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")
} }
@ -108,7 +108,7 @@ impl<Off: Offset> Date<Off> {
/// Returns `None` on invalid hour, minute, second and/or microsecond. /// Returns `None` on invalid hour, minute, second and/or microsecond.
#[inline] #[inline]
pub fn and_hms_micro_opt(&self, hour: u32, min: u32, sec: u32, pub fn and_hms_micro_opt(&self, hour: u32, min: u32, sec: u32,
micro: u32) -> Option<DateTime<Off>> { micro: u32) -> Option<DateTime<Tz>> {
NaiveTime::from_hms_micro_opt(hour, min, sec, micro).and_then(|time| self.and_time(time)) NaiveTime::from_hms_micro_opt(hour, min, sec, micro).and_then(|time| self.and_time(time))
} }
@ -118,7 +118,7 @@ impl<Off: Offset> Date<Off> {
/// ///
/// Fails on invalid hour, minute, second and/or nanosecond. /// Fails 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<Off> { 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")
} }
@ -129,7 +129,7 @@ impl<Off: Offset> Date<Off> {
/// Returns `None` on invalid hour, minute, second and/or nanosecond. /// Returns `None` on invalid hour, minute, second and/or nanosecond.
#[inline] #[inline]
pub fn and_hms_nano_opt(&self, hour: u32, min: u32, sec: u32, pub fn and_hms_nano_opt(&self, hour: u32, min: u32, sec: u32,
nano: u32) -> Option<DateTime<Off>> { nano: u32) -> Option<DateTime<Tz>> {
NaiveTime::from_hms_nano_opt(hour, min, sec, nano).and_then(|time| self.and_time(time)) NaiveTime::from_hms_nano_opt(hour, min, sec, nano).and_then(|time| self.and_time(time))
} }
@ -137,7 +137,7 @@ impl<Off: Offset> Date<Off> {
/// ///
/// Fails when `self` is the last representable date. /// Fails when `self` is the last representable date.
#[inline] #[inline]
pub fn succ(&self) -> Date<Off> { pub fn succ(&self) -> Date<Tz> {
self.succ_opt().expect("out of bound") self.succ_opt().expect("out of bound")
} }
@ -145,7 +145,7 @@ impl<Off: Offset> Date<Off> {
/// ///
/// Returns `None` when `self` is the last representable date. /// Returns `None` when `self` is the last representable date.
#[inline] #[inline]
pub fn succ_opt(&self) -> Option<Date<Off>> { pub fn succ_opt(&self) -> Option<Date<Tz>> {
self.date.succ_opt().map(|date| Date::from_utc(date, self.offset.clone())) self.date.succ_opt().map(|date| Date::from_utc(date, self.offset.clone()))
} }
@ -153,7 +153,7 @@ impl<Off: Offset> Date<Off> {
/// ///
/// Fails when `self` is the first representable date. /// Fails when `self` is the first representable date.
#[inline] #[inline]
pub fn pred(&self) -> Date<Off> { pub fn pred(&self) -> Date<Tz> {
self.pred_opt().expect("out of bound") self.pred_opt().expect("out of bound")
} }
@ -161,26 +161,26 @@ impl<Off: Offset> Date<Off> {
/// ///
/// Returns `None` when `self` is the first representable date. /// Returns `None` when `self` is the first representable date.
#[inline] #[inline]
pub fn pred_opt(&self) -> Option<Date<Off>> { pub fn pred_opt(&self) -> Option<Date<Tz>> {
self.date.pred_opt().map(|date| Date::from_utc(date, self.offset.clone())) self.date.pred_opt().map(|date| Date::from_utc(date, self.offset.clone()))
} }
/// Retrieves an associated offset state. /// Retrieves an associated offset from UTC.
#[inline] #[inline]
pub fn offset<'a>(&'a self) -> &'a Off::State { pub fn offset<'a>(&'a self) -> &'a Tz::Offset {
&self.offset &self.offset
} }
/// Retrieves an associated offset. /// Retrieves an associated time zone.
#[inline] #[inline]
pub fn timezone(&self) -> Off { pub fn timezone(&self) -> Tz {
Offset::from_state(&self.offset) TimeZone::from_offset(&self.offset)
} }
/// Changes the associated offset. /// Changes the associated time zone.
/// This does not change the actual `Date` (but will change the string representation). /// This does not change the actual `Date` (but will change the string representation).
#[inline] #[inline]
pub fn with_timezone<Off2: Offset>(&self, tz: &Off2) -> Date<Off2> { pub fn with_timezone<Tz2: TimeZone>(&self, tz: &Tz2) -> Date<Tz2> {
tz.from_utc_date(&self.date) tz.from_utc_date(&self.date)
} }
@ -198,12 +198,12 @@ impl<Off: Offset> Date<Off> {
} }
/// Maps the local date to other date with given conversion function. /// Maps the local date to other date with given conversion function.
fn map_local<Off: Offset, F>(d: &Date<Off>, mut f: F) -> Option<Date<Off>> fn map_local<Tz: TimeZone, F>(d: &Date<Tz>, mut f: F) -> Option<Date<Tz>>
where F: FnMut(NaiveDate) -> Option<NaiveDate> { where F: FnMut(NaiveDate) -> Option<NaiveDate> {
f(d.naive_local()).and_then(|date| d.timezone().from_local_date(&date).single()) f(d.naive_local()).and_then(|date| d.timezone().from_local_date(&date).single())
} }
impl<Off: Offset> Date<Off> where Off::State: fmt::Display { impl<Tz: TimeZone> Date<Tz> where Tz::Offset: fmt::Display {
/// Formats the date in the specified format string. /// Formats the date in the specified format string.
/// See the `format` module on the supported escape sequences. /// See the `format` module on the supported escape sequences.
#[inline] #[inline]
@ -212,7 +212,7 @@ impl<Off: Offset> Date<Off> where Off::State: fmt::Display {
} }
} }
impl<Off: Offset> Datelike for Date<Off> { impl<Tz: TimeZone> Datelike for Date<Tz> {
#[inline] fn year(&self) -> i32 { self.naive_local().year() } #[inline] fn year(&self) -> i32 { self.naive_local().year() }
#[inline] fn month(&self) -> u32 { self.naive_local().month() } #[inline] fn month(&self) -> u32 { self.naive_local().month() }
#[inline] fn month0(&self) -> u32 { self.naive_local().month0() } #[inline] fn month0(&self) -> u32 { self.naive_local().month0() }
@ -224,90 +224,90 @@ impl<Off: Offset> Datelike for Date<Off> {
#[inline] fn isoweekdate(&self) -> (i32, u32, Weekday) { self.naive_local().isoweekdate() } #[inline] fn isoweekdate(&self) -> (i32, u32, Weekday) { self.naive_local().isoweekdate() }
#[inline] #[inline]
fn with_year(&self, year: i32) -> Option<Date<Off>> { fn with_year(&self, year: i32) -> Option<Date<Tz>> {
map_local(self, |date| date.with_year(year)) map_local(self, |date| date.with_year(year))
} }
#[inline] #[inline]
fn with_month(&self, month: u32) -> Option<Date<Off>> { fn with_month(&self, month: u32) -> Option<Date<Tz>> {
map_local(self, |date| date.with_month(month)) map_local(self, |date| date.with_month(month))
} }
#[inline] #[inline]
fn with_month0(&self, month0: u32) -> Option<Date<Off>> { fn with_month0(&self, month0: u32) -> Option<Date<Tz>> {
map_local(self, |date| date.with_month0(month0)) map_local(self, |date| date.with_month0(month0))
} }
#[inline] #[inline]
fn with_day(&self, day: u32) -> Option<Date<Off>> { fn with_day(&self, day: u32) -> Option<Date<Tz>> {
map_local(self, |date| date.with_day(day)) map_local(self, |date| date.with_day(day))
} }
#[inline] #[inline]
fn with_day0(&self, day0: u32) -> Option<Date<Off>> { fn with_day0(&self, day0: u32) -> Option<Date<Tz>> {
map_local(self, |date| date.with_day0(day0)) map_local(self, |date| date.with_day0(day0))
} }
#[inline] #[inline]
fn with_ordinal(&self, ordinal: u32) -> Option<Date<Off>> { fn with_ordinal(&self, ordinal: u32) -> Option<Date<Tz>> {
map_local(self, |date| date.with_ordinal(ordinal)) map_local(self, |date| date.with_ordinal(ordinal))
} }
#[inline] #[inline]
fn with_ordinal0(&self, ordinal0: u32) -> Option<Date<Off>> { fn with_ordinal0(&self, ordinal0: u32) -> Option<Date<Tz>> {
map_local(self, |date| date.with_ordinal0(ordinal0)) map_local(self, |date| date.with_ordinal0(ordinal0))
} }
} }
impl<Off: Offset, Off2: Offset> PartialEq<Date<Off2>> for Date<Off> { impl<Tz: TimeZone, Tz2: TimeZone> PartialEq<Date<Tz2>> for Date<Tz> {
fn eq(&self, other: &Date<Off2>) -> bool { self.date == other.date } fn eq(&self, other: &Date<Tz2>) -> bool { self.date == other.date }
} }
impl<Off: Offset> Eq for Date<Off> { impl<Tz: TimeZone> Eq for Date<Tz> {
} }
impl<Off: Offset> PartialOrd for Date<Off> { impl<Tz: TimeZone> PartialOrd for Date<Tz> {
fn partial_cmp(&self, other: &Date<Off>) -> Option<Ordering> { fn partial_cmp(&self, other: &Date<Tz>) -> Option<Ordering> {
self.date.partial_cmp(&other.date) self.date.partial_cmp(&other.date)
} }
} }
impl<Off: Offset> Ord for Date<Off> { impl<Tz: TimeZone> Ord for Date<Tz> {
fn cmp(&self, other: &Date<Off>) -> Ordering { self.date.cmp(&other.date) } fn cmp(&self, other: &Date<Tz>) -> Ordering { self.date.cmp(&other.date) }
} }
impl<Off: Offset, H: hash::Hasher + hash::Writer> hash::Hash<H> for Date<Off> { impl<Tz: TimeZone, H: hash::Hasher + hash::Writer> hash::Hash<H> for Date<Tz> {
fn hash(&self, state: &mut H) { self.date.hash(state) } fn hash(&self, state: &mut H) { self.date.hash(state) }
} }
impl<Off: Offset> Add<Duration> for Date<Off> { impl<Tz: TimeZone> Add<Duration> for Date<Tz> {
type Output = Date<Off>; type Output = Date<Tz>;
fn add(self, rhs: Duration) -> Date<Off> { fn add(self, rhs: Duration) -> Date<Tz> {
Date { date: self.date + rhs, offset: self.offset } Date { date: self.date + rhs, offset: self.offset }
} }
} }
impl<Off: Offset, Off2: Offset> Sub<Date<Off2>> for Date<Off> { impl<Tz: TimeZone, Tz2: TimeZone> Sub<Date<Tz2>> for Date<Tz> {
type Output = Duration; type Output = Duration;
fn sub(self, rhs: Date<Off2>) -> Duration { self.date - rhs.date } fn sub(self, rhs: Date<Tz2>) -> Duration { self.date - rhs.date }
} }
impl<Off: Offset> Sub<Duration> for Date<Off> { impl<Tz: TimeZone> Sub<Duration> for Date<Tz> {
type Output = Date<Off>; type Output = Date<Tz>;
#[inline] #[inline]
fn sub(self, rhs: Duration) -> Date<Off> { self.add(-rhs) } fn sub(self, rhs: Duration) -> Date<Tz> { self.add(-rhs) }
} }
impl<Off: Offset> fmt::Debug for Date<Off> { impl<Tz: TimeZone> fmt::Debug for Date<Tz> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}{:?}", self.naive_local(), self.offset) write!(f, "{:?}{:?}", self.naive_local(), self.offset)
} }
} }
impl<Off: Offset> fmt::Display for Date<Off> where Off::State: fmt::Display { impl<Tz: TimeZone> fmt::Display for Date<Tz> where Tz::Offset: fmt::Display {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}{}", self.naive_local(), self.offset) write!(f, "{}{}", self.naive_local(), self.offset)
} }
@ -321,7 +321,7 @@ mod tests {
use naive::date::NaiveDate; use naive::date::NaiveDate;
use naive::time::NaiveTime; use naive::time::NaiveTime;
use naive::datetime::NaiveDateTime; use naive::datetime::NaiveDateTime;
use offset::{Offset, OffsetState, LocalResult}; use offset::{TimeZone, Offset, LocalResult};
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
struct UTC1y; // same to UTC but with an offset of 365 days struct UTC1y; // same to UTC but with an offset of 365 days
@ -329,27 +329,27 @@ mod tests {
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
struct OneYear; struct OneYear;
impl Offset for UTC1y { impl TimeZone for UTC1y {
type State = OneYear; type Offset = OneYear;
fn from_state(_state: &OneYear) -> UTC1y { UTC1y } fn from_offset(_offset: &OneYear) -> UTC1y { UTC1y }
fn state_from_local_date(&self, _local: &NaiveDate) -> LocalResult<OneYear> { fn offset_from_local_date(&self, _local: &NaiveDate) -> LocalResult<OneYear> {
LocalResult::Single(OneYear) LocalResult::Single(OneYear)
} }
fn state_from_local_time(&self, _local: &NaiveTime) -> LocalResult<OneYear> { fn offset_from_local_time(&self, _local: &NaiveTime) -> LocalResult<OneYear> {
LocalResult::Single(OneYear) LocalResult::Single(OneYear)
} }
fn state_from_local_datetime(&self, _local: &NaiveDateTime) -> LocalResult<OneYear> { fn offset_from_local_datetime(&self, _local: &NaiveDateTime) -> LocalResult<OneYear> {
LocalResult::Single(OneYear) LocalResult::Single(OneYear)
} }
fn state_from_utc_date(&self, _utc: &NaiveDate) -> OneYear { OneYear } fn offset_from_utc_date(&self, _utc: &NaiveDate) -> OneYear { OneYear }
fn state_from_utc_time(&self, _utc: &NaiveTime) -> OneYear { OneYear } fn offset_from_utc_time(&self, _utc: &NaiveTime) -> OneYear { OneYear }
fn state_from_utc_datetime(&self, _utc: &NaiveDateTime) -> OneYear { OneYear } fn offset_from_utc_datetime(&self, _utc: &NaiveDateTime) -> OneYear { OneYear }
} }
impl OffsetState for OneYear { impl Offset for OneYear {
fn local_minus_utc(&self) -> Duration { Duration::days(365) } fn local_minus_utc(&self) -> Duration { Duration::days(365) }
} }

View File

@ -3,7 +3,7 @@
// See README.md and LICENSE.txt for details. // See README.md and LICENSE.txt for details.
/*! /*!
* ISO 8601 date and time. * ISO 8601 date and time with time zone.
*/ */
use std::{fmt, hash}; use std::{fmt, hash};
@ -11,39 +11,39 @@ use std::cmp::Ordering;
use std::ops::{Add, Sub}; use std::ops::{Add, Sub};
use {Weekday, Timelike, Datelike}; use {Weekday, Timelike, Datelike};
use offset::{Offset, OffsetState}; use offset::{TimeZone, Offset};
use duration::Duration; use duration::Duration;
use naive::datetime::NaiveDateTime; use naive::datetime::NaiveDateTime;
use time::Time; use time::Time;
use date::Date; use date::Date;
use format::DelayedFormat; use format::DelayedFormat;
/// ISO 8601 combined date and time with timezone. /// ISO 8601 combined date and time with time zone.
#[derive(Clone)] #[derive(Clone)]
pub struct DateTime<Off: Offset> { pub struct DateTime<Tz: TimeZone> {
datetime: NaiveDateTime, datetime: NaiveDateTime,
offset: Off::State, offset: Tz::Offset,
} }
impl<Off: Offset> DateTime<Off> { impl<Tz: TimeZone> DateTime<Tz> {
/// Makes a new `DateTime` with given *UTC* datetime and offset. /// Makes a new `DateTime` with given *UTC* datetime and offset.
/// The local datetime should be constructed via the `Offset` trait. /// The local datetime should be constructed via the `TimeZone` trait.
// //
// note: this constructor is purposedly not named to `new` to discourage the direct usage. // note: this constructor is purposedly not named to `new` to discourage the direct usage.
#[inline] #[inline]
pub fn from_utc(datetime: NaiveDateTime, offset: Off::State) -> DateTime<Off> { pub fn from_utc(datetime: NaiveDateTime, offset: Tz::Offset) -> DateTime<Tz> {
DateTime { datetime: datetime, offset: offset } DateTime { datetime: datetime, offset: offset }
} }
/// Retrieves a date component. /// Retrieves a date component.
#[inline] #[inline]
pub fn date(&self) -> Date<Off> { pub fn date(&self) -> Date<Tz> {
Date::from_utc(self.datetime.date().clone(), self.offset.clone()) Date::from_utc(self.datetime.date().clone(), self.offset.clone())
} }
/// Retrieves a time component. /// Retrieves a time component.
#[inline] #[inline]
pub fn time(&self) -> Time<Off> { pub fn time(&self) -> Time<Tz> {
Time::from_utc(self.datetime.time().clone(), self.offset.clone()) Time::from_utc(self.datetime.time().clone(), self.offset.clone())
} }
@ -53,22 +53,22 @@ impl<Off: Offset> DateTime<Off> {
self.datetime.num_seconds_from_unix_epoch() self.datetime.num_seconds_from_unix_epoch()
} }
/// Retrieves an associated offset state. /// Retrieves an associated offset from UTC.
#[inline] #[inline]
pub fn offset<'a>(&'a self) -> &'a Off::State { pub fn offset<'a>(&'a self) -> &'a Tz::Offset {
&self.offset &self.offset
} }
/// Retrieves an associated offset. /// Retrieves an associated time zone.
#[inline] #[inline]
pub fn timezone(&self) -> Off { pub fn timezone(&self) -> Tz {
Offset::from_state(&self.offset) TimeZone::from_offset(&self.offset)
} }
/// Changes the associated offset. /// Changes the associated time zone.
/// This does not change the actual `DateTime` (but will change the string representation). /// This does not change the actual `DateTime` (but will change the string representation).
#[inline] #[inline]
pub fn with_timezone<Off2: Offset>(&self, tz: &Off2) -> DateTime<Off2> { pub fn with_timezone<Tz2: TimeZone>(&self, tz: &Tz2) -> DateTime<Tz2> {
tz.from_utc_datetime(&self.datetime) tz.from_utc_datetime(&self.datetime)
} }
@ -86,12 +86,12 @@ impl<Off: Offset> DateTime<Off> {
} }
/// Maps the local datetime to other datetime with given conversion function. /// Maps the local datetime to other datetime with given conversion function.
fn map_local<Off: Offset, F>(dt: &DateTime<Off>, mut f: F) -> Option<DateTime<Off>> fn map_local<Tz: TimeZone, F>(dt: &DateTime<Tz>, mut f: F) -> Option<DateTime<Tz>>
where F: FnMut(NaiveDateTime) -> Option<NaiveDateTime> { where F: FnMut(NaiveDateTime) -> Option<NaiveDateTime> {
f(dt.naive_local()).and_then(|datetime| dt.timezone().from_local_datetime(&datetime).single()) f(dt.naive_local()).and_then(|datetime| dt.timezone().from_local_datetime(&datetime).single())
} }
impl<Off: Offset> DateTime<Off> where Off::State: fmt::Display { impl<Tz: TimeZone> DateTime<Tz> where Tz::Offset: fmt::Display {
/// Formats the combined date and time in the specified format string. /// Formats the combined date and time in the specified format string.
/// See the `format` module on the supported escape sequences. /// See the `format` module on the supported escape sequences.
#[inline] #[inline]
@ -101,7 +101,7 @@ impl<Off: Offset> DateTime<Off> where Off::State: fmt::Display {
} }
} }
impl<Off: Offset> Datelike for DateTime<Off> { impl<Tz: TimeZone> Datelike for DateTime<Tz> {
#[inline] fn year(&self) -> i32 { self.naive_local().year() } #[inline] fn year(&self) -> i32 { self.naive_local().year() }
#[inline] fn month(&self) -> u32 { self.naive_local().month() } #[inline] fn month(&self) -> u32 { self.naive_local().month() }
#[inline] fn month0(&self) -> u32 { self.naive_local().month0() } #[inline] fn month0(&self) -> u32 { self.naive_local().month0() }
@ -113,117 +113,117 @@ impl<Off: Offset> Datelike for DateTime<Off> {
#[inline] fn isoweekdate(&self) -> (i32, u32, Weekday) { self.naive_local().isoweekdate() } #[inline] fn isoweekdate(&self) -> (i32, u32, Weekday) { self.naive_local().isoweekdate() }
#[inline] #[inline]
fn with_year(&self, year: i32) -> Option<DateTime<Off>> { fn with_year(&self, year: i32) -> Option<DateTime<Tz>> {
map_local(self, |datetime| datetime.with_year(year)) map_local(self, |datetime| datetime.with_year(year))
} }
#[inline] #[inline]
fn with_month(&self, month: u32) -> Option<DateTime<Off>> { fn with_month(&self, month: u32) -> Option<DateTime<Tz>> {
map_local(self, |datetime| datetime.with_month(month)) map_local(self, |datetime| datetime.with_month(month))
} }
#[inline] #[inline]
fn with_month0(&self, month0: u32) -> Option<DateTime<Off>> { fn with_month0(&self, month0: u32) -> Option<DateTime<Tz>> {
map_local(self, |datetime| datetime.with_month0(month0)) map_local(self, |datetime| datetime.with_month0(month0))
} }
#[inline] #[inline]
fn with_day(&self, day: u32) -> Option<DateTime<Off>> { fn with_day(&self, day: u32) -> Option<DateTime<Tz>> {
map_local(self, |datetime| datetime.with_day(day)) map_local(self, |datetime| datetime.with_day(day))
} }
#[inline] #[inline]
fn with_day0(&self, day0: u32) -> Option<DateTime<Off>> { fn with_day0(&self, day0: u32) -> Option<DateTime<Tz>> {
map_local(self, |datetime| datetime.with_day0(day0)) map_local(self, |datetime| datetime.with_day0(day0))
} }
#[inline] #[inline]
fn with_ordinal(&self, ordinal: u32) -> Option<DateTime<Off>> { fn with_ordinal(&self, ordinal: u32) -> Option<DateTime<Tz>> {
map_local(self, |datetime| datetime.with_ordinal(ordinal)) map_local(self, |datetime| datetime.with_ordinal(ordinal))
} }
#[inline] #[inline]
fn with_ordinal0(&self, ordinal0: u32) -> Option<DateTime<Off>> { fn with_ordinal0(&self, ordinal0: u32) -> Option<DateTime<Tz>> {
map_local(self, |datetime| datetime.with_ordinal0(ordinal0)) map_local(self, |datetime| datetime.with_ordinal0(ordinal0))
} }
} }
impl<Off: Offset> Timelike for DateTime<Off> { impl<Tz: TimeZone> Timelike for DateTime<Tz> {
#[inline] fn hour(&self) -> u32 { self.naive_local().hour() } #[inline] fn hour(&self) -> u32 { self.naive_local().hour() }
#[inline] fn minute(&self) -> u32 { self.naive_local().minute() } #[inline] fn minute(&self) -> u32 { self.naive_local().minute() }
#[inline] fn second(&self) -> u32 { self.naive_local().second() } #[inline] fn second(&self) -> u32 { self.naive_local().second() }
#[inline] fn nanosecond(&self) -> u32 { self.naive_local().nanosecond() } #[inline] fn nanosecond(&self) -> u32 { self.naive_local().nanosecond() }
#[inline] #[inline]
fn with_hour(&self, hour: u32) -> Option<DateTime<Off>> { fn with_hour(&self, hour: u32) -> Option<DateTime<Tz>> {
map_local(self, |datetime| datetime.with_hour(hour)) map_local(self, |datetime| datetime.with_hour(hour))
} }
#[inline] #[inline]
fn with_minute(&self, min: u32) -> Option<DateTime<Off>> { fn with_minute(&self, min: u32) -> Option<DateTime<Tz>> {
map_local(self, |datetime| datetime.with_minute(min)) map_local(self, |datetime| datetime.with_minute(min))
} }
#[inline] #[inline]
fn with_second(&self, sec: u32) -> Option<DateTime<Off>> { fn with_second(&self, sec: u32) -> Option<DateTime<Tz>> {
map_local(self, |datetime| datetime.with_second(sec)) map_local(self, |datetime| datetime.with_second(sec))
} }
#[inline] #[inline]
fn with_nanosecond(&self, nano: u32) -> Option<DateTime<Off>> { fn with_nanosecond(&self, nano: u32) -> Option<DateTime<Tz>> {
map_local(self, |datetime| datetime.with_nanosecond(nano)) map_local(self, |datetime| datetime.with_nanosecond(nano))
} }
} }
impl<Off: Offset, Off2: Offset> PartialEq<DateTime<Off2>> for DateTime<Off> { impl<Tz: TimeZone, Tz2: TimeZone> PartialEq<DateTime<Tz2>> for DateTime<Tz> {
fn eq(&self, other: &DateTime<Off2>) -> bool { self.datetime == other.datetime } fn eq(&self, other: &DateTime<Tz2>) -> bool { self.datetime == other.datetime }
} }
impl<Off: Offset> Eq for DateTime<Off> { impl<Tz: TimeZone> Eq for DateTime<Tz> {
} }
impl<Off: Offset> PartialOrd for DateTime<Off> { impl<Tz: TimeZone> PartialOrd for DateTime<Tz> {
fn partial_cmp(&self, other: &DateTime<Off>) -> Option<Ordering> { fn partial_cmp(&self, other: &DateTime<Tz>) -> Option<Ordering> {
self.datetime.partial_cmp(&other.datetime) self.datetime.partial_cmp(&other.datetime)
} }
} }
impl<Off: Offset> Ord for DateTime<Off> { impl<Tz: TimeZone> Ord for DateTime<Tz> {
fn cmp(&self, other: &DateTime<Off>) -> Ordering { self.datetime.cmp(&other.datetime) } fn cmp(&self, other: &DateTime<Tz>) -> Ordering { self.datetime.cmp(&other.datetime) }
} }
impl<Off: Offset, H: hash::Hasher + hash::Writer> hash::Hash<H> for DateTime<Off> { impl<Tz: TimeZone, H: hash::Hasher + hash::Writer> hash::Hash<H> for DateTime<Tz> {
fn hash(&self, state: &mut H) { self.datetime.hash(state) } fn hash(&self, state: &mut H) { self.datetime.hash(state) }
} }
impl<Off: Offset> Add<Duration> for DateTime<Off> { impl<Tz: TimeZone> Add<Duration> for DateTime<Tz> {
type Output = DateTime<Off>; type Output = DateTime<Tz>;
fn add(self, rhs: Duration) -> DateTime<Off> { fn add(self, rhs: Duration) -> DateTime<Tz> {
DateTime { datetime: self.datetime + rhs, offset: self.offset } DateTime { datetime: self.datetime + rhs, offset: self.offset }
} }
} }
impl<Off: Offset, Off2: Offset> Sub<DateTime<Off2>> for DateTime<Off> { impl<Tz: TimeZone, Tz2: TimeZone> Sub<DateTime<Tz2>> for DateTime<Tz> {
type Output = Duration; type Output = Duration;
fn sub(self, rhs: DateTime<Off2>) -> Duration { self.datetime - rhs.datetime } fn sub(self, rhs: DateTime<Tz2>) -> Duration { self.datetime - rhs.datetime }
} }
impl<Off: Offset> Sub<Duration> for DateTime<Off> { impl<Tz: TimeZone> Sub<Duration> for DateTime<Tz> {
type Output = DateTime<Off>; type Output = DateTime<Tz>;
#[inline] #[inline]
fn sub(self, rhs: Duration) -> DateTime<Off> { self.add(-rhs) } fn sub(self, rhs: Duration) -> DateTime<Tz> { self.add(-rhs) }
} }
impl<Off: Offset> fmt::Debug for DateTime<Off> { impl<Tz: TimeZone> fmt::Debug for DateTime<Tz> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}{:?}", self.naive_local(), self.offset) write!(f, "{:?}{:?}", self.naive_local(), self.offset)
} }
} }
impl<Off: Offset> fmt::Display for DateTime<Off> where Off::State: fmt::Display { impl<Tz: TimeZone> fmt::Display for DateTime<Tz> where Tz::Offset: fmt::Display {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {}", self.naive_local(), self.offset) write!(f, "{} {}", self.naive_local(), self.offset)
} }
@ -233,7 +233,7 @@ impl<Off: Offset> fmt::Display for DateTime<Off> where Off::State: fmt::Display
mod tests { mod tests {
use {Datelike}; use {Datelike};
use duration::Duration; use duration::Duration;
use offset::Offset; use offset::TimeZone;
use offset::utc::UTC; use offset::utc::UTC;
use offset::local::Local; use offset::local::Local;
use offset::fixed::FixedOffset; use offset::fixed::FixedOffset;

View File

@ -10,7 +10,7 @@ use std::fmt;
use {Datelike, Timelike}; use {Datelike, Timelike};
use duration::Duration; use duration::Duration;
use offset::OffsetState; use offset::Offset;
use naive::date::NaiveDate; use naive::date::NaiveDate;
use naive::time::NaiveTime; use naive::time::NaiveTime;
@ -198,11 +198,11 @@ impl<'a> DelayedFormat<'a> {
DelayedFormat { date: date, time: time, off: None, fmt: fmt } DelayedFormat { date: date, time: time, off: None, fmt: fmt }
} }
/// Makes a new `DelayedFormat` value out of local date and time with offset state. /// Makes a new `DelayedFormat` value out of local date and time with offset.
pub fn new_with_offset<Off>(date: Option<NaiveDate>, time: Option<NaiveTime>, pub fn new_with_offset<Off>(date: Option<NaiveDate>, time: Option<NaiveTime>,
state: &Off, fmt: &'a str) -> DelayedFormat<'a> offset: &Off, fmt: &'a str) -> DelayedFormat<'a>
where Off: OffsetState + fmt::Display { where Off: Offset + fmt::Display {
let name_and_diff = (state.to_string(), state.local_minus_utc()); let name_and_diff = (offset.to_string(), offset.local_minus_utc());
DelayedFormat { date: date, time: time, off: Some(name_and_diff), fmt: fmt } DelayedFormat { date: date, time: time, off: Some(name_and_diff), fmt: fmt }
} }
} }

View File

@ -34,8 +34,8 @@ Chrono simply reexports it.
Chrono provides a `DateTime` type for the combined date and time. Chrono provides a `DateTime` type for the combined date and time.
`DateTime`, among others, is timezone-aware and `DateTime`, among others, is timezone-aware and
must be constructed from the timezone object (`Offset`). must be constructed from the `TimeZone` object.
`DateTime`s with different offsets do not mix, but can be converted to each other. `DateTime`s with different time zones do not mix, but can be converted to each other.
You can get the current date and time in the UTC timezone (`UTC::now()`) You can get the current date and time in the UTC timezone (`UTC::now()`)
or in the local timezone (`Local::now()`). or in the local timezone (`Local::now()`).
@ -95,8 +95,9 @@ assert_eq!(dt.weekday().number_from_monday(), 5); // Mon=1, ..., Sat=7
assert_eq!(dt.ordinal(), 332); // the day of year assert_eq!(dt.ordinal(), 332); // the day of year
assert_eq!(dt.num_days_from_ce(), 735565); // the number of days from and including Jan 1, 1 assert_eq!(dt.num_days_from_ce(), 735565); // the number of days from and including Jan 1, 1
// offset accessor and manipulation // time zone accessor and manipulation
assert_eq!(dt.offset().local_minus_utc(), Duration::hours(9)); assert_eq!(dt.offset().local_minus_utc(), Duration::hours(9));
assert_eq!(dt.timezone(), FixedOffset::east(9 * 3600));
assert_eq!(dt.with_timezone(&UTC), UTC.ymd(2014, 11, 28).and_hms_nano(12, 45, 59, 324310806)); assert_eq!(dt.with_timezone(&UTC), UTC.ymd(2014, 11, 28).and_hms_nano(12, 45, 59, 324310806));
// a sample of property manipulations (validates dynamically) // a sample of property manipulations (validates dynamically)
@ -132,7 +133,7 @@ assert_eq!(format!("{:?}", dt), "2014-11-28T12:00:09Z");
### Individual date and time ### Individual date and time
Chrono also provides an individual date type (`Date`) and time type (`Time`). Chrono also provides an individual date type (`Date`) and time type (`Time`).
They also have offsets attached, and have to be constructed via offsets. They also have time zones attached, and have to be constructed via time zones.
Most operations available to `DateTime` are also available to `Date` and `Time` Most operations available to `DateTime` are also available to `Date` and `Time`
whenever appropriate. whenever appropriate.
@ -157,7 +158,7 @@ Chrono provides naive counterparts to `Date`, `Time` and `DateTime`
as `NaiveDate`, `NaiveTime` and `NaiveDateTime` respectively. as `NaiveDate`, `NaiveTime` and `NaiveDateTime` respectively.
They have almost equivalent interfaces as their timezone-aware twins, They have almost equivalent interfaces as their timezone-aware twins,
but are not associated to offsets obviously and can be quite low-level. but are not associated to time zones obviously and can be quite low-level.
They are mostly useful for building blocks for higher-level types. They are mostly useful for building blocks for higher-level types.
## Limitations ## Limitations
@ -178,7 +179,7 @@ Any operation that can be ambiguous will return `None` in such cases.
For example, "a month later" of 2014-01-30 is not well-defined For example, "a month later" of 2014-01-30 is not well-defined
and consequently `UTC.ymd(2014, 1, 30).with_month(2)` returns `None`. and consequently `UTC.ymd(2014, 1, 30).with_month(2)` returns `None`.
Advanced offset handling and date/time parsing is not yet supported (but is planned). Advanced time zone handling and date/time parsing is not yet supported (but is planned).
*/ */
@ -191,7 +192,7 @@ Advanced offset handling and date/time parsing is not yet supported (but is plan
extern crate "time" as stdtime; extern crate "time" as stdtime;
pub use duration::Duration; pub use duration::Duration;
pub use offset::{Offset, OffsetState, LocalResult}; pub use offset::{TimeZone, Offset, LocalResult};
pub use offset::utc::UTC; pub use offset::utc::UTC;
pub use offset::fixed::FixedOffset; pub use offset::fixed::FixedOffset;
pub use offset::local::Local; pub use offset::local::Local;
@ -214,7 +215,7 @@ pub mod offset;
pub mod naive { pub mod naive {
//! Date and time types which do not concern about the timezones. //! Date and time types which do not concern about the timezones.
//! //!
//! They are primarily building blocks for other types (e.g. `Offset`), //! They are primarily building blocks for other types (e.g. `TimeZone`),
//! but can be also used for the simpler date and time handling. //! but can be also used for the simpler date and time handling.
pub mod date; pub mod date;
pub mod time; pub mod time;

View File

@ -12,7 +12,6 @@ use std::ops::{Add, Sub};
use Timelike; use Timelike;
use div::div_mod_floor; use div::div_mod_floor;
use offset::Offset;
use duration::Duration; use duration::Duration;
use format::DelayedFormat; use format::DelayedFormat;

View File

@ -13,9 +13,9 @@ use duration::Duration;
use naive::date::NaiveDate; use naive::date::NaiveDate;
use naive::time::NaiveTime; use naive::time::NaiveTime;
use naive::datetime::NaiveDateTime; use naive::datetime::NaiveDateTime;
use super::{Offset, OffsetState, LocalResult}; use super::{TimeZone, Offset, LocalResult};
/// The fixed offset (and also state), from UTC-23:59:59 to UTC+23:59:59. /// The time zone with fixed offset, from UTC-23:59:59 to UTC+23:59:59.
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
pub struct FixedOffset { pub struct FixedOffset {
local_minus_utc: i32, local_minus_utc: i32,
@ -63,27 +63,27 @@ impl FixedOffset {
} }
} }
impl Offset for FixedOffset { impl TimeZone for FixedOffset {
type State = FixedOffset; type Offset = FixedOffset;
fn from_state(state: &FixedOffset) -> FixedOffset { state.clone() } fn from_offset(offset: &FixedOffset) -> FixedOffset { offset.clone() }
fn state_from_local_date(&self, _local: &NaiveDate) -> LocalResult<FixedOffset> { fn offset_from_local_date(&self, _local: &NaiveDate) -> LocalResult<FixedOffset> {
LocalResult::Single(self.clone()) LocalResult::Single(self.clone())
} }
fn state_from_local_time(&self, _local: &NaiveTime) -> LocalResult<FixedOffset> { fn offset_from_local_time(&self, _local: &NaiveTime) -> LocalResult<FixedOffset> {
LocalResult::Single(self.clone()) LocalResult::Single(self.clone())
} }
fn state_from_local_datetime(&self, _local: &NaiveDateTime) -> LocalResult<FixedOffset> { fn offset_from_local_datetime(&self, _local: &NaiveDateTime) -> LocalResult<FixedOffset> {
LocalResult::Single(self.clone()) LocalResult::Single(self.clone())
} }
fn state_from_utc_date(&self, _utc: &NaiveDate) -> FixedOffset { self.clone() } fn offset_from_utc_date(&self, _utc: &NaiveDate) -> FixedOffset { self.clone() }
fn state_from_utc_time(&self, _utc: &NaiveTime) -> FixedOffset { self.clone() } fn offset_from_utc_time(&self, _utc: &NaiveTime) -> FixedOffset { self.clone() }
fn state_from_utc_datetime(&self, _utc: &NaiveDateTime) -> FixedOffset { self.clone() } fn offset_from_utc_datetime(&self, _utc: &NaiveDateTime) -> FixedOffset { self.clone() }
} }
impl OffsetState for FixedOffset { impl Offset for FixedOffset {
fn local_minus_utc(&self) -> Duration { Duration::seconds(self.local_minus_utc as i64) } fn local_minus_utc(&self) -> Duration { Duration::seconds(self.local_minus_utc as i64) }
} }

View File

@ -16,7 +16,7 @@ use naive::datetime::NaiveDateTime;
use date::Date; use date::Date;
use time::Time; use time::Time;
use datetime::DateTime; use datetime::DateTime;
use super::{Offset, LocalResult}; use super::{TimeZone, LocalResult};
use super::fixed::FixedOffset; use super::fixed::FixedOffset;
/// Converts a `time::Tm` struct into the timezone-aware `DateTime`. /// Converts a `time::Tm` struct into the timezone-aware `DateTime`.
@ -70,29 +70,29 @@ impl Local {
} }
} }
impl Offset for Local { impl TimeZone for Local {
type State = FixedOffset; type Offset = FixedOffset;
fn from_state(_state: &FixedOffset) -> Local { Local } fn from_offset(_offset: &FixedOffset) -> Local { Local }
// they are easier to define in terms of the finished date and time unlike other offsets // they are easier to define in terms of the finished date and time unlike other offsets
fn state_from_local_date(&self, local: &NaiveDate) -> LocalResult<FixedOffset> { fn offset_from_local_date(&self, local: &NaiveDate) -> LocalResult<FixedOffset> {
self.from_local_date(local).map(|&: date| *date.offset()) self.from_local_date(local).map(|&: date| *date.offset())
} }
fn state_from_local_time(&self, local: &NaiveTime) -> LocalResult<FixedOffset> { fn offset_from_local_time(&self, local: &NaiveTime) -> LocalResult<FixedOffset> {
self.from_local_time(local).map(|&: time| *time.offset()) self.from_local_time(local).map(|&: time| *time.offset())
} }
fn state_from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<FixedOffset> { fn offset_from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<FixedOffset> {
self.from_local_datetime(local).map(|&: datetime| *datetime.offset()) self.from_local_datetime(local).map(|&: datetime| *datetime.offset())
} }
fn state_from_utc_date(&self, utc: &NaiveDate) -> FixedOffset { fn offset_from_utc_date(&self, utc: &NaiveDate) -> FixedOffset {
*self.from_utc_date(utc).offset() *self.from_utc_date(utc).offset()
} }
fn state_from_utc_time(&self, utc: &NaiveTime) -> FixedOffset { fn offset_from_utc_time(&self, utc: &NaiveTime) -> FixedOffset {
*self.from_utc_time(utc).offset() *self.from_utc_time(utc).offset()
} }
fn state_from_utc_datetime(&self, utc: &NaiveDateTime) -> FixedOffset { fn offset_from_utc_datetime(&self, utc: &NaiveDateTime) -> FixedOffset {
*self.from_utc_datetime(utc).offset() *self.from_utc_datetime(utc).offset()
} }

View File

@ -3,21 +3,21 @@
// See README.md and LICENSE.txt for details. // See README.md and LICENSE.txt for details.
/*! /*!
* Offsets from the local time to UTC. * The time zone, which calculates offsets from the local time to UTC.
* *
* There are three operations provided by the `Offset` trait: * There are three operations provided by the `TimeZone` trait:
* *
* 1. Converting the local `NaiveDateTime` to `DateTime<Offset>` * 1. Converting the local `NaiveDateTime` to `DateTime<Tz>`
* 2. Converting the UTC `NaiveDateTime` to `DateTime<Offset>` * 2. Converting the UTC `NaiveDateTime` to `DateTime<Tz>`
* 3. Converting `DateTime<Offset>` to the local `NaiveDateTime` * 3. Converting `DateTime<Tz>` to the local `NaiveDateTime`
* *
* 1 is used for constructors. 2 is used for the `with_offset` method of date and time types. * 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 * 3 is used for other methods, e.g. `year()` or `format()`, and provided by an associated type
* which implements `OffsetState` (which then passed to `Offset` for actual implementations). * which implements `Offset` (which then passed to `TimeZone` for actual implementations).
* Technically speaking `Offset` has a total knowledge about given timescale, * Technically speaking `TimeZone` has a total knowledge about given timescale,
* but `OffsetState` is used as a cache to avoid the repeated conversion * but `Offset` is used as a cache to avoid the repeated conversion
* and provides implementations for 1 and 3. * and provides implementations for 1 and 3.
* An `Offset` instance can be reconstructed from the corresponding `OffsetState` instance. * An `TimeZone` instance can be reconstructed from the corresponding `Offset` instance.
*/ */
use std::fmt; use std::fmt;
@ -70,13 +70,13 @@ impl<T> LocalResult<T> {
} }
} }
impl<Off: Offset> LocalResult<Date<Off>> { impl<Tz: TimeZone> LocalResult<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.
/// ///
/// Propagates any error. Ambiguous result would be discarded. /// Propagates any error. Ambiguous result would be discarded.
#[inline] #[inline]
pub fn and_time(self, time: NaiveTime) -> LocalResult<DateTime<Off>> { pub fn and_time(self, time: NaiveTime) -> LocalResult<DateTime<Tz>> {
match self { match self {
LocalResult::Single(d) => d.and_time(time) LocalResult::Single(d) => d.and_time(time)
.map_or(LocalResult::None, LocalResult::Single), .map_or(LocalResult::None, LocalResult::Single),
@ -89,7 +89,7 @@ impl<Off: Offset> LocalResult<Date<Off>> {
/// ///
/// Propagates any error. Ambiguous result would be discarded. /// Propagates any error. Ambiguous result would be discarded.
#[inline] #[inline]
pub fn and_hms_opt(self, hour: u32, min: u32, sec: u32) -> LocalResult<DateTime<Off>> { pub fn and_hms_opt(self, hour: u32, min: u32, sec: u32) -> LocalResult<DateTime<Tz>> {
match self { match self {
LocalResult::Single(d) => d.and_hms_opt(hour, min, sec) LocalResult::Single(d) => d.and_hms_opt(hour, min, sec)
.map_or(LocalResult::None, LocalResult::Single), .map_or(LocalResult::None, LocalResult::Single),
@ -104,7 +104,7 @@ impl<Off: Offset> LocalResult<Date<Off>> {
/// Propagates any error. Ambiguous result would be discarded. /// Propagates any error. Ambiguous result would be discarded.
#[inline] #[inline]
pub fn and_hms_milli_opt(self, hour: u32, min: u32, sec: u32, pub fn and_hms_milli_opt(self, hour: u32, min: u32, sec: u32,
milli: u32) -> LocalResult<DateTime<Off>> { milli: u32) -> LocalResult<DateTime<Tz>> {
match self { match self {
LocalResult::Single(d) => d.and_hms_milli_opt(hour, min, sec, milli) LocalResult::Single(d) => d.and_hms_milli_opt(hour, min, sec, milli)
.map_or(LocalResult::None, LocalResult::Single), .map_or(LocalResult::None, LocalResult::Single),
@ -119,7 +119,7 @@ impl<Off: Offset> LocalResult<Date<Off>> {
/// Propagates any error. Ambiguous result would be discarded. /// Propagates any error. Ambiguous result would be discarded.
#[inline] #[inline]
pub fn and_hms_micro_opt(self, hour: u32, min: u32, sec: u32, pub fn and_hms_micro_opt(self, hour: u32, min: u32, sec: u32,
micro: u32) -> LocalResult<DateTime<Off>> { micro: u32) -> LocalResult<DateTime<Tz>> {
match self { match self {
LocalResult::Single(d) => d.and_hms_micro_opt(hour, min, sec, micro) LocalResult::Single(d) => d.and_hms_micro_opt(hour, min, sec, micro)
.map_or(LocalResult::None, LocalResult::Single), .map_or(LocalResult::None, LocalResult::Single),
@ -134,7 +134,7 @@ impl<Off: Offset> LocalResult<Date<Off>> {
/// Propagates any error. Ambiguous result would be discarded. /// Propagates any error. Ambiguous result would be discarded.
#[inline] #[inline]
pub fn and_hms_nano_opt(self, hour: u32, min: u32, sec: u32, pub fn and_hms_nano_opt(self, hour: u32, min: u32, sec: u32,
nano: u32) -> LocalResult<DateTime<Off>> { nano: u32) -> LocalResult<DateTime<Tz>> {
match self { match self {
LocalResult::Single(d) => d.and_hms_nano_opt(hour, min, sec, nano) LocalResult::Single(d) => d.and_hms_nano_opt(hour, min, sec, nano)
.map_or(LocalResult::None, LocalResult::Single), .map_or(LocalResult::None, LocalResult::Single),
@ -157,20 +157,20 @@ impl<T: fmt::Debug> LocalResult<T> {
} }
} }
/// The offset state. /// The offset from the local time to UTC.
pub trait OffsetState: Sized + Clone + fmt::Debug { pub trait Offset: Sized + Clone + fmt::Debug {
/// Returns the offset from UTC to the local time stored in the offset state. /// Returns the offset from UTC to the local time stored.
fn local_minus_utc(&self) -> Duration; fn local_minus_utc(&self) -> Duration;
} }
/// The offset from the local time to UTC. /// The time zone.
pub trait Offset: Sized { pub trait TimeZone: Sized {
type State: OffsetState; type Offset: Offset;
/// Makes a new `Date` from year, month, day and the current offset. /// Makes a new `Date` from year, month, day and the current time zone.
/// 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 offset 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. /// Fails on the out-of-range date, invalid month and/or day.
@ -178,10 +178,10 @@ pub trait Offset: Sized {
self.ymd_opt(year, month, day).unwrap() self.ymd_opt(year, month, day).unwrap()
} }
/// Makes a new `Date` from year, month, day and the current offset. /// Makes a new `Date` from year, month, day and the current time zone.
/// 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 offset 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.
/// ///
/// Returns `None` on the out-of-range date, invalid month and/or day. /// Returns `None` on the out-of-range date, invalid month and/or day.
@ -192,10 +192,10 @@ pub trait Offset: Sized {
} }
} }
/// Makes a new `Date` from year, day of year (DOY or "ordinal") and the current offset. /// Makes a new `Date` from year, day of year (DOY or "ordinal") and the current time zone.
/// 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 offset 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. /// Fails on the out-of-range date and/or invalid DOY.
@ -203,10 +203,10 @@ pub trait Offset: Sized {
self.yo_opt(year, ordinal).unwrap() self.yo_opt(year, ordinal).unwrap()
} }
/// Makes a new `Date` from year, day of year (DOY or "ordinal") and the current offset. /// Makes a new `Date` from year, day of year (DOY or "ordinal") and the current time zone.
/// 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 offset 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.
/// ///
/// Returns `None` on the out-of-range date and/or invalid DOY. /// Returns `None` on the out-of-range date and/or invalid DOY.
@ -218,11 +218,11 @@ pub trait Offset: Sized {
} }
/// Makes a new `Date` from ISO week date (year and week number), day of the week (DOW) and /// Makes a new `Date` from ISO week date (year and week number), day of the week (DOW) and
/// the current offset. /// the current time zone.
/// 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 `Date` may have a different year from the input year. /// The resulting `Date` may have a different year from the input year.
/// ///
/// The offset 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. /// Fails on the out-of-range date and/or invalid week number.
@ -231,11 +231,11 @@ pub trait Offset: Sized {
} }
/// Makes a new `Date` from ISO week date (year and week number), day of the week (DOW) and /// Makes a new `Date` from ISO week date (year and week number), day of the week (DOW) and
/// the current offset. /// the current time zone.
/// 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 `Date` may have a different year from the input year. /// The resulting `Date` may have a different year from the input year.
/// ///
/// The offset 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.
/// ///
/// Returns `None` on the out-of-range date and/or invalid week number. /// Returns `None` on the out-of-range date and/or invalid week number.
@ -246,14 +246,14 @@ pub trait Offset: Sized {
} }
} }
/// Makes a new `Time` from hour, minute, second and the current offset. /// Makes a new `Time` from hour, minute, second and the current time zone.
/// ///
/// Fails on invalid hour, minute and/or second. /// Fails on invalid hour, minute and/or second.
fn hms(&self, hour: u32, min: u32, sec: u32) -> Time<Self> { fn hms(&self, hour: u32, min: u32, sec: u32) -> Time<Self> {
self.hms_opt(hour, min, sec).unwrap() self.hms_opt(hour, min, sec).unwrap()
} }
/// Makes a new `Time` from hour, minute, second and the current offset. /// Makes a new `Time` from hour, minute, second and the current time zone.
/// ///
/// Returns `None` on invalid hour, minute and/or second. /// Returns `None` on invalid hour, minute and/or second.
fn hms_opt(&self, hour: u32, min: u32, sec: u32) -> LocalResult<Time<Self>> { fn hms_opt(&self, hour: u32, min: u32, sec: u32) -> LocalResult<Time<Self>> {
@ -263,7 +263,7 @@ pub trait Offset: Sized {
} }
} }
/// Makes a new `Time` from hour, minute, second, millisecond and the current offset. /// Makes a new `Time` from hour, minute, second, millisecond and the current time zone.
/// 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.
/// ///
/// Fails on invalid hour, minute, second and/or millisecond. /// Fails on invalid hour, minute, second and/or millisecond.
@ -271,7 +271,7 @@ pub trait Offset: Sized {
self.hms_milli_opt(hour, min, sec, milli).unwrap() self.hms_milli_opt(hour, min, sec, milli).unwrap()
} }
/// Makes a new `Time` from hour, minute, second, millisecond and the current offset. /// Makes a new `Time` from hour, minute, second, millisecond and the current time zone.
/// 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.
/// ///
/// Returns `None` on invalid hour, minute, second and/or millisecond. /// Returns `None` on invalid hour, minute, second and/or millisecond.
@ -282,7 +282,7 @@ pub trait Offset: Sized {
} }
} }
/// Makes a new `Time` from hour, minute, second, microsecond and the current offset. /// Makes a new `Time` from hour, minute, second, microsecond and the current time zone.
/// 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.
/// ///
/// Fails on invalid hour, minute, second and/or microsecond. /// Fails on invalid hour, minute, second and/or microsecond.
@ -290,7 +290,7 @@ pub trait Offset: Sized {
self.hms_micro_opt(hour, min, sec, micro).unwrap() self.hms_micro_opt(hour, min, sec, micro).unwrap()
} }
/// Makes a new `Time` from hour, minute, second, microsecond and the current offset. /// Makes a new `Time` from hour, minute, second, microsecond and the current time zone.
/// 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.
/// ///
/// Returns `None` on invalid hour, minute, second and/or microsecond. /// Returns `None` on invalid hour, minute, second and/or microsecond.
@ -301,7 +301,7 @@ pub trait Offset: Sized {
} }
} }
/// Makes a new `Time` from hour, minute, second, nanosecond and the current offset. /// Makes a new `Time` from hour, minute, second, nanosecond and the current time zone.
/// 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.
/// ///
/// Fails on invalid hour, minute, second and/or nanosecond. /// Fails on invalid hour, minute, second and/or nanosecond.
@ -309,7 +309,7 @@ pub trait Offset: Sized {
self.hms_nano_opt(hour, min, sec, nano).unwrap() self.hms_nano_opt(hour, min, sec, nano).unwrap()
} }
/// Makes a new `Time` from hour, minute, second, nanosecond and the current offset. /// Makes a new `Time` from hour, minute, second, nanosecond and the current time zone.
/// 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.
/// ///
/// Returns `None` on invalid hour, minute, second and/or nanosecond. /// Returns `None` on invalid hour, minute, second and/or nanosecond.
@ -320,64 +320,64 @@ pub trait Offset: Sized {
} }
} }
/// Reconstructs the offset from the offset state. /// Reconstructs the time zone from the offset.
fn from_state(state: &Self::State) -> Self; fn from_offset(offset: &Self::Offset) -> Self;
/// Creates the offset state(s) for given local `NaiveDate` if possible. /// Creates the offset(s) for given local `NaiveDate` if possible.
fn state_from_local_date(&self, local: &NaiveDate) -> LocalResult<Self::State>; fn offset_from_local_date(&self, local: &NaiveDate) -> LocalResult<Self::Offset>;
/// Creates the offset state(s) for given local `NaiveTime` if possible. /// Creates the offset(s) for given local `NaiveTime` if possible.
fn state_from_local_time(&self, local: &NaiveTime) -> LocalResult<Self::State>; fn offset_from_local_time(&self, local: &NaiveTime) -> LocalResult<Self::Offset>;
/// Creates the offset state(s) for given local `NaiveDateTime` if possible. /// Creates the offset(s) for given local `NaiveDateTime` if possible.
fn state_from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<Self::State>; fn offset_from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<Self::Offset>;
/// Converts the local `NaiveDate` to the timezone-aware `Date` if possible. /// Converts the local `NaiveDate` to the timezone-aware `Date` if possible.
fn from_local_date(&self, local: &NaiveDate) -> LocalResult<Date<Self>> { fn from_local_date(&self, local: &NaiveDate) -> LocalResult<Date<Self>> {
self.state_from_local_date(local).map(|state| { self.offset_from_local_date(local).map(|offset| {
Date::from_utc(*local - state.local_minus_utc(), state) Date::from_utc(*local - offset.local_minus_utc(), offset)
}) })
} }
/// Converts the local `NaiveTime` to the timezone-aware `Time` if possible. /// Converts the local `NaiveTime` to the timezone-aware `Time` if possible.
fn from_local_time(&self, local: &NaiveTime) -> LocalResult<Time<Self>> { fn from_local_time(&self, local: &NaiveTime) -> LocalResult<Time<Self>> {
self.state_from_local_time(local).map(|state| { self.offset_from_local_time(local).map(|offset| {
Time::from_utc(*local - state.local_minus_utc(), state) Time::from_utc(*local - offset.local_minus_utc(), offset)
}) })
} }
/// Converts the local `NaiveDateTime` to the timezone-aware `DateTime` if possible. /// Converts the local `NaiveDateTime` to the timezone-aware `DateTime` if possible.
fn from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<DateTime<Self>> { fn from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<DateTime<Self>> {
self.state_from_local_datetime(local).map(|state| { self.offset_from_local_datetime(local).map(|offset| {
DateTime::from_utc(*local - state.local_minus_utc(), state) DateTime::from_utc(*local - offset.local_minus_utc(), offset)
}) })
} }
/// Creates the offset state for given UTC `NaiveDate`. This cannot fail. /// Creates the offset for given UTC `NaiveDate`. This cannot fail.
fn state_from_utc_date(&self, utc: &NaiveDate) -> Self::State; fn offset_from_utc_date(&self, utc: &NaiveDate) -> Self::Offset;
/// Creates the offset state for given UTC `NaiveTime`. This cannot fail. /// Creates the offset for given UTC `NaiveTime`. This cannot fail.
fn state_from_utc_time(&self, utc: &NaiveTime) -> Self::State; fn offset_from_utc_time(&self, utc: &NaiveTime) -> Self::Offset;
/// Creates the offset state for given UTC `NaiveDateTime`. This cannot fail. /// Creates the offset for given UTC `NaiveDateTime`. This cannot fail.
fn state_from_utc_datetime(&self, utc: &NaiveDateTime) -> Self::State; fn offset_from_utc_datetime(&self, utc: &NaiveDateTime) -> Self::Offset;
/// Converts the UTC `NaiveDate` to the local time. /// Converts the UTC `NaiveDate` to the local time.
/// The UTC is continuous and thus this cannot fail (but can give the duplicate local time). /// The UTC is continuous and thus this cannot fail (but can give the duplicate local time).
fn from_utc_date(&self, utc: &NaiveDate) -> Date<Self> { fn from_utc_date(&self, utc: &NaiveDate) -> Date<Self> {
Date::from_utc(utc.clone(), self.state_from_utc_date(utc)) Date::from_utc(utc.clone(), self.offset_from_utc_date(utc))
} }
/// Converts the UTC `NaiveTime` to the local time. /// Converts the UTC `NaiveTime` to the local time.
/// The UTC is continuous and thus this cannot fail (but can give the duplicate local time). /// The UTC is continuous and thus this cannot fail (but can give the duplicate local time).
fn from_utc_time(&self, utc: &NaiveTime) -> Time<Self> { fn from_utc_time(&self, utc: &NaiveTime) -> Time<Self> {
Time::from_utc(utc.clone(), self.state_from_utc_time(utc)) Time::from_utc(utc.clone(), self.offset_from_utc_time(utc))
} }
/// Converts the UTC `NaiveDateTime` to the local time. /// Converts the UTC `NaiveDateTime` to the local time.
/// The UTC is continuous and thus this cannot fail (but can give the duplicate local time). /// The UTC is continuous and thus this cannot fail (but can give the duplicate local time).
fn from_utc_datetime(&self, utc: &NaiveDateTime) -> DateTime<Self> { fn from_utc_datetime(&self, utc: &NaiveDateTime) -> DateTime<Self> {
DateTime::from_utc(utc.clone(), self.state_from_utc_datetime(utc)) DateTime::from_utc(utc.clone(), self.offset_from_utc_datetime(utc))
} }
} }

View File

@ -15,10 +15,10 @@ use naive::time::NaiveTime;
use naive::datetime::NaiveDateTime; use naive::datetime::NaiveDateTime;
use date::Date; use date::Date;
use datetime::DateTime; use datetime::DateTime;
use super::{Offset, OffsetState, LocalResult}; use super::{TimeZone, Offset, LocalResult};
/// The UTC offset. This is the most efficient offset when you don't need the local time. /// 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 state (which is also a dummy type). /// It is also used as an offset (which is also a dummy type).
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
pub struct UTC; pub struct UTC;
@ -34,27 +34,27 @@ impl UTC {
} }
} }
impl Offset for UTC { impl TimeZone for UTC {
type State = UTC; type Offset = UTC;
fn from_state(_state: &UTC) -> UTC { UTC } fn from_offset(_state: &UTC) -> UTC { UTC }
fn state_from_local_date(&self, _local: &NaiveDate) -> LocalResult<UTC> { fn offset_from_local_date(&self, _local: &NaiveDate) -> LocalResult<UTC> {
LocalResult::Single(UTC) LocalResult::Single(UTC)
} }
fn state_from_local_time(&self, _local: &NaiveTime) -> LocalResult<UTC> { fn offset_from_local_time(&self, _local: &NaiveTime) -> LocalResult<UTC> {
LocalResult::Single(UTC) LocalResult::Single(UTC)
} }
fn state_from_local_datetime(&self, _local: &NaiveDateTime) -> LocalResult<UTC> { fn offset_from_local_datetime(&self, _local: &NaiveDateTime) -> LocalResult<UTC> {
LocalResult::Single(UTC) LocalResult::Single(UTC)
} }
fn state_from_utc_date(&self, _utc: &NaiveDate) -> UTC { UTC } fn offset_from_utc_date(&self, _utc: &NaiveDate) -> UTC { UTC }
fn state_from_utc_time(&self, _utc: &NaiveTime) -> UTC { UTC } fn offset_from_utc_time(&self, _utc: &NaiveTime) -> UTC { UTC }
fn state_from_utc_datetime(&self, _utc: &NaiveDateTime) -> UTC { UTC} fn offset_from_utc_datetime(&self, _utc: &NaiveDateTime) -> UTC { UTC}
} }
impl OffsetState for UTC { impl Offset for UTC {
fn local_minus_utc(&self) -> Duration { Duration::zero() } fn local_minus_utc(&self) -> Duration { Duration::zero() }
} }

View File

@ -3,7 +3,7 @@
// See README.md and LICENSE.txt for details. // See README.md and LICENSE.txt for details.
/*! /*!
* ISO 8601 time with timezone. * ISO 8601 time with time zone.
*/ */
use std::{fmt, hash}; use std::{fmt, hash};
@ -11,44 +11,44 @@ use std::cmp::Ordering;
use std::ops::{Add, Sub}; use std::ops::{Add, Sub};
use Timelike; use Timelike;
use offset::{Offset, OffsetState}; use offset::{TimeZone, Offset};
use duration::Duration; use duration::Duration;
use naive::time::NaiveTime; use naive::time::NaiveTime;
use format::DelayedFormat; use format::DelayedFormat;
/// ISO 8601 time with timezone. /// ISO 8601 time with timezone.
#[derive(Clone)] #[derive(Clone)]
pub struct Time<Off: Offset> { pub struct Time<Tz: TimeZone> {
time: NaiveTime, time: NaiveTime,
offset: Off::State, offset: Tz::Offset,
} }
impl<Off: Offset> Time<Off> { impl<Tz: TimeZone> Time<Tz> {
/// Makes a new `Time` with given *UTC* time and offset. /// Makes a new `Time` with given *UTC* time and offset.
/// The local time should be constructed via the `Offset` trait. /// The local time should be constructed via the `TimeZone` trait.
// //
// note: this constructor is purposedly not named to `new` to discourage the direct usage. // note: this constructor is purposedly not named to `new` to discourage the direct usage.
#[inline] #[inline]
pub fn from_utc(time: NaiveTime, offset: Off::State) -> Time<Off> { pub fn from_utc(time: NaiveTime, offset: Tz::Offset) -> Time<Tz> {
Time { time: time, offset: offset } Time { time: time, offset: offset }
} }
/// Retrieves an associated offset. /// Retrieves an associated offset from UTC.
#[inline] #[inline]
pub fn offset<'a>(&'a self) -> &'a Off::State { pub fn offset<'a>(&'a self) -> &'a Tz::Offset {
&self.offset &self.offset
} }
/// Retrieves an associated offset. /// Retrieves an associated time zone.
#[inline] #[inline]
pub fn timezone(&self) -> Off { pub fn timezone(&self) -> Tz {
Offset::from_state(&self.offset) TimeZone::from_offset(&self.offset)
} }
/// Changes the associated offset. /// Changes the associated time zone.
/// This does not change the actual `Time` (but will change the string representation). /// This does not change the actual `Time` (but will change the string representation).
#[inline] #[inline]
pub fn with_timezone<Off2: Offset>(&self, tz: &Off2) -> Time<Off2> { pub fn with_timezone<Tz2: TimeZone>(&self, tz: &Tz2) -> Time<Tz2> {
tz.from_utc_time(&self.time) tz.from_utc_time(&self.time)
} }
@ -66,12 +66,12 @@ impl<Off: Offset> Time<Off> {
} }
/// Maps the local time to other time with given conversion function. /// Maps the local time to other time with given conversion function.
fn map_local<Off: Offset, F>(t: &Time<Off>, mut f: F) -> Option<Time<Off>> fn map_local<Tz: TimeZone, F>(t: &Time<Tz>, mut f: F) -> Option<Time<Tz>>
where F: FnMut(NaiveTime) -> Option<NaiveTime> { where F: FnMut(NaiveTime) -> Option<NaiveTime> {
f(t.naive_local()).and_then(|time| t.timezone().from_local_time(&time).single()) f(t.naive_local()).and_then(|time| t.timezone().from_local_time(&time).single())
} }
impl<Off: Offset> Time<Off> where Off::State: fmt::Display { impl<Tz: TimeZone> Time<Tz> where Tz::Offset: fmt::Display {
/// Formats the time in the specified format string. /// Formats the time in the specified format string.
/// See the `format` module on the supported escape sequences. /// See the `format` module on the supported escape sequences.
#[inline] #[inline]
@ -80,29 +80,29 @@ impl<Off: Offset> Time<Off> where Off::State: fmt::Display {
} }
} }
impl<Off: Offset> Timelike for Time<Off> { impl<Tz: TimeZone> Timelike for Time<Tz> {
#[inline] fn hour(&self) -> u32 { self.naive_local().hour() } #[inline] fn hour(&self) -> u32 { self.naive_local().hour() }
#[inline] fn minute(&self) -> u32 { self.naive_local().minute() } #[inline] fn minute(&self) -> u32 { self.naive_local().minute() }
#[inline] fn second(&self) -> u32 { self.naive_local().second() } #[inline] fn second(&self) -> u32 { self.naive_local().second() }
#[inline] fn nanosecond(&self) -> u32 { self.naive_local().nanosecond() } #[inline] fn nanosecond(&self) -> u32 { self.naive_local().nanosecond() }
#[inline] #[inline]
fn with_hour(&self, hour: u32) -> Option<Time<Off>> { fn with_hour(&self, hour: u32) -> Option<Time<Tz>> {
map_local(self, |time| time.with_hour(hour)) map_local(self, |time| time.with_hour(hour))
} }
#[inline] #[inline]
fn with_minute(&self, min: u32) -> Option<Time<Off>> { fn with_minute(&self, min: u32) -> Option<Time<Tz>> {
map_local(self, |time| time.with_minute(min)) map_local(self, |time| time.with_minute(min))
} }
#[inline] #[inline]
fn with_second(&self, sec: u32) -> Option<Time<Off>> { fn with_second(&self, sec: u32) -> Option<Time<Tz>> {
map_local(self, |time| time.with_second(sec)) map_local(self, |time| time.with_second(sec))
} }
#[inline] #[inline]
fn with_nanosecond(&self, nano: u32) -> Option<Time<Off>> { fn with_nanosecond(&self, nano: u32) -> Option<Time<Tz>> {
map_local(self, |time| time.with_nanosecond(nano)) map_local(self, |time| time.with_nanosecond(nano))
} }
@ -110,55 +110,55 @@ impl<Off: Offset> Timelike for Time<Off> {
fn num_seconds_from_midnight(&self) -> u32 { self.naive_local().num_seconds_from_midnight() } fn num_seconds_from_midnight(&self) -> u32 { self.naive_local().num_seconds_from_midnight() }
} }
impl<Off: Offset, Off2: Offset> PartialEq<Time<Off2>> for Time<Off> { impl<Tz: TimeZone, Tz2: TimeZone> PartialEq<Time<Tz2>> for Time<Tz> {
fn eq(&self, other: &Time<Off2>) -> bool { self.time == other.time } fn eq(&self, other: &Time<Tz2>) -> bool { self.time == other.time }
} }
impl<Off: Offset> Eq for Time<Off> { impl<Tz: TimeZone> Eq for Time<Tz> {
} }
impl<Off: Offset> PartialOrd for Time<Off> { impl<Tz: TimeZone> PartialOrd for Time<Tz> {
fn partial_cmp(&self, other: &Time<Off>) -> Option<Ordering> { fn partial_cmp(&self, other: &Time<Tz>) -> Option<Ordering> {
self.time.partial_cmp(&other.time) self.time.partial_cmp(&other.time)
} }
} }
impl<Off: Offset> Ord for Time<Off> { impl<Tz: TimeZone> Ord for Time<Tz> {
fn cmp(&self, other: &Time<Off>) -> Ordering { self.time.cmp(&other.time) } fn cmp(&self, other: &Time<Tz>) -> Ordering { self.time.cmp(&other.time) }
} }
impl<Off: Offset, H: hash::Hasher + hash::Writer> hash::Hash<H> for Time<Off> { impl<Tz: TimeZone, H: hash::Hasher + hash::Writer> hash::Hash<H> for Time<Tz> {
fn hash(&self, state: &mut H) { self.time.hash(state) } fn hash(&self, state: &mut H) { self.time.hash(state) }
} }
impl<Off: Offset> Add<Duration> for Time<Off> { impl<Tz: TimeZone> Add<Duration> for Time<Tz> {
type Output = Time<Off>; type Output = Time<Tz>;
fn add(self, rhs: Duration) -> Time<Off> { fn add(self, rhs: Duration) -> Time<Tz> {
Time { time: self.time + rhs, offset: self.offset } Time { time: self.time + rhs, offset: self.offset }
} }
} }
impl<Off: Offset, Off2: Offset> Sub<Time<Off2>> for Time<Off> { impl<Tz: TimeZone, Tz2: TimeZone> Sub<Time<Tz2>> for Time<Tz> {
type Output = Duration; type Output = Duration;
fn sub(self, rhs: Time<Off2>) -> Duration { self.time - rhs.time } fn sub(self, rhs: Time<Tz2>) -> Duration { self.time - rhs.time }
} }
impl<Off: Offset> Sub<Duration> for Time<Off> { impl<Tz: TimeZone> Sub<Duration> for Time<Tz> {
type Output = Time<Off>; type Output = Time<Tz>;
#[inline] #[inline]
fn sub(self, rhs: Duration) -> Time<Off> { self.add(-rhs) } fn sub(self, rhs: Duration) -> Time<Tz> { self.add(-rhs) }
} }
impl<Off: Offset> fmt::Debug for Time<Off> { impl<Tz: TimeZone> fmt::Debug for Time<Tz> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}{:?}", self.naive_local(), self.offset) write!(f, "{:?}{:?}", self.naive_local(), self.offset)
} }
} }
impl<Off: Offset> fmt::Display for Time<Off> where Off::State: fmt::Display { impl<Tz: TimeZone> fmt::Display for Time<Tz> where Tz::Offset: fmt::Display {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}{}", self.naive_local(), self.offset) write!(f, "{}{}", self.naive_local(), self.offset)
} }