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.
`DateTime`, among others, is timezone-aware and
must be constructed from the timezone object (`Offset`).
`DateTime`s with different offsets do not mix, but can be converted to each other.
must be constructed from the `TimeZone` object.
`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()`)
or in the local timezone (`Local::now()`).
~~~~ {.rust}
use chrono::{UTC, Local, DateTime};
use chrono::*;
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`
@ -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.
~~~~ {.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`
// 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:
~~~~ {.rust}
use chrono::{UTC, Local, Datelike, Timelike, Weekday, Duration};
use chrono::*;
// assume this returned `2014-11-28T21:45:59.324310806+09:00`:
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.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.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)
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.
~~~~ {.rust}
use chrono::{UTC, Offset};
use chrono::*;
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");
@ -132,12 +133,12 @@ assert_eq!(format!("{:?}", dt), "2014-11-28T12:00:09Z");
### Individual date and 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`
whenever appropriate.
~~~~ {.rust}
use chrono::{UTC, Local, Offset, LocalResult, Datelike, Weekday};
use chrono::*;
assert_eq!(UTC::today(), UTC::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.
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.
## 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
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

@ -12,7 +12,7 @@ use std::ops::{Add, Sub};
use {Weekday, Datelike};
use duration::Duration;
use offset::{Offset, OffsetState};
use offset::{TimeZone, Offset};
use offset::utc::UTC;
use naive;
use naive::date::NaiveDate;
@ -22,9 +22,9 @@ use format::DelayedFormat;
/// ISO 8601 calendar date with time zone.
#[derive(Clone)]
pub struct Date<Off: Offset> {
pub struct Date<Tz: TimeZone> {
date: NaiveDate,
offset: Off::State,
offset: Tz::Offset,
}
/// The minimum possible `Date`.
@ -32,13 +32,13 @@ pub const MIN: Date<UTC> = Date { date: naive::date::MIN, offset: UTC };
/// The maximum possible `Date`.
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.
/// 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.
#[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 }
}
@ -47,7 +47,7 @@ impl<Off: Offset> Date<Off> {
///
/// Fails on invalid datetime.
#[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);
self.timezone().from_local_datetime(&localdt).single()
}
@ -57,7 +57,7 @@ impl<Off: Offset> Date<Off> {
///
/// Fails on invalid hour, minute and/or second.
#[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")
}
@ -66,7 +66,7 @@ impl<Off: Offset> Date<Off> {
///
/// Returns `None` on invalid hour, minute and/or second.
#[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))
}
@ -76,7 +76,7 @@ impl<Off: Offset> Date<Off> {
///
/// Fails on invalid hour, minute, second and/or millisecond.
#[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")
}
@ -87,7 +87,7 @@ impl<Off: Offset> Date<Off> {
/// Returns `None` on invalid hour, minute, second and/or millisecond.
#[inline]
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))
}
@ -97,7 +97,7 @@ impl<Off: Offset> Date<Off> {
///
/// Fails on invalid hour, minute, second and/or microsecond.
#[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")
}
@ -108,7 +108,7 @@ impl<Off: Offset> Date<Off> {
/// Returns `None` on invalid hour, minute, second and/or microsecond.
#[inline]
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))
}
@ -118,7 +118,7 @@ impl<Off: Offset> Date<Off> {
///
/// Fails on invalid hour, minute, second and/or nanosecond.
#[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")
}
@ -129,7 +129,7 @@ impl<Off: Offset> Date<Off> {
/// Returns `None` on invalid hour, minute, second and/or nanosecond.
#[inline]
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))
}
@ -137,7 +137,7 @@ impl<Off: Offset> Date<Off> {
///
/// Fails when `self` is the last representable date.
#[inline]
pub fn succ(&self) -> Date<Off> {
pub fn succ(&self) -> Date<Tz> {
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.
#[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()))
}
@ -153,7 +153,7 @@ impl<Off: Offset> Date<Off> {
///
/// Fails when `self` is the first representable date.
#[inline]
pub fn pred(&self) -> Date<Off> {
pub fn pred(&self) -> Date<Tz> {
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.
#[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()))
}
/// Retrieves an associated offset state.
/// Retrieves an associated offset from UTC.
#[inline]
pub fn offset<'a>(&'a self) -> &'a Off::State {
pub fn offset<'a>(&'a self) -> &'a Tz::Offset {
&self.offset
}
/// Retrieves an associated offset.
/// Retrieves an associated time zone.
#[inline]
pub fn timezone(&self) -> Off {
Offset::from_state(&self.offset)
pub fn timezone(&self) -> Tz {
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).
#[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)
}
@ -198,12 +198,12 @@ impl<Off: Offset> Date<Off> {
}
/// 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> {
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.
/// See the `format` module on the supported escape sequences.
#[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 month(&self) -> u32 { self.naive_local().month() }
#[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 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))
}
#[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))
}
#[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))
}
#[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))
}
#[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))
}
#[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))
}
#[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))
}
}
impl<Off: Offset, Off2: Offset> PartialEq<Date<Off2>> for Date<Off> {
fn eq(&self, other: &Date<Off2>) -> bool { self.date == other.date }
impl<Tz: TimeZone, Tz2: TimeZone> PartialEq<Date<Tz2>> for Date<Tz> {
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> {
fn partial_cmp(&self, other: &Date<Off>) -> Option<Ordering> {
impl<Tz: TimeZone> PartialOrd for Date<Tz> {
fn partial_cmp(&self, other: &Date<Tz>) -> Option<Ordering> {
self.date.partial_cmp(&other.date)
}
}
impl<Off: Offset> Ord for Date<Off> {
fn cmp(&self, other: &Date<Off>) -> Ordering { self.date.cmp(&other.date) }
impl<Tz: TimeZone> Ord for Date<Tz> {
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) }
}
impl<Off: Offset> Add<Duration> for Date<Off> {
type Output = Date<Off>;
impl<Tz: TimeZone> Add<Duration> for Date<Tz> {
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 }
}
}
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;
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> {
type Output = Date<Off>;
impl<Tz: TimeZone> Sub<Duration> for Date<Tz> {
type Output = Date<Tz>;
#[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 {
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 {
write!(f, "{}{}", self.naive_local(), self.offset)
}
@ -321,7 +321,7 @@ mod tests {
use naive::date::NaiveDate;
use naive::time::NaiveTime;
use naive::datetime::NaiveDateTime;
use offset::{Offset, OffsetState, LocalResult};
use offset::{TimeZone, Offset, LocalResult};
#[derive(Copy, Clone, PartialEq, Eq)]
struct UTC1y; // same to UTC but with an offset of 365 days
@ -329,27 +329,27 @@ mod tests {
#[derive(Copy, Clone, PartialEq, Eq)]
struct OneYear;
impl Offset for UTC1y {
type State = OneYear;
impl TimeZone for UTC1y {
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)
}
fn state_from_local_time(&self, _local: &NaiveTime) -> LocalResult<OneYear> {
fn offset_from_local_time(&self, _local: &NaiveTime) -> LocalResult<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)
}
fn state_from_utc_date(&self, _utc: &NaiveDate) -> OneYear { OneYear }
fn state_from_utc_time(&self, _utc: &NaiveTime) -> OneYear { OneYear }
fn state_from_utc_datetime(&self, _utc: &NaiveDateTime) -> OneYear { OneYear }
fn offset_from_utc_date(&self, _utc: &NaiveDate) -> OneYear { OneYear }
fn offset_from_utc_time(&self, _utc: &NaiveTime) -> 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) }
}

View File

@ -3,7 +3,7 @@
// 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};
@ -11,7 +11,7 @@ use std::cmp::Ordering;
use std::ops::{Add, Sub};
use {Weekday, Timelike, Datelike};
use offset::{Offset, OffsetState};
use offset::{TimeZone, Offset};
use duration::Duration;
use naive::datetime::NaiveDateTime;
use time::Time;
@ -20,30 +20,30 @@ use format::DelayedFormat;
/// ISO 8601 combined date and time with time zone.
#[derive(Clone)]
pub struct DateTime<Off: Offset> {
pub struct DateTime<Tz: TimeZone> {
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.
/// 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.
#[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 }
}
/// Retrieves a date component.
#[inline]
pub fn date(&self) -> Date<Off> {
pub fn date(&self) -> Date<Tz> {
Date::from_utc(self.datetime.date().clone(), self.offset.clone())
}
/// Retrieves a time component.
#[inline]
pub fn time(&self) -> Time<Off> {
pub fn time(&self) -> Time<Tz> {
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()
}
/// Retrieves an associated offset state.
/// Retrieves an associated offset from UTC.
#[inline]
pub fn offset<'a>(&'a self) -> &'a Off::State {
pub fn offset<'a>(&'a self) -> &'a Tz::Offset {
&self.offset
}
/// Retrieves an associated offset.
/// Retrieves an associated time zone.
#[inline]
pub fn timezone(&self) -> Off {
Offset::from_state(&self.offset)
pub fn timezone(&self) -> Tz {
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).
#[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)
}
@ -86,12 +86,12 @@ impl<Off: Offset> DateTime<Off> {
}
/// 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> {
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.
/// See the `format` module on the supported escape sequences.
#[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 month(&self) -> u32 { self.naive_local().month() }
#[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 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))
}
#[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))
}
#[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))
}
#[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))
}
#[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))
}
#[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))
}
#[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))
}
}
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 minute(&self) -> u32 { self.naive_local().minute() }
#[inline] fn second(&self) -> u32 { self.naive_local().second() }
#[inline] fn nanosecond(&self) -> u32 { self.naive_local().nanosecond() }
#[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))
}
#[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))
}
#[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))
}
#[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))
}
}
impl<Off: Offset, Off2: Offset> PartialEq<DateTime<Off2>> for DateTime<Off> {
fn eq(&self, other: &DateTime<Off2>) -> bool { self.datetime == other.datetime }
impl<Tz: TimeZone, Tz2: TimeZone> PartialEq<DateTime<Tz2>> for DateTime<Tz> {
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> {
fn partial_cmp(&self, other: &DateTime<Off>) -> Option<Ordering> {
impl<Tz: TimeZone> PartialOrd for DateTime<Tz> {
fn partial_cmp(&self, other: &DateTime<Tz>) -> Option<Ordering> {
self.datetime.partial_cmp(&other.datetime)
}
}
impl<Off: Offset> Ord for DateTime<Off> {
fn cmp(&self, other: &DateTime<Off>) -> Ordering { self.datetime.cmp(&other.datetime) }
impl<Tz: TimeZone> Ord for DateTime<Tz> {
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) }
}
impl<Off: Offset> Add<Duration> for DateTime<Off> {
type Output = DateTime<Off>;
impl<Tz: TimeZone> Add<Duration> for DateTime<Tz> {
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 }
}
}
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;
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> {
type Output = DateTime<Off>;
impl<Tz: TimeZone> Sub<Duration> for DateTime<Tz> {
type Output = DateTime<Tz>;
#[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 {
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 {
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 {
use {Datelike};
use duration::Duration;
use offset::Offset;
use offset::TimeZone;
use offset::utc::UTC;
use offset::local::Local;
use offset::fixed::FixedOffset;

View File

@ -10,7 +10,7 @@ use std::fmt;
use {Datelike, Timelike};
use duration::Duration;
use offset::OffsetState;
use offset::Offset;
use naive::date::NaiveDate;
use naive::time::NaiveTime;
@ -198,11 +198,11 @@ impl<'a> DelayedFormat<'a> {
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>,
state: &Off, fmt: &'a str) -> DelayedFormat<'a>
where Off: OffsetState + fmt::Display {
let name_and_diff = (state.to_string(), state.local_minus_utc());
offset: &Off, fmt: &'a str) -> DelayedFormat<'a>
where Off: Offset + fmt::Display {
let name_and_diff = (offset.to_string(), offset.local_minus_utc());
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.
`DateTime`, among others, is timezone-aware and
must be constructed from the timezone object (`Offset`).
`DateTime`s with different offsets do not mix, but can be converted to each other.
must be constructed from the `TimeZone` object.
`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()`)
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.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.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)
@ -132,7 +133,7 @@ assert_eq!(format!("{:?}", dt), "2014-11-28T12:00:09Z");
### Individual date and 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`
whenever appropriate.
@ -157,7 +158,7 @@ Chrono provides naive counterparts to `Date`, `Time` and `DateTime`
as `NaiveDate`, `NaiveTime` and `NaiveDateTime` respectively.
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.
## 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
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;
pub use duration::Duration;
pub use offset::{Offset, OffsetState, LocalResult};
pub use offset::{TimeZone, Offset, LocalResult};
pub use offset::utc::UTC;
pub use offset::fixed::FixedOffset;
pub use offset::local::Local;
@ -214,7 +215,7 @@ pub mod offset;
pub mod naive {
//! 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.
pub mod date;
pub mod time;

View File

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

View File

@ -13,9 +13,9 @@ use duration::Duration;
use naive::date::NaiveDate;
use naive::time::NaiveTime;
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)]
pub struct FixedOffset {
local_minus_utc: i32,
@ -63,27 +63,27 @@ impl FixedOffset {
}
}
impl TimeZone for FixedOffset {
type Offset = FixedOffset;
fn from_offset(offset: &FixedOffset) -> FixedOffset { offset.clone() }
fn offset_from_local_date(&self, _local: &NaiveDate) -> LocalResult<FixedOffset> {
LocalResult::Single(self.clone())
}
fn offset_from_local_time(&self, _local: &NaiveTime) -> LocalResult<FixedOffset> {
LocalResult::Single(self.clone())
}
fn offset_from_local_datetime(&self, _local: &NaiveDateTime) -> LocalResult<FixedOffset> {
LocalResult::Single(self.clone())
}
fn offset_from_utc_date(&self, _utc: &NaiveDate) -> FixedOffset { self.clone() }
fn offset_from_utc_time(&self, _utc: &NaiveTime) -> FixedOffset { self.clone() }
fn offset_from_utc_datetime(&self, _utc: &NaiveDateTime) -> FixedOffset { self.clone() }
}
impl Offset for FixedOffset {
type State = FixedOffset;
fn from_state(state: &FixedOffset) -> FixedOffset { state.clone() }
fn state_from_local_date(&self, _local: &NaiveDate) -> LocalResult<FixedOffset> {
LocalResult::Single(self.clone())
}
fn state_from_local_time(&self, _local: &NaiveTime) -> LocalResult<FixedOffset> {
LocalResult::Single(self.clone())
}
fn state_from_local_datetime(&self, _local: &NaiveDateTime) -> LocalResult<FixedOffset> {
LocalResult::Single(self.clone())
}
fn state_from_utc_date(&self, _utc: &NaiveDate) -> FixedOffset { self.clone() }
fn state_from_utc_time(&self, _utc: &NaiveTime) -> FixedOffset { self.clone() }
fn state_from_utc_datetime(&self, _utc: &NaiveDateTime) -> FixedOffset { self.clone() }
}
impl OffsetState for FixedOffset {
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 time::Time;
use datetime::DateTime;
use super::{Offset, LocalResult};
use super::{TimeZone, LocalResult};
use super::fixed::FixedOffset;
/// Converts a `time::Tm` struct into the timezone-aware `DateTime`.
@ -70,29 +70,29 @@ impl Local {
}
}
impl Offset for Local {
type State = FixedOffset;
impl TimeZone for Local {
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
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())
}
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())
}
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())
}
fn state_from_utc_date(&self, utc: &NaiveDate) -> FixedOffset {
fn offset_from_utc_date(&self, utc: &NaiveDate) -> FixedOffset {
*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()
}
fn state_from_utc_datetime(&self, utc: &NaiveDateTime) -> FixedOffset {
fn offset_from_utc_datetime(&self, utc: &NaiveDateTime) -> FixedOffset {
*self.from_utc_datetime(utc).offset()
}

View File

@ -3,21 +3,21 @@
// 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>`
* 2. Converting the UTC `NaiveDateTime` to `DateTime<Offset>`
* 3. Converting `DateTime<Offset>` to the local `NaiveDateTime`
* 1. Converting the local `NaiveDateTime` to `DateTime<Tz>`
* 2. Converting the UTC `NaiveDateTime` to `DateTime<Tz>`
* 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
* which implements `OffsetState` (which then passed to `Offset` for actual implementations).
* Technically speaking `Offset` has a total knowledge about given timescale,
* but `OffsetState` is used as a cache to avoid the repeated conversion
* which implements `Offset` (which then passed to `TimeZone` for actual implementations).
* Technically speaking `TimeZone` has a total knowledge about given timescale,
* but `Offset` is used as a cache to avoid the repeated conversion
* 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;
@ -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`.
/// The offset in the current date is preserved.
///
/// Propagates any error. Ambiguous result would be discarded.
#[inline]
pub fn and_time(self, time: NaiveTime) -> LocalResult<DateTime<Off>> {
pub fn and_time(self, time: NaiveTime) -> LocalResult<DateTime<Tz>> {
match self {
LocalResult::Single(d) => d.and_time(time)
.map_or(LocalResult::None, LocalResult::Single),
@ -89,7 +89,7 @@ impl<Off: Offset> LocalResult<Date<Off>> {
///
/// Propagates any error. Ambiguous result would be discarded.
#[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 {
LocalResult::Single(d) => d.and_hms_opt(hour, min, sec)
.map_or(LocalResult::None, LocalResult::Single),
@ -104,7 +104,7 @@ impl<Off: Offset> LocalResult<Date<Off>> {
/// Propagates any error. Ambiguous result would be discarded.
#[inline]
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 {
LocalResult::Single(d) => d.and_hms_milli_opt(hour, min, sec, milli)
.map_or(LocalResult::None, LocalResult::Single),
@ -119,7 +119,7 @@ impl<Off: Offset> LocalResult<Date<Off>> {
/// Propagates any error. Ambiguous result would be discarded.
#[inline]
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 {
LocalResult::Single(d) => d.and_hms_micro_opt(hour, min, sec, micro)
.map_or(LocalResult::None, LocalResult::Single),
@ -134,7 +134,7 @@ impl<Off: Offset> LocalResult<Date<Off>> {
/// Propagates any error. Ambiguous result would be discarded.
#[inline]
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 {
LocalResult::Single(d) => d.and_hms_nano_opt(hour, min, sec, nano)
.map_or(LocalResult::None, LocalResult::Single),
@ -157,20 +157,20 @@ impl<T: fmt::Debug> LocalResult<T> {
}
}
/// The offset state.
pub trait OffsetState: Sized + Clone + fmt::Debug {
/// Returns the offset from UTC to the local time stored in the offset state.
/// The offset from the local time to UTC.
pub trait Offset: Sized + Clone + fmt::Debug {
/// Returns the offset from UTC to the local time stored.
fn local_minus_utc(&self) -> Duration;
}
/// The offset from the local time to UTC.
pub trait Offset: Sized {
type State: OffsetState;
/// The time zone.
pub trait TimeZone: Sized {
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.
///
/// 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.
///
/// 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()
}
/// 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.
///
/// 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.
///
/// 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.
///
/// 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.
///
/// 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()
}
/// 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.
///
/// 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.
///
/// 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
/// the current offset.
/// the current time zone.
/// 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 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.
///
/// 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
/// the current offset.
/// the current time zone.
/// 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 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.
///
/// 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.
fn hms(&self, hour: u32, min: u32, sec: u32) -> Time<Self> {
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.
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.
///
/// 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()
}
/// 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.
///
/// 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.
///
/// 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()
}
/// 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.
///
/// 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.
///
/// 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()
}
/// 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.
///
/// 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.
fn from_state(state: &Self::State) -> Self;
/// Reconstructs the time zone from the offset.
fn from_offset(offset: &Self::Offset) -> Self;
/// Creates the offset state(s) for given local `NaiveDate` if possible.
fn state_from_local_date(&self, local: &NaiveDate) -> LocalResult<Self::State>;
/// Creates the offset(s) for given local `NaiveDate` if possible.
fn offset_from_local_date(&self, local: &NaiveDate) -> LocalResult<Self::Offset>;
/// Creates the offset state(s) for given local `NaiveTime` if possible.
fn state_from_local_time(&self, local: &NaiveTime) -> LocalResult<Self::State>;
/// Creates the offset(s) for given local `NaiveTime` if possible.
fn offset_from_local_time(&self, local: &NaiveTime) -> LocalResult<Self::Offset>;
/// Creates the offset state(s) for given local `NaiveDateTime` if possible.
fn state_from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<Self::State>;
/// Creates the offset(s) for given local `NaiveDateTime` if possible.
fn offset_from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<Self::Offset>;
/// Converts the local `NaiveDate` to the timezone-aware `Date` if possible.
fn from_local_date(&self, local: &NaiveDate) -> LocalResult<Date<Self>> {
self.state_from_local_date(local).map(|state| {
Date::from_utc(*local - state.local_minus_utc(), state)
self.offset_from_local_date(local).map(|offset| {
Date::from_utc(*local - offset.local_minus_utc(), offset)
})
}
/// Converts the local `NaiveTime` to the timezone-aware `Time` if possible.
fn from_local_time(&self, local: &NaiveTime) -> LocalResult<Time<Self>> {
self.state_from_local_time(local).map(|state| {
Time::from_utc(*local - state.local_minus_utc(), state)
self.offset_from_local_time(local).map(|offset| {
Time::from_utc(*local - offset.local_minus_utc(), offset)
})
}
/// Converts the local `NaiveDateTime` to the timezone-aware `DateTime` if possible.
fn from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<DateTime<Self>> {
self.state_from_local_datetime(local).map(|state| {
DateTime::from_utc(*local - state.local_minus_utc(), state)
self.offset_from_local_datetime(local).map(|offset| {
DateTime::from_utc(*local - offset.local_minus_utc(), offset)
})
}
/// Creates the offset state for given UTC `NaiveDate`. This cannot fail.
fn state_from_utc_date(&self, utc: &NaiveDate) -> Self::State;
/// Creates the offset for given UTC `NaiveDate`. This cannot fail.
fn offset_from_utc_date(&self, utc: &NaiveDate) -> Self::Offset;
/// Creates the offset state for given UTC `NaiveTime`. This cannot fail.
fn state_from_utc_time(&self, utc: &NaiveTime) -> Self::State;
/// Creates the offset for given UTC `NaiveTime`. This cannot fail.
fn offset_from_utc_time(&self, utc: &NaiveTime) -> Self::Offset;
/// Creates the offset state for given UTC `NaiveDateTime`. This cannot fail.
fn state_from_utc_datetime(&self, utc: &NaiveDateTime) -> Self::State;
/// Creates the offset for given UTC `NaiveDateTime`. This cannot fail.
fn offset_from_utc_datetime(&self, utc: &NaiveDateTime) -> Self::Offset;
/// Converts the UTC `NaiveDate` to the 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> {
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.
/// 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> {
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.
/// 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> {
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 date::Date;
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.
/// It is also used as an offset state (which is also a dummy type).
/// 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).
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct UTC;
@ -34,27 +34,27 @@ impl UTC {
}
}
impl TimeZone for UTC {
type Offset = UTC;
fn from_offset(_state: &UTC) -> UTC { UTC }
fn offset_from_local_date(&self, _local: &NaiveDate) -> LocalResult<UTC> {
LocalResult::Single(UTC)
}
fn offset_from_local_time(&self, _local: &NaiveTime) -> LocalResult<UTC> {
LocalResult::Single(UTC)
}
fn offset_from_local_datetime(&self, _local: &NaiveDateTime) -> LocalResult<UTC> {
LocalResult::Single(UTC)
}
fn offset_from_utc_date(&self, _utc: &NaiveDate) -> UTC { UTC }
fn offset_from_utc_time(&self, _utc: &NaiveTime) -> UTC { UTC }
fn offset_from_utc_datetime(&self, _utc: &NaiveDateTime) -> UTC { UTC}
}
impl Offset for UTC {
type State = UTC;
fn from_state(_state: &UTC) -> UTC { UTC }
fn state_from_local_date(&self, _local: &NaiveDate) -> LocalResult<UTC> {
LocalResult::Single(UTC)
}
fn state_from_local_time(&self, _local: &NaiveTime) -> LocalResult<UTC> {
LocalResult::Single(UTC)
}
fn state_from_local_datetime(&self, _local: &NaiveDateTime) -> LocalResult<UTC> {
LocalResult::Single(UTC)
}
fn state_from_utc_date(&self, _utc: &NaiveDate) -> UTC { UTC }
fn state_from_utc_time(&self, _utc: &NaiveTime) -> UTC { UTC }
fn state_from_utc_datetime(&self, _utc: &NaiveDateTime) -> UTC { UTC}
}
impl OffsetState for UTC {
fn local_minus_utc(&self) -> Duration { Duration::zero() }
}

View File

@ -11,44 +11,44 @@ use std::cmp::Ordering;
use std::ops::{Add, Sub};
use Timelike;
use offset::{Offset, OffsetState};
use offset::{TimeZone, Offset};
use duration::Duration;
use naive::time::NaiveTime;
use format::DelayedFormat;
/// ISO 8601 time with timezone.
#[derive(Clone)]
pub struct Time<Off: Offset> {
pub struct Time<Tz: TimeZone> {
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.
/// 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.
#[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 }
}
/// Retrieves an associated offset.
/// Retrieves an associated offset from UTC.
#[inline]
pub fn offset<'a>(&'a self) -> &'a Off::State {
pub fn offset<'a>(&'a self) -> &'a Tz::Offset {
&self.offset
}
/// Retrieves an associated offset.
/// Retrieves an associated time zone.
#[inline]
pub fn timezone(&self) -> Off {
Offset::from_state(&self.offset)
pub fn timezone(&self) -> Tz {
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).
#[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)
}
@ -66,12 +66,12 @@ impl<Off: Offset> Time<Off> {
}
/// 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> {
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.
/// See the `format` module on the supported escape sequences.
#[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 minute(&self) -> u32 { self.naive_local().minute() }
#[inline] fn second(&self) -> u32 { self.naive_local().second() }
#[inline] fn nanosecond(&self) -> u32 { self.naive_local().nanosecond() }
#[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))
}
#[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))
}
#[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))
}
#[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))
}
@ -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() }
}
impl<Off: Offset, Off2: Offset> PartialEq<Time<Off2>> for Time<Off> {
fn eq(&self, other: &Time<Off2>) -> bool { self.time == other.time }
impl<Tz: TimeZone, Tz2: TimeZone> PartialEq<Time<Tz2>> for Time<Tz> {
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> {
fn partial_cmp(&self, other: &Time<Off>) -> Option<Ordering> {
impl<Tz: TimeZone> PartialOrd for Time<Tz> {
fn partial_cmp(&self, other: &Time<Tz>) -> Option<Ordering> {
self.time.partial_cmp(&other.time)
}
}
impl<Off: Offset> Ord for Time<Off> {
fn cmp(&self, other: &Time<Off>) -> Ordering { self.time.cmp(&other.time) }
impl<Tz: TimeZone> Ord for Time<Tz> {
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) }
}
impl<Off: Offset> Add<Duration> for Time<Off> {
type Output = Time<Off>;
impl<Tz: TimeZone> Add<Duration> for Time<Tz> {
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 }
}
}
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;
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> {
type Output = Time<Off>;
impl<Tz: TimeZone> Sub<Duration> for Time<Tz> {
type Output = Time<Tz>;
#[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 {
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 {
write!(f, "{}{}", self.naive_local(), self.offset)
}