removed timezone-aware `Time` type.

`Time` with an associated time zone is in principle possible, but
in practice it can only meaningfully constructed from an existing
`DateTime`. this makes it hard to implement other operations
natural to `NaiveTime` for `Time` (e.g. `with_*` methods), so
we simply let it go.

migration path: if you *do* happen to use `Time`, don't panic!
every operation possible to `Time` is much more possible to
`NaiveTime`. if you have to deal with a local time, first combine
it with a `NaiveDate`, convert it via `TimeZone::from_local_datetime`
then extract `Time` part again.
This commit is contained in:
Kang Seonghoon 2015-02-19 04:17:27 +09:00
parent e997403c10
commit f39b13a14c
8 changed files with 6 additions and 301 deletions

View File

@ -348,7 +348,6 @@ mod tests {
use duration::Duration;
use naive::date::NaiveDate;
use naive::time::NaiveTime;
use naive::datetime::NaiveDateTime;
use offset::{TimeZone, Offset, LocalResult};
@ -366,15 +365,11 @@ mod tests {
fn offset_from_local_date(&self, _local: &NaiveDate) -> LocalResult<OneYear> {
LocalResult::Single(OneYear)
}
fn offset_from_local_time(&self, _local: &NaiveTime) -> LocalResult<OneYear> {
LocalResult::Single(OneYear)
}
fn offset_from_local_datetime(&self, _local: &NaiveDateTime) -> LocalResult<OneYear> {
LocalResult::Single(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 }
}

View File

@ -16,8 +16,8 @@ use offset::utc::UTC;
use offset::local::Local;
use offset::fixed::FixedOffset;
use duration::Duration;
use naive::time::NaiveTime;
use naive::datetime::NaiveDateTime;
use time::Time;
use date::Date;
use format::{Item, Numeric, Pad, Fixed};
use format::{parse, Parsed, ParseError, ParseResult, DelayedFormat, StrftimeItems};
@ -46,9 +46,10 @@ impl<Tz: TimeZone> DateTime<Tz> {
}
/// Retrieves a time component.
/// Unlike `date`, this is not associated to the time zone.
#[inline]
pub fn time(&self) -> Time<Tz> {
Time::from_utc(self.datetime.time().clone(), self.offset.clone())
pub fn time(&self) -> NaiveTime {
self.datetime.time().clone()
}
/// Returns the number of non-leap seconds since January 1, 1970 0:00:00 UTC

View File

@ -214,7 +214,8 @@ assert_eq!(Local::today(), Local::now().date());
assert_eq!(UTC.ymd(2014, 11, 28).weekday(), Weekday::Fri);
assert_eq!(UTC.ymd_opt(2014, 11, 31), LocalResult::None);
assert_eq!(UTC.hms_milli(7, 8, 9, 10).format("%H%M%S").to_string(), "070809");
assert_eq!(UTC.ymd(2014, 11, 28).and_hms_milli(7, 8, 9, 10).format("%H%M%S").to_string(),
"070809");
~~~~
`DateTime` has two methods, `date` and `time`,
@ -268,7 +269,6 @@ pub use naive::date::NaiveDate;
pub use naive::time::NaiveTime;
pub use naive::datetime::NaiveDateTime;
pub use date::Date;
pub use time::Time;
pub use datetime::DateTime;
pub use format::{ParseError, ParseResult};
@ -296,7 +296,6 @@ pub mod naive {
pub mod datetime;
}
pub mod date;
pub mod time;
pub mod datetime;
pub mod format;

View File

@ -11,7 +11,6 @@ use std::fmt;
use div::div_mod_floor;
use duration::Duration;
use naive::date::NaiveDate;
use naive::time::NaiveTime;
use naive::datetime::NaiveDateTime;
use super::{TimeZone, Offset, LocalResult};
@ -71,15 +70,11 @@ impl TimeZone for FixedOffset {
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() }
}

View File

@ -14,7 +14,6 @@ use naive::date::NaiveDate;
use naive::time::NaiveTime;
use naive::datetime::NaiveDateTime;
use date::Date;
use time::Time;
use datetime::DateTime;
use super::{TimeZone, LocalResult};
use super::fixed::FixedOffset;
@ -79,9 +78,6 @@ impl TimeZone for Local {
fn offset_from_local_date(&self, local: &NaiveDate) -> LocalResult<FixedOffset> {
self.from_local_date(local).map(|&: date| *date.offset())
}
fn offset_from_local_time(&self, local: &NaiveTime) -> LocalResult<FixedOffset> {
self.from_local_time(local).map(|&: time| *time.offset())
}
fn offset_from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<FixedOffset> {
self.from_local_datetime(local).map(|&: datetime| *datetime.offset())
}
@ -89,9 +85,6 @@ impl TimeZone for Local {
fn offset_from_utc_date(&self, utc: &NaiveDate) -> FixedOffset {
*self.from_utc_date(utc).offset()
}
fn offset_from_utc_time(&self, utc: &NaiveTime) -> FixedOffset {
*self.from_utc_time(utc).offset()
}
fn offset_from_utc_datetime(&self, utc: &NaiveDateTime) -> FixedOffset {
*self.from_utc_datetime(utc).offset()
}
@ -100,9 +93,6 @@ impl TimeZone for Local {
fn from_local_date(&self, local: &NaiveDate) -> LocalResult<Date<Local>> {
self.from_local_datetime(&local.and_hms(0, 0, 0)).map(|datetime| datetime.date())
}
fn from_local_time(&self, _local: &NaiveTime) -> LocalResult<Time<Local>> {
LocalResult::None // we have no information about this time
}
fn from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<DateTime<Local>> {
let timespec = datetime_to_timespec(local);
LocalResult::Single(tm_to_datetime(stdtime::at(timespec)))
@ -111,9 +101,6 @@ impl TimeZone for Local {
fn from_utc_date(&self, utc: &NaiveDate) -> Date<Local> {
self.from_utc_datetime(&utc.and_hms(0, 0, 0)).date()
}
fn from_utc_time(&self, _utc: &NaiveTime) -> Time<Local> {
unimplemented!() // we have no information about this time
}
fn from_utc_datetime(&self, utc: &NaiveDateTime) -> DateTime<Local> {
let timespec = datetime_to_timespec(utc);
tm_to_datetime(stdtime::at_utc(timespec))

View File

@ -28,7 +28,6 @@ use naive::date::NaiveDate;
use naive::time::NaiveTime;
use naive::datetime::NaiveDateTime;
use date::Date;
use time::Time;
use datetime::DateTime;
use format::{parse, Parsed, ParseResult, StrftimeItems};
@ -247,80 +246,6 @@ pub trait TimeZone: Sized {
}
}
/// 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 time zone.
///
/// Returns `None` on invalid hour, minute and/or second.
fn hms_opt(&self, hour: u32, min: u32, sec: u32) -> LocalResult<Time<Self>> {
match NaiveTime::from_hms_opt(hour, min, sec) {
Some(t) => self.from_local_time(&t),
None => LocalResult::None,
}
}
/// 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.
fn hms_milli(&self, hour: u32, min: u32, sec: u32, milli: u32) -> Time<Self> {
self.hms_milli_opt(hour, min, sec, milli).unwrap()
}
/// 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.
fn hms_milli_opt(&self, hour: u32, min: u32, sec: u32, milli: u32) -> LocalResult<Time<Self>> {
match NaiveTime::from_hms_milli_opt(hour, min, sec, milli) {
Some(t) => self.from_local_time(&t),
None => LocalResult::None,
}
}
/// 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.
fn hms_micro(&self, hour: u32, min: u32, sec: u32, micro: u32) -> Time<Self> {
self.hms_micro_opt(hour, min, sec, micro).unwrap()
}
/// 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.
fn hms_micro_opt(&self, hour: u32, min: u32, sec: u32, micro: u32) -> LocalResult<Time<Self>> {
match NaiveTime::from_hms_micro_opt(hour, min, sec, micro) {
Some(t) => self.from_local_time(&t),
None => LocalResult::None,
}
}
/// 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.
fn hms_nano(&self, hour: u32, min: u32, sec: u32, nano: u32) -> Time<Self> {
self.hms_nano_opt(hour, min, sec, nano).unwrap()
}
/// 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.
fn hms_nano_opt(&self, hour: u32, min: u32, sec: u32, nano: u32) -> LocalResult<Time<Self>> {
match NaiveTime::from_hms_nano_opt(hour, min, sec, nano) {
Some(t) => self.from_local_time(&t),
None => LocalResult::None,
}
}
/// Makes a new `DateTime` from the number of non-leap seconds
/// since January 1, 1970 0:00:00 UTC (aka "UNIX timestamp")
/// and the number of nanoseconds since the last whole non-leap second.
@ -363,9 +288,6 @@ pub trait TimeZone: Sized {
/// Creates the offset(s) for given local `NaiveDate` if possible.
fn offset_from_local_date(&self, local: &NaiveDate) -> LocalResult<Self::Offset>;
/// Creates the offset(s) for given local `NaiveTime` if possible.
fn offset_from_local_time(&self, local: &NaiveTime) -> LocalResult<Self::Offset>;
/// Creates the offset(s) for given local `NaiveDateTime` if possible.
fn offset_from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<Self::Offset>;
@ -376,13 +298,6 @@ pub trait TimeZone: Sized {
})
}
/// Converts the local `NaiveTime` to the timezone-aware `Time` if possible.
fn from_local_time(&self, local: &NaiveTime) -> LocalResult<Time<Self>> {
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.offset_from_local_datetime(local).map(|offset| {
@ -393,9 +308,6 @@ pub trait TimeZone: Sized {
/// Creates the offset for given UTC `NaiveDate`. This cannot fail.
fn offset_from_utc_date(&self, utc: &NaiveDate) -> Self::Offset;
/// Creates the offset for given UTC `NaiveTime`. This cannot fail.
fn offset_from_utc_time(&self, utc: &NaiveTime) -> Self::Offset;
/// Creates the offset for given UTC `NaiveDateTime`. This cannot fail.
fn offset_from_utc_datetime(&self, utc: &NaiveDateTime) -> Self::Offset;
@ -405,12 +317,6 @@ pub trait TimeZone: Sized {
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.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> {

View File

@ -11,7 +11,6 @@ use stdtime;
use duration::Duration;
use naive::date::NaiveDate;
use naive::time::NaiveTime;
use naive::datetime::NaiveDateTime;
use date::Date;
use datetime::DateTime;
@ -42,15 +41,11 @@ impl TimeZone for 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}
}

View File

@ -1,173 +0,0 @@
// This is a part of rust-chrono.
// Copyright (c) 2014-2015, Kang Seonghoon.
// See README.md and LICENSE.txt for details.
/*!
* ISO 8601 time with time zone.
*/
use std::{fmt, hash};
use std::cmp::Ordering;
use std::ops::{Add, Sub};
use Timelike;
use offset::{TimeZone, Offset};
use duration::Duration;
use naive::time::NaiveTime;
use format::{Item, DelayedFormat, StrftimeItems};
/// ISO 8601 time with timezone.
#[derive(Clone)]
pub struct Time<Tz: TimeZone> {
time: NaiveTime,
offset: Tz::Offset,
}
impl<Tz: TimeZone> Time<Tz> {
/// Makes a new `Time` with given *UTC* time and offset.
/// 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: Tz::Offset) -> Time<Tz> {
Time { time: time, offset: offset }
}
/// Retrieves an associated offset from UTC.
#[inline]
pub fn offset<'a>(&'a self) -> &'a Tz::Offset {
&self.offset
}
/// Retrieves an associated time zone.
#[inline]
pub fn timezone(&self) -> Tz {
TimeZone::from_offset(&self.offset)
}
/// Changes the associated time zone.
/// This does not change the actual `Time` (but will change the string representation).
#[inline]
pub fn with_timezone<Tz2: TimeZone>(&self, tz: &Tz2) -> Time<Tz2> {
tz.from_utc_time(&self.time)
}
/// Returns a view to the naive UTC time.
#[inline]
pub fn naive_utc(&self) -> NaiveTime {
self.time
}
/// Returns a view to the naive local time.
#[inline]
pub fn naive_local(&self) -> NaiveTime {
self.time + self.offset.local_minus_utc()
}
}
/// Maps the local time to other time with given conversion function.
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<Tz: TimeZone> Time<Tz> where Tz::Offset: fmt::Display {
/// Formats the time with the specified formatting items.
#[inline]
pub fn format_with_items<'a, I>(&'a self, items: I) -> DelayedFormat<'a, I>
where I: Iterator<Item=Item<'a>> + Clone {
DelayedFormat::new_with_offset(None, Some(self.naive_local()), &self.offset, items)
}
/// Formats the time with the specified format string.
/// See the `format::strftime` module on the supported escape sequences.
#[inline]
pub fn format<'a>(&'a self, fmt: &'a str) -> DelayedFormat<'a, StrftimeItems<'a>> {
self.format_with_items(StrftimeItems::new(fmt))
}
}
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<Tz>> {
map_local(self, |time| time.with_hour(hour))
}
#[inline]
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<Tz>> {
map_local(self, |time| time.with_second(sec))
}
#[inline]
fn with_nanosecond(&self, nano: u32) -> Option<Time<Tz>> {
map_local(self, |time| time.with_nanosecond(nano))
}
#[inline]
fn num_seconds_from_midnight(&self) -> u32 { self.naive_local().num_seconds_from_midnight() }
}
impl<Tz: TimeZone, Tz2: TimeZone> PartialEq<Time<Tz2>> for Time<Tz> {
fn eq(&self, other: &Time<Tz2>) -> bool { self.time == other.time }
}
impl<Tz: TimeZone> Eq for Time<Tz> {
}
impl<Tz: TimeZone> PartialOrd for Time<Tz> {
fn partial_cmp(&self, other: &Time<Tz>) -> Option<Ordering> {
self.time.partial_cmp(&other.time)
}
}
impl<Tz: TimeZone> Ord for Time<Tz> {
fn cmp(&self, other: &Time<Tz>) -> Ordering { self.time.cmp(&other.time) }
}
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<Tz: TimeZone> Add<Duration> for Time<Tz> {
type Output = Time<Tz>;
fn add(self, rhs: Duration) -> Time<Tz> {
Time { time: self.time + rhs, offset: self.offset }
}
}
impl<Tz: TimeZone, Tz2: TimeZone> Sub<Time<Tz2>> for Time<Tz> {
type Output = Duration;
fn sub(self, rhs: Time<Tz2>) -> Duration { self.time - rhs.time }
}
impl<Tz: TimeZone> Sub<Duration> for Time<Tz> {
type Output = Time<Tz>;
#[inline]
fn sub(self, rhs: Duration) -> Time<Tz> { self.add(-rhs) }
}
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<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)
}
}