mass renaming from offset/state to timezone/offset.
This commit is contained in:
parent
e43cb62f10
commit
a4f5d19d24
25
README.md
25
README.md
|
@ -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).
|
||||
|
||||
|
|
134
src/date.rs
134
src/date.rs
|
@ -3,7 +3,7 @@
|
|||
// 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};
|
||||
|
@ -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;
|
||||
|
@ -20,11 +20,11 @@ use naive::time::NaiveTime;
|
|||
use datetime::DateTime;
|
||||
use format::DelayedFormat;
|
||||
|
||||
/// ISO 8601 calendar date with timezone.
|
||||
/// 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) }
|
||||
}
|
||||
|
||||
|
|
102
src/datetime.rs
102
src/datetime.rs
|
@ -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,39 +11,39 @@ 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;
|
||||
use date::Date;
|
||||
use format::DelayedFormat;
|
||||
|
||||
/// ISO 8601 combined date and time with timezone.
|
||||
/// 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;
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
}
|
||||
|
|
17
src/lib.rs
17
src/lib.rs
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 Offset for FixedOffset {
|
||||
type State = FixedOffset;
|
||||
impl TimeZone for 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())
|
||||
}
|
||||
fn state_from_local_time(&self, _local: &NaiveTime) -> LocalResult<FixedOffset> {
|
||||
fn offset_from_local_time(&self, _local: &NaiveTime) -> LocalResult<FixedOffset> {
|
||||
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())
|
||||
}
|
||||
|
||||
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() }
|
||||
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 OffsetState for FixedOffset {
|
||||
impl Offset for FixedOffset {
|
||||
fn local_minus_utc(&self) -> Duration { Duration::seconds(self.local_minus_utc as i64) }
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 Offset for UTC {
|
||||
type State = UTC;
|
||||
impl TimeZone for 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)
|
||||
}
|
||||
fn state_from_local_time(&self, _local: &NaiveTime) -> LocalResult<UTC> {
|
||||
fn offset_from_local_time(&self, _local: &NaiveTime) -> LocalResult<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)
|
||||
}
|
||||
|
||||
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}
|
||||
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 OffsetState for UTC {
|
||||
impl Offset for UTC {
|
||||
fn local_minus_utc(&self) -> Duration { Duration::zero() }
|
||||
}
|
||||
|
||||
|
|
78
src/time.rs
78
src/time.rs
|
@ -3,7 +3,7 @@
|
|||
// See README.md and LICENSE.txt for details.
|
||||
|
||||
/*!
|
||||
* ISO 8601 time with timezone.
|
||||
* ISO 8601 time with time zone.
|
||||
*/
|
||||
|
||||
use std::{fmt, hash};
|
||||
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue