`time::Duration` is no longer the sole duration type described.

Due to the backward compatibility we won't be going to remove support
for `time::Duration` in 0.3, and the initial 0.3.0 release won't have
proper `std::time::Duration` support (haven't finalized the logics).
However we will reserve proper names and signatures for the upcoming
`std::time::Duration` support---the "older" duration type will be
referred as "signed" in the names.

- Added a `chrono::prelude` module. This does not have the (old)
  `Duration` type reexported, so the documentation has now correctly
  replaced all occurrences of `chrono::Duration`. The existing
  `chrono::Duration` reexport itself remains for the compatibility.

- Avoided using a plain `Duration` type in the signature, to avoid
  any ambiguity.

- Renamed `checked_{add,sub}` to `checked_{add,sub}_signed`.

- Subtraction operator between two instants has been removed and
  replaced with `signed_duration_since`. This follows the naming
  chosen by `std::time::SystemTime` etc., and the version for newer
  `std::time::Duration` will be named to `duration_since`.
This commit is contained in:
Kang Seonghoon 2017-02-06 08:17:01 +09:00
parent de4df91421
commit c63ef14734
No known key found for this signature in database
GPG Key ID: 82440FABA6709020
13 changed files with 654 additions and 399 deletions

View File

@ -58,17 +58,34 @@ Then put this in your crate root:
extern crate chrono; extern crate chrono;
``` ```
Avoid using `use chrono::*;` as Chrono exports several modules other than types.
If you prefer the glob imports, use the following instead:
```rust
use chrono::prelude::*;
```
## Overview ## Overview
### Duration ### Duration
[**`Duration`**](https://docs.rs/chrono/0.2.25/chrono/struct.Duration.html) represents the magnitude of a time Chrono currently uses
span. Note that this is an "accurate" duration represented as seconds and the [`time::Duration`](https://doc.rust-lang.org/time/time/struct.Duration.html) type
from the `time` crate to represent the magnitude of a time span.
Since this has the same name to the newer, standard type for duration,
the reference will refer this type as `OldDuration`.
Note that this is an "accurate" duration represented as seconds and
nanoseconds and does not represent "nominal" components such as days or nanoseconds and does not represent "nominal" components such as days or
months. `Duration` used to be provided by Chrono. It has been moved to the months.
`time` crate as the
[`time::Duration`](https://doc.rust-lang.org/time/time/struct.Duration.html) Chrono does not yet natively support
type, but is still re-exported from Chrono. the standard [`Duration`](https://doc.rust-lang.org/std/time/struct.Duration.html) type,
but it will be supported in the future.
Meanwhile you can convert between two types with
[`Duration::from_std`](https://doc.rust-lang.org/time/time/struct.Duration.html#method.from_std)
and
[`Duration::to_std`](https://doc.rust-lang.org/time/time/struct.Duration.html#method.to_std)
methods.
### Date and Time ### Date and Time
@ -108,7 +125,7 @@ or in the local time zone
([`Local::now()`](https://docs.rs/chrono/0.2.25/chrono/offset/local/struct.Local.html#method.now)). ([`Local::now()`](https://docs.rs/chrono/0.2.25/chrono/offset/local/struct.Local.html#method.now)).
~~~~ {.rust} ~~~~ {.rust}
use chrono::*; use chrono::prelude::*;
let utc: DateTime<UTC> = UTC::now(); // e.g. `2014-11-28T12:45:59.324310806Z` let utc: DateTime<UTC> = UTC::now(); // e.g. `2014-11-28T12:45:59.324310806Z`
let local: DateTime<Local> = Local::now(); // e.g. `2014-11-28T21:45:59.324310806+09:00` let local: DateTime<Local> = Local::now(); // e.g. `2014-11-28T21:45:59.324310806+09:00`
@ -119,7 +136,8 @@ This is a bit verbose due to Rust's lack of function and method overloading,
but in turn we get a rich combination of initialization methods. but in turn we get a rich combination of initialization methods.
~~~~ {.rust} ~~~~ {.rust}
use chrono::*; use chrono::prelude::*;
use chrono::offset::LocalResult;
let dt = UTC.ymd(2014, 7, 8).and_hms(9, 10, 11); // `2014-07-08T09:10:11Z` let dt = UTC.ymd(2014, 7, 8).and_hms(9, 10, 11); // `2014-07-08T09:10:11Z`
// July 8 is 188th day of the year 2014 (`o` for "ordinal") // July 8 is 188th day of the year 2014 (`o` for "ordinal")
@ -151,7 +169,8 @@ Addition and subtraction is also supported.
The following illustrates most supported operations to the date and time: The following illustrates most supported operations to the date and time:
~~~~ {.rust} ~~~~ {.rust}
use chrono::*; use chrono::prelude::*;
use time::Duration;
// assume this returned `2014-11-28T21:45:59.324310806+09:00`: // assume this returned `2014-11-28T21:45:59.324310806+09:00`:
let dt = Local::now(); let dt = Local::now();
@ -176,8 +195,10 @@ assert_eq!(dt.with_day(32), None);
assert_eq!(dt.with_year(-300).unwrap().num_days_from_ce(), -109606); // November 29, 301 BCE assert_eq!(dt.with_year(-300).unwrap().num_days_from_ce(), -109606); // November 29, 301 BCE
// arithmetic operations // arithmetic operations
assert_eq!(UTC.ymd(2014, 11, 14).and_hms(8, 9, 10) - UTC.ymd(2014, 11, 14).and_hms(10, 9, 8), let dt1 = UTC.ymd(2014, 11, 14).and_hms(8, 9, 10);
Duration::seconds(-2 * 3600 + 2)); let dt2 = UTC.ymd(2014, 11, 14).and_hms(10, 9, 8);
assert_eq!(dt1.signed_duration_since(dt2), Duration::seconds(-2 * 3600 + 2));
assert_eq!(dt2.signed_duration_since(dt1), Duration::seconds(2 * 3600 - 2));
assert_eq!(UTC.ymd(1970, 1, 1).and_hms(0, 0, 0) + Duration::seconds(1_000_000_000), assert_eq!(UTC.ymd(1970, 1, 1).and_hms(0, 0, 0) + Duration::seconds(1_000_000_000),
UTC.ymd(2001, 9, 9).and_hms(1, 46, 40)); UTC.ymd(2001, 9, 9).and_hms(1, 46, 40));
assert_eq!(UTC.ymd(1970, 1, 1).and_hms(0, 0, 0) - Duration::seconds(1_000_000_000), assert_eq!(UTC.ymd(1970, 1, 1).and_hms(0, 0, 0) - Duration::seconds(1_000_000_000),
@ -195,7 +216,7 @@ Chrono also provides [`to_rfc2822`](https://docs.rs/chrono/0.2.25/chrono/datetim
for well-known formats. for well-known formats.
~~~~ {.rust} ~~~~ {.rust}
use chrono::*; use chrono::prelude::*;
let dt = UTC.ymd(2014, 11, 28).and_hms(12, 0, 9); let dt = UTC.ymd(2014, 11, 28).and_hms(12, 0, 9);
assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2014-11-28 12:00:09"); assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2014-11-28 12:00:09");
@ -236,7 +257,7 @@ More detailed control over the parsing process is available via
[`format`](https://docs.rs/chrono/0.2.25/chrono/format/index.html) module. [`format`](https://docs.rs/chrono/0.2.25/chrono/format/index.html) module.
~~~~ {.rust} ~~~~ {.rust}
use chrono::*; use chrono::prelude::*;
let dt = UTC.ymd(2014, 11, 28).and_hms(12, 0, 9); let dt = UTC.ymd(2014, 11, 28).and_hms(12, 0, 9);
let fixed_dt = dt.with_timezone(&FixedOffset::east(9*3600)); let fixed_dt = dt.with_timezone(&FixedOffset::east(9*3600));
@ -272,7 +293,8 @@ It also has time zones attached, and have to be constructed via time zones.
Most operations available to `DateTime` are also available to `Date` whenever appropriate. Most operations available to `DateTime` are also available to `Date` whenever appropriate.
~~~~ {.rust} ~~~~ {.rust}
use chrono::*; use chrono::prelude::*;
use chrono::offset::LocalResult;
assert_eq!(UTC::today(), UTC::now().date()); assert_eq!(UTC::today(), UTC::now().date());
assert_eq!(Local::today(), Local::now().date()); assert_eq!(Local::today(), Local::now().date());

View File

@ -1,16 +1,14 @@
// This is a part of Chrono. // This is a part of Chrono.
// See README.md and LICENSE.txt for details. // See README.md and LICENSE.txt for details.
/*! //! ISO 8601 calendar date with time zone.
* ISO 8601 calendar date with time zone.
*/
use std::{fmt, hash}; use std::{fmt, hash};
use std::cmp::Ordering; use std::cmp::Ordering;
use std::ops::{Add, Sub}; use std::ops::{Add, Sub};
use oldtime::Duration as OldDuration;
use {Weekday, Datelike}; use {Weekday, Datelike};
use duration::Duration;
use offset::{TimeZone, Offset}; use offset::{TimeZone, Offset};
use offset::utc::UTC; use offset::utc::UTC;
use naive; use naive;
@ -209,8 +207,8 @@ impl<Tz: TimeZone> Date<Tz> {
/// ///
/// Returns `None` when it will result in overflow. /// Returns `None` when it will result in overflow.
#[inline] #[inline]
pub fn checked_add(self, rhs: Duration) -> Option<Date<Tz>> { pub fn checked_add_signed(self, rhs: OldDuration) -> Option<Date<Tz>> {
let date = try_opt!(self.date.checked_add(rhs)); let date = try_opt!(self.date.checked_add_signed(rhs));
Some(Date { date: date, offset: self.offset }) Some(Date { date: date, offset: self.offset })
} }
@ -218,11 +216,39 @@ impl<Tz: TimeZone> Date<Tz> {
/// ///
/// Returns `None` when it will result in overflow. /// Returns `None` when it will result in overflow.
#[inline] #[inline]
pub fn checked_sub(self, rhs: Duration) -> Option<Date<Tz>> { pub fn checked_sub_signed(self, rhs: OldDuration) -> Option<Date<Tz>> {
let date = try_opt!(self.date.checked_sub(rhs)); let date = try_opt!(self.date.checked_sub_signed(rhs));
Some(Date { date: date, offset: self.offset }) Some(Date { date: date, offset: self.offset })
} }
/// Subtracts another `Date` from the current date.
/// Returns a `Duration` of integral numbers.
///
/// This does not overflow or underflow at all,
/// as all possible output fits in the range of `Duration`.
#[inline]
pub fn signed_duration_since<Tz2: TimeZone>(self, rhs: Date<Tz2>) -> OldDuration {
self.date.signed_duration_since(rhs.date)
}
/// Same to [`Date::checked_add_signed`](#method.checked_add_signed).
#[inline]
#[deprecated(since = "0.2.26",
note = "Renamed to `checked_add_signed`, \
will be replaced with a version with `std::time::Duration`")]
pub fn checked_add(self, rhs: OldDuration) -> Option<Date<Tz>> {
self.checked_add_signed(rhs)
}
/// Same to [`Date::checked_sub_signed`](#method.checked_sub_signed).
#[inline]
#[deprecated(since = "0.2.26",
note = "Renamed to `checked_sub_signed`, \
will be replaced with a version with `std::time::Duration`")]
pub fn checked_sub(self, rhs: OldDuration) -> Option<Date<Tz>> {
self.checked_sub_signed(rhs)
}
/// Returns a view to the naive UTC date. /// Returns a view to the naive UTC date.
#[inline] #[inline]
pub fn naive_utc(&self) -> NaiveDate { pub fn naive_utc(&self) -> NaiveDate {
@ -331,28 +357,32 @@ impl<Tz: TimeZone> hash::Hash for Date<Tz> {
fn hash<H: hash::Hasher>(&self, state: &mut H) { self.date.hash(state) } fn hash<H: hash::Hasher>(&self, state: &mut H) { self.date.hash(state) }
} }
impl<Tz: TimeZone> Add<Duration> for Date<Tz> { impl<Tz: TimeZone> Add<OldDuration> for Date<Tz> {
type Output = Date<Tz>; type Output = Date<Tz>;
#[inline] #[inline]
fn add(self, rhs: Duration) -> Date<Tz> { fn add(self, rhs: OldDuration) -> Date<Tz> {
self.checked_add(rhs).expect("`Date + Duration` overflowed") self.checked_add_signed(rhs).expect("`Date + Duration` overflowed")
} }
} }
// XXX this does not really work yet
#[deprecated(since = "0.2.26", note = "Use `signed_duration_since` method instead")]
impl<Tz: TimeZone, Tz2: TimeZone> Sub<Date<Tz2>> for Date<Tz> { impl<Tz: TimeZone, Tz2: TimeZone> Sub<Date<Tz2>> for Date<Tz> {
type Output = Duration; type Output = OldDuration;
#[inline] #[inline]
fn sub(self, rhs: Date<Tz2>) -> Duration { self.date - rhs.date } fn sub(self, rhs: Date<Tz2>) -> OldDuration {
self.signed_duration_since(rhs)
}
} }
impl<Tz: TimeZone> Sub<Duration> for Date<Tz> { impl<Tz: TimeZone> Sub<OldDuration> for Date<Tz> {
type Output = Date<Tz>; type Output = Date<Tz>;
#[inline] #[inline]
fn sub(self, rhs: Duration) -> Date<Tz> { fn sub(self, rhs: OldDuration) -> Date<Tz> {
self.checked_sub(rhs).expect("`Date - Duration` overflowed") self.checked_sub_signed(rhs).expect("`Date - Duration` overflowed")
} }
} }
@ -423,9 +453,9 @@ mod rustc_serialize {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::fmt; use std::fmt;
use oldtime::Duration;
use Datelike; use Datelike;
use duration::Duration;
use naive::date::NaiveDate; use naive::date::NaiveDate;
use naive::datetime::NaiveDateTime; use naive::datetime::NaiveDateTime;
use offset::{TimeZone, Offset, LocalResult}; use offset::{TimeZone, Offset, LocalResult};

View File

@ -1,20 +1,18 @@
// This is a part of Chrono. // This is a part of Chrono.
// See README.md and LICENSE.txt for details. // See README.md and LICENSE.txt for details.
/*! //! ISO 8601 date and time with time zone.
* ISO 8601 date and time with time zone.
*/
use std::{str, fmt, hash}; use std::{str, fmt, hash};
use std::cmp::Ordering; use std::cmp::Ordering;
use std::ops::{Add, Sub}; use std::ops::{Add, Sub};
use oldtime::Duration as OldDuration;
use {Weekday, Timelike, Datelike}; use {Weekday, Timelike, Datelike};
use offset::{TimeZone, Offset, add_with_leapsecond}; use offset::{TimeZone, Offset, add_with_leapsecond};
use offset::utc::UTC; use offset::utc::UTC;
use offset::local::Local; use offset::local::Local;
use offset::fixed::FixedOffset; use offset::fixed::FixedOffset;
use duration::Duration;
use naive::time::NaiveTime; use naive::time::NaiveTime;
use naive::datetime::NaiveDateTime; use naive::datetime::NaiveDateTime;
use date::Date; use date::Date;
@ -130,8 +128,8 @@ impl<Tz: TimeZone> DateTime<Tz> {
/// ///
/// Returns `None` when it will result in overflow. /// Returns `None` when it will result in overflow.
#[inline] #[inline]
pub fn checked_add(self, rhs: Duration) -> Option<DateTime<Tz>> { pub fn checked_add_signed(self, rhs: OldDuration) -> Option<DateTime<Tz>> {
let datetime = try_opt!(self.datetime.checked_add(rhs)); let datetime = try_opt!(self.datetime.checked_add_signed(rhs));
Some(DateTime { datetime: datetime, offset: self.offset }) Some(DateTime { datetime: datetime, offset: self.offset })
} }
@ -139,11 +137,18 @@ impl<Tz: TimeZone> DateTime<Tz> {
/// ///
/// Returns `None` when it will result in overflow. /// Returns `None` when it will result in overflow.
#[inline] #[inline]
pub fn checked_sub(self, rhs: Duration) -> Option<DateTime<Tz>> { pub fn checked_sub_signed(self, rhs: OldDuration) -> Option<DateTime<Tz>> {
let datetime = try_opt!(self.datetime.checked_sub(rhs)); let datetime = try_opt!(self.datetime.checked_sub_signed(rhs));
Some(DateTime { datetime: datetime, offset: self.offset }) Some(DateTime { datetime: datetime, offset: self.offset })
} }
/// Subtracts another `DateTime` from the current date and time.
/// This does not overflow or underflow at all.
#[inline]
pub fn signed_duration_since<Tz2: TimeZone>(self, rhs: DateTime<Tz2>) -> OldDuration {
self.datetime.signed_duration_since(rhs.datetime)
}
/// Returns a view to the naive UTC datetime. /// Returns a view to the naive UTC datetime.
#[inline] #[inline]
pub fn naive_utc(&self) -> NaiveDateTime { pub fn naive_utc(&self) -> NaiveDateTime {
@ -327,28 +332,21 @@ impl<Tz: TimeZone> hash::Hash for DateTime<Tz> {
fn hash<H: hash::Hasher>(&self, state: &mut H) { self.datetime.hash(state) } fn hash<H: hash::Hasher>(&self, state: &mut H) { self.datetime.hash(state) }
} }
impl<Tz: TimeZone> Add<Duration> for DateTime<Tz> { impl<Tz: TimeZone> Add<OldDuration> for DateTime<Tz> {
type Output = DateTime<Tz>; type Output = DateTime<Tz>;
#[inline] #[inline]
fn add(self, rhs: Duration) -> DateTime<Tz> { fn add(self, rhs: OldDuration) -> DateTime<Tz> {
self.checked_add(rhs).expect("`DateTime + Duration` overflowed") self.checked_add_signed(rhs).expect("`DateTime + Duration` overflowed")
} }
} }
impl<Tz: TimeZone, Tz2: TimeZone> Sub<DateTime<Tz2>> for DateTime<Tz> { impl<Tz: TimeZone> Sub<OldDuration> for DateTime<Tz> {
type Output = Duration;
#[inline]
fn sub(self, rhs: DateTime<Tz2>) -> Duration { self.datetime - rhs.datetime }
}
impl<Tz: TimeZone> Sub<Duration> for DateTime<Tz> {
type Output = DateTime<Tz>; type Output = DateTime<Tz>;
#[inline] #[inline]
fn sub(self, rhs: Duration) -> DateTime<Tz> { fn sub(self, rhs: OldDuration) -> DateTime<Tz> {
self.checked_sub(rhs).expect("`DateTime - Duration` overflowed") self.checked_sub_signed(rhs).expect("`DateTime - Duration` overflowed")
} }
} }
@ -578,11 +576,11 @@ mod tests {
use Datelike; use Datelike;
use naive::time::NaiveTime; use naive::time::NaiveTime;
use naive::date::NaiveDate; use naive::date::NaiveDate;
use duration::Duration;
use offset::TimeZone; use offset::TimeZone;
use offset::utc::UTC; use offset::utc::UTC;
use offset::local::Local; use offset::local::Local;
use offset::fixed::FixedOffset; use offset::fixed::FixedOffset;
use oldtime::Duration;
#[test] #[test]
#[allow(non_snake_case)] #[allow(non_snake_case)]
@ -618,10 +616,10 @@ mod tests {
assert_eq!(format!("{:?}", KST.ymd(2014, 5, 6).and_hms(23, 59, 59)), assert_eq!(format!("{:?}", KST.ymd(2014, 5, 6).and_hms(23, 59, 59)),
"2014-05-06T23:59:59+09:00"); "2014-05-06T23:59:59+09:00");
assert_eq!(UTC.ymd(2014, 5, 6).and_hms(7, 8, 9), EDT.ymd(2014, 5, 6).and_hms(3, 8, 9)); let dt = UTC.ymd(2014, 5, 6).and_hms(7, 8, 9);
assert_eq!(UTC.ymd(2014, 5, 6).and_hms(7, 8, 9) + Duration::seconds(3600 + 60 + 1), assert_eq!(dt, EDT.ymd(2014, 5, 6).and_hms(3, 8, 9));
UTC.ymd(2014, 5, 6).and_hms(8, 9, 10)); assert_eq!(dt + Duration::seconds(3600 + 60 + 1), UTC.ymd(2014, 5, 6).and_hms(8, 9, 10));
assert_eq!(UTC.ymd(2014, 5, 6).and_hms(7, 8, 9) - EDT.ymd(2014, 5, 6).and_hms(10, 11, 12), assert_eq!(dt.signed_duration_since(EDT.ymd(2014, 5, 6).and_hms(10, 11, 12)),
Duration::seconds(-7*3600 - 3*60 - 3)); Duration::seconds(-7*3600 - 3*60 - 3));
assert_eq!(*UTC.ymd(2014, 5, 6).and_hms(7, 8, 9).offset(), UTC); assert_eq!(*UTC.ymd(2014, 5, 6).and_hms(7, 8, 9).offset(), UTC);

View File

@ -5,10 +5,10 @@
use std::fmt; use std::fmt;
use std::error::Error; use std::error::Error;
use oldtime::Duration as OldDuration;
use {Datelike, Timelike}; use {Datelike, Timelike};
use div::{div_floor, mod_floor}; use div::{div_floor, mod_floor};
use duration::Duration;
use offset::{Offset, add_with_leapsecond}; use offset::{Offset, add_with_leapsecond};
use naive::date::NaiveDate; use naive::date::NaiveDate;
use naive::time::NaiveTime; use naive::time::NaiveTime;
@ -252,7 +252,7 @@ const BAD_FORMAT: ParseError = ParseError(ParseErrorKind::BadFormat);
/// Tries to format given arguments with given formatting items. /// Tries to format given arguments with given formatting items.
/// Internally used by `DelayedFormat`. /// Internally used by `DelayedFormat`.
pub fn format<'a, I>(w: &mut fmt::Formatter, date: Option<&NaiveDate>, time: Option<&NaiveTime>, pub fn format<'a, I>(w: &mut fmt::Formatter, date: Option<&NaiveDate>, time: Option<&NaiveTime>,
off: Option<&(String, Duration)>, items: I) -> fmt::Result off: Option<&(String, OldDuration)>, items: I) -> fmt::Result
where I: Iterator<Item=Item<'a>> { where I: Iterator<Item=Item<'a>> {
// full and abbreviated month and weekday names // full and abbreviated month and weekday names
static SHORT_MONTHS: [&'static str; 12] = static SHORT_MONTHS: [&'static str; 12] =
@ -332,7 +332,7 @@ pub fn format<'a, I>(w: &mut fmt::Formatter, date: Option<&NaiveDate>, time: Opt
/// Prints an offset from UTC in the format of `+HHMM` or `+HH:MM`. /// Prints an offset from UTC in the format of `+HHMM` or `+HH:MM`.
/// `Z` instead of `+00[:]00` is allowed when `allow_zulu` is true. /// `Z` instead of `+00[:]00` is allowed when `allow_zulu` is true.
fn write_local_minus_utc(w: &mut fmt::Formatter, off: Duration, fn write_local_minus_utc(w: &mut fmt::Formatter, off: OldDuration,
allow_zulu: bool, use_colon: bool) -> fmt::Result { allow_zulu: bool, use_colon: bool) -> fmt::Result {
let off = off.num_minutes(); let off = off.num_minutes();
if !allow_zulu || off != 0 { if !allow_zulu || off != 0 {
@ -452,7 +452,7 @@ pub struct DelayedFormat<I> {
/// The time view, if any. /// The time view, if any.
time: Option<NaiveTime>, time: Option<NaiveTime>,
/// The name and local-to-UTC difference for the offset (timezone), if any. /// The name and local-to-UTC difference for the offset (timezone), if any.
off: Option<(String, Duration)>, off: Option<(String, OldDuration)>,
/// An iterator returning formatting items. /// An iterator returning formatting items.
items: I, items: I,
} }

View File

@ -5,11 +5,11 @@
//! They can be constructed incrementally while being checked for consistency. //! They can be constructed incrementally while being checked for consistency.
use num::traits::ToPrimitive; use num::traits::ToPrimitive;
use oldtime::Duration as OldDuration;
use {Datelike, Timelike}; use {Datelike, Timelike};
use Weekday; use Weekday;
use div::div_rem; use div::div_rem;
use duration::Duration;
use offset::{TimeZone, Offset, LocalResult}; use offset::{TimeZone, Offset, LocalResult};
use offset::fixed::FixedOffset; use offset::fixed::FixedOffset;
use naive::date::NaiveDate; use naive::date::NaiveDate;
@ -382,7 +382,7 @@ impl Parsed {
if week_from_sun > 53 { return Err(OUT_OF_RANGE); } // can it overflow? if week_from_sun > 53 { return Err(OUT_OF_RANGE); } // can it overflow?
let ndays = firstweek + (week_from_sun as i32 - 1) * 7 + let ndays = firstweek + (week_from_sun as i32 - 1) * 7 +
weekday.num_days_from_sunday() as i32; weekday.num_days_from_sunday() as i32;
let date = try!(newyear.checked_add(Duration::days(ndays as i64)) let date = try!(newyear.checked_add_signed(OldDuration::days(ndays as i64))
.ok_or(OUT_OF_RANGE)); .ok_or(OUT_OF_RANGE));
if date.year() != year { return Err(OUT_OF_RANGE); } // early exit for correct error if date.year() != year { return Err(OUT_OF_RANGE); } // early exit for correct error
@ -407,7 +407,7 @@ impl Parsed {
if week_from_mon > 53 { return Err(OUT_OF_RANGE); } // can it overflow? if week_from_mon > 53 { return Err(OUT_OF_RANGE); } // can it overflow?
let ndays = firstweek + (week_from_mon as i32 - 1) * 7 + let ndays = firstweek + (week_from_mon as i32 - 1) * 7 +
weekday.num_days_from_monday() as i32; weekday.num_days_from_monday() as i32;
let date = try!(newyear.checked_add(Duration::days(ndays as i64)) let date = try!(newyear.checked_add_signed(OldDuration::days(ndays as i64))
.ok_or(OUT_OF_RANGE)); .ok_or(OUT_OF_RANGE));
if date.year() != year { return Err(OUT_OF_RANGE); } // early exit for correct error if date.year() != year { return Err(OUT_OF_RANGE); } // early exit for correct error
@ -526,7 +526,7 @@ impl Parsed {
// it's okay, just do not try to overwrite the existing field. // it's okay, just do not try to overwrite the existing field.
59 => {} 59 => {}
// `datetime` is known to be off by one second. // `datetime` is known to be off by one second.
0 => { datetime = datetime - Duration::seconds(1); } 0 => { datetime = datetime - OldDuration::seconds(1); }
// otherwise it is impossible. // otherwise it is impossible.
_ => return Err(IMPOSSIBLE) _ => return Err(IMPOSSIBLE)
} }
@ -957,9 +957,12 @@ mod tests {
ymdhmsn(2014,12,31, 4,26,40,12_345_678)); ymdhmsn(2014,12,31, 4,26,40,12_345_678));
// more timestamps // more timestamps
let max_days_from_year_1970 = date::MAX - NaiveDate::from_ymd(1970,1,1); let max_days_from_year_1970 =
let year_0_from_year_1970 = NaiveDate::from_ymd(0,1,1) - NaiveDate::from_ymd(1970,1,1); date::MAX.signed_duration_since(NaiveDate::from_ymd(1970,1,1));
let min_days_from_year_1970 = date::MIN - NaiveDate::from_ymd(1970,1,1); let year_0_from_year_1970 =
NaiveDate::from_ymd(0,1,1).signed_duration_since(NaiveDate::from_ymd(1970,1,1));
let min_days_from_year_1970 =
date::MIN.signed_duration_since(NaiveDate::from_ymd(1970,1,1));
assert_eq!(parse!(timestamp: min_days_from_year_1970.num_seconds()), assert_eq!(parse!(timestamp: min_days_from_year_1970.num_seconds()),
ymdhms(date::MIN.year(),1,1, 0,0,0)); ymdhms(date::MIN.year(),1,1, 0,0,0));
assert_eq!(parse!(timestamp: year_0_from_year_1970.num_seconds()), assert_eq!(parse!(timestamp: year_0_from_year_1970.num_seconds()),

View File

@ -44,17 +44,34 @@
//! extern crate chrono; //! extern crate chrono;
//! ``` //! ```
//! //!
//! Avoid using `use chrono::*;` as Chrono exports several modules other than types.
//! If you prefer the glob imports, use the following instead:
//!
//! ```rust
//! use chrono::prelude::*;
//! ```
//!
//! ## Overview //! ## Overview
//! //!
//! ### Duration //! ### Duration
//! //!
//! [**`Duration`**](./struct.Duration.html) represents the magnitude of a time //! Chrono currently uses
//! span. Note that this is an "accurate" duration represented as seconds and //! the [`time::Duration`](https://doc.rust-lang.org/time/time/struct.Duration.html) type
//! from the `time` crate to represent the magnitude of a time span.
//! Since this has the same name to the newer, standard type for duration,
//! the reference will refer this type as `OldDuration`.
//! Note that this is an "accurate" duration represented as seconds and
//! nanoseconds and does not represent "nominal" components such as days or //! nanoseconds and does not represent "nominal" components such as days or
//! months. `Duration` used to be provided by Chrono. It has been moved to the //! months.
//! `time` crate as the //!
//! [`time::Duration`](https://doc.rust-lang.org/time/time/struct.Duration.html) //! Chrono does not yet natively support
//! type, but is still re-exported from Chrono. //! the standard [`Duration`](https://doc.rust-lang.org/std/time/struct.Duration.html) type,
//! but it will be supported in the future.
//! Meanwhile you can convert between two types with
//! [`Duration::from_std`](https://doc.rust-lang.org/time/time/struct.Duration.html#method.from_std)
//! and
//! [`Duration::to_std`](https://doc.rust-lang.org/time/time/struct.Duration.html#method.to_std)
//! methods.
//! //!
//! ### Date and Time //! ### Date and Time
//! //!
@ -94,7 +111,7 @@
//! ([`Local::now()`](./offset/local/struct.Local.html#method.now)). //! ([`Local::now()`](./offset/local/struct.Local.html#method.now)).
//! //!
//! ~~~~ {.rust} //! ~~~~ {.rust}
//! use chrono::*; //! use chrono::prelude::*;
//! //!
//! let utc: DateTime<UTC> = UTC::now(); // e.g. `2014-11-28T12:45:59.324310806Z` //! let utc: DateTime<UTC> = UTC::now(); // e.g. `2014-11-28T12:45:59.324310806Z`
//! let local: DateTime<Local> = Local::now(); // e.g. `2014-11-28T21:45:59.324310806+09:00` //! let local: DateTime<Local> = Local::now(); // e.g. `2014-11-28T21:45:59.324310806+09:00`
@ -106,7 +123,8 @@
//! but in turn we get a rich combination of initialization methods. //! but in turn we get a rich combination of initialization methods.
//! //!
//! ~~~~ {.rust} //! ~~~~ {.rust}
//! use chrono::*; //! use chrono::prelude::*;
//! use chrono::offset::LocalResult;
//! //!
//! let dt = UTC.ymd(2014, 7, 8).and_hms(9, 10, 11); // `2014-07-08T09:10:11Z` //! let dt = UTC.ymd(2014, 7, 8).and_hms(9, 10, 11); // `2014-07-08T09:10:11Z`
//! // July 8 is 188th day of the year 2014 (`o` for "ordinal") //! // July 8 is 188th day of the year 2014 (`o` for "ordinal")
@ -139,7 +157,9 @@
//! The following illustrates most supported operations to the date and time: //! The following illustrates most supported operations to the date and time:
//! //!
//! ~~~~ {.rust} //! ~~~~ {.rust}
//! use chrono::*; //! # extern crate chrono; extern crate time; fn main() {
//! use chrono::prelude::*;
//! use time::Duration;
//! //!
//! # /* we intentionally fake the datetime... //! # /* we intentionally fake the datetime...
//! // assume this returned `2014-11-28T21:45:59.324310806+09:00`: //! // assume this returned `2014-11-28T21:45:59.324310806+09:00`:
@ -167,12 +187,15 @@
//! assert_eq!(dt.with_year(-300).unwrap().num_days_from_ce(), -109606); // November 29, 301 BCE //! assert_eq!(dt.with_year(-300).unwrap().num_days_from_ce(), -109606); // November 29, 301 BCE
//! //!
//! // arithmetic operations //! // arithmetic operations
//! assert_eq!(UTC.ymd(2014, 11, 14).and_hms(8, 9, 10) - UTC.ymd(2014, 11, 14).and_hms(10, 9, 8), //! let dt1 = UTC.ymd(2014, 11, 14).and_hms(8, 9, 10);
//! Duration::seconds(-2 * 3600 + 2)); //! let dt2 = UTC.ymd(2014, 11, 14).and_hms(10, 9, 8);
//! assert_eq!(dt1.signed_duration_since(dt2), Duration::seconds(-2 * 3600 + 2));
//! assert_eq!(dt2.signed_duration_since(dt1), Duration::seconds(2 * 3600 - 2));
//! assert_eq!(UTC.ymd(1970, 1, 1).and_hms(0, 0, 0) + Duration::seconds(1_000_000_000), //! assert_eq!(UTC.ymd(1970, 1, 1).and_hms(0, 0, 0) + Duration::seconds(1_000_000_000),
//! UTC.ymd(2001, 9, 9).and_hms(1, 46, 40)); //! UTC.ymd(2001, 9, 9).and_hms(1, 46, 40));
//! assert_eq!(UTC.ymd(1970, 1, 1).and_hms(0, 0, 0) - Duration::seconds(1_000_000_000), //! assert_eq!(UTC.ymd(1970, 1, 1).and_hms(0, 0, 0) - Duration::seconds(1_000_000_000),
//! UTC.ymd(1938, 4, 24).and_hms(22, 13, 20)); //! UTC.ymd(1938, 4, 24).and_hms(22, 13, 20));
//! # }
//! ~~~~ //! ~~~~
//! //!
//! Formatting is done via the [`format`](./datetime/struct.DateTime.html#method.format) method, //! Formatting is done via the [`format`](./datetime/struct.DateTime.html#method.format) method,
@ -186,7 +209,7 @@
//! for well-known formats. //! for well-known formats.
//! //!
//! ~~~~ {.rust} //! ~~~~ {.rust}
//! use chrono::*; //! use chrono::prelude::*;
//! //!
//! let dt = UTC.ymd(2014, 11, 28).and_hms(12, 0, 9); //! let dt = UTC.ymd(2014, 11, 28).and_hms(12, 0, 9);
//! assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2014-11-28 12:00:09"); //! assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2014-11-28 12:00:09");
@ -227,7 +250,7 @@
//! [`format`](./format/index.html) module. //! [`format`](./format/index.html) module.
//! //!
//! ~~~~ {.rust} //! ~~~~ {.rust}
//! use chrono::*; //! use chrono::prelude::*;
//! //!
//! let dt = UTC.ymd(2014, 11, 28).and_hms(12, 0, 9); //! let dt = UTC.ymd(2014, 11, 28).and_hms(12, 0, 9);
//! let fixed_dt = dt.with_timezone(&FixedOffset::east(9*3600)); //! let fixed_dt = dt.with_timezone(&FixedOffset::east(9*3600));
@ -263,7 +286,8 @@
//! Most operations available to `DateTime` are also available to `Date` whenever appropriate. //! Most operations available to `DateTime` are also available to `Date` whenever appropriate.
//! //!
//! ~~~~ {.rust} //! ~~~~ {.rust}
//! use chrono::*; //! use chrono::prelude::*;
//! use chrono::offset::LocalResult;
//! //!
//! # // these *may* fail, but only very rarely. just rerun the test if you were that unfortunate ;) //! # // these *may* fail, but only very rarely. just rerun the test if you were that unfortunate ;)
//! assert_eq!(UTC::today(), UTC::now().date()); //! assert_eq!(UTC::today(), UTC::now().date());
@ -326,14 +350,16 @@
#![cfg_attr(bench, feature(test))] // lib stability features as per RFC #507 #![cfg_attr(bench, feature(test))] // lib stability features as per RFC #507
#![deny(missing_docs)] #![deny(missing_docs)]
extern crate time as stdtime; extern crate time as oldtime;
extern crate num; extern crate num;
#[cfg(feature = "rustc-serialize")] #[cfg(feature = "rustc-serialize")]
extern crate rustc_serialize; extern crate rustc_serialize;
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
extern crate serde; extern crate serde;
pub use duration::Duration; // this reexport is to aid the transition and should not be in the prelude!
pub use oldtime::Duration;
pub use offset::{TimeZone, Offset, LocalResult}; pub use offset::{TimeZone, Offset, LocalResult};
pub use offset::utc::UTC; pub use offset::utc::UTC;
pub use offset::fixed::FixedOffset; pub use offset::fixed::FixedOffset;
@ -345,24 +371,26 @@ pub use date::Date;
pub use datetime::DateTime; pub use datetime::DateTime;
pub use format::{ParseError, ParseResult}; pub use format::{ParseError, ParseResult};
/// A convenience module appropriate for glob imports (`use chrono::prelude::*;`).
pub mod prelude {
pub use {Datelike, Timelike, Weekday};
pub use offset::{TimeZone, Offset};
pub use offset::utc::UTC;
pub use offset::fixed::FixedOffset;
pub use offset::local::Local;
pub use naive::date::NaiveDate;
pub use naive::time::NaiveTime;
pub use naive::datetime::NaiveDateTime;
pub use date::Date;
pub use datetime::DateTime;
}
// useful throughout the codebase // useful throughout the codebase
macro_rules! try_opt { macro_rules! try_opt {
($e:expr) => (match $e { Some(v) => v, None => return None }) ($e:expr) => (match $e { Some(v) => v, None => return None })
} }
mod div; mod div;
pub mod duration {
//! ISO 8601 accurate duration.
//!
//! Note that this is an "accurate" (i.e. "exact") duration represented as
//! seconds and nanoseconds. It does not include the "nominal" components
//! (years, months, weeks, and days) in the ISO 8601 duration format
//! because arithmetic with nominal components is not defined in ISO 8601.
//!
//! This used to be a part of Chrono,
//! but has been subsequently merged into Rust's standard library.
pub use stdtime::Duration;
}
pub mod offset; pub mod offset;
pub mod naive { pub mod naive {
//! Date and time types which do not concern about the timezones. //! Date and time types which do not concern about the timezones.

View File

@ -49,10 +49,10 @@
use std::{str, fmt, hash}; use std::{str, fmt, hash};
use std::ops::{Add, Sub}; use std::ops::{Add, Sub};
use num::traits::ToPrimitive; use num::traits::ToPrimitive;
use oldtime::Duration as OldDuration;
use {Weekday, Datelike}; use {Weekday, Datelike};
use div::div_mod_floor; use div::div_mod_floor;
use duration::Duration;
use naive::time::NaiveTime; use naive::time::NaiveTime;
use naive::datetime::NaiveDateTime; use naive::datetime::NaiveDateTime;
use format::{Item, Numeric, Pad}; use format::{Item, Numeric, Pad};
@ -114,7 +114,7 @@ fn test_date_bounds() {
// let's also check that the entire range do not exceed 2^44 seconds // let's also check that the entire range do not exceed 2^44 seconds
// (sometimes used for bounding `Duration` against overflow) // (sometimes used for bounding `Duration` against overflow)
let maxsecs = (MAX - MIN).num_seconds(); let maxsecs = MAX.signed_duration_since(MIN).num_seconds();
let maxsecs = maxsecs + 86401; // also take care of DateTime let maxsecs = maxsecs + 86401; // also take care of DateTime
assert!(maxsecs < (1 << MAX_BITS), assert!(maxsecs < (1 << MAX_BITS),
"The entire `NaiveDate` range somehow exceeds 2^{} seconds", MAX_BITS); "The entire `NaiveDate` range somehow exceeds 2^{} seconds", MAX_BITS);
@ -798,17 +798,22 @@ impl NaiveDate {
/// # Example /// # Example
/// ///
/// ~~~~ /// ~~~~
/// use chrono::{NaiveDate, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// use chrono::NaiveDate;
/// use chrono::naive::date::MAX; /// use chrono::naive::date::MAX;
/// use time::Duration;
/// ///
/// let d = NaiveDate::from_ymd(2015, 9, 5); /// let d = NaiveDate::from_ymd(2015, 9, 5);
/// assert_eq!(d.checked_add(Duration::days(40)), Some(NaiveDate::from_ymd(2015, 10, 15))); /// assert_eq!(d.checked_add_signed(Duration::days(40)),
/// assert_eq!(d.checked_add(Duration::days(-40)), Some(NaiveDate::from_ymd(2015, 7, 27))); /// Some(NaiveDate::from_ymd(2015, 10, 15)));
/// assert_eq!(d.checked_add(Duration::days(1_000_000_000)), None); /// assert_eq!(d.checked_add_signed(Duration::days(-40)),
/// assert_eq!(d.checked_add(Duration::days(-1_000_000_000)), None); /// Some(NaiveDate::from_ymd(2015, 7, 27)));
/// assert_eq!(MAX.checked_add(Duration::days(1)), None); /// assert_eq!(d.checked_add_signed(Duration::days(1_000_000_000)), None);
/// assert_eq!(d.checked_add_signed(Duration::days(-1_000_000_000)), None);
/// assert_eq!(MAX.checked_add_signed(Duration::days(1)), None);
/// # }
/// ~~~~ /// ~~~~
pub fn checked_add(self, rhs: Duration) -> Option<NaiveDate> { pub fn checked_add_signed(self, rhs: OldDuration) -> Option<NaiveDate> {
let year = self.year(); let year = self.year();
let (mut year_div_400, year_mod_400) = div_mod_floor(year, 400); let (mut year_div_400, year_mod_400) = div_mod_floor(year, 400);
let cycle = internals::yo_to_cycle(year_mod_400 as u32, self.of().ordinal()); let cycle = internals::yo_to_cycle(year_mod_400 as u32, self.of().ordinal());
@ -829,17 +834,22 @@ impl NaiveDate {
/// # Example /// # Example
/// ///
/// ~~~~ /// ~~~~
/// use chrono::{NaiveDate, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// use chrono::NaiveDate;
/// use chrono::naive::date::MIN; /// use chrono::naive::date::MIN;
/// use time::Duration;
/// ///
/// let d = NaiveDate::from_ymd(2015, 9, 5); /// let d = NaiveDate::from_ymd(2015, 9, 5);
/// assert_eq!(d.checked_sub(Duration::days(40)), Some(NaiveDate::from_ymd(2015, 7, 27))); /// assert_eq!(d.checked_sub_signed(Duration::days(40)),
/// assert_eq!(d.checked_sub(Duration::days(-40)), Some(NaiveDate::from_ymd(2015, 10, 15))); /// Some(NaiveDate::from_ymd(2015, 7, 27)));
/// assert_eq!(d.checked_sub(Duration::days(1_000_000_000)), None); /// assert_eq!(d.checked_sub_signed(Duration::days(-40)),
/// assert_eq!(d.checked_sub(Duration::days(-1_000_000_000)), None); /// Some(NaiveDate::from_ymd(2015, 10, 15)));
/// assert_eq!(MIN.checked_sub(Duration::days(1)), None); /// assert_eq!(d.checked_sub_signed(Duration::days(1_000_000_000)), None);
/// assert_eq!(d.checked_sub_signed(Duration::days(-1_000_000_000)), None);
/// assert_eq!(MIN.checked_sub_signed(Duration::days(1)), None);
/// # }
/// ~~~~ /// ~~~~
pub fn checked_sub(self, rhs: Duration) -> Option<NaiveDate> { pub fn checked_sub_signed(self, rhs: OldDuration) -> Option<NaiveDate> {
let year = self.year(); let year = self.year();
let (mut year_div_400, year_mod_400) = div_mod_floor(year, 400); let (mut year_div_400, year_mod_400) = div_mod_floor(year, 400);
let cycle = internals::yo_to_cycle(year_mod_400 as u32, self.of().ordinal()); let cycle = internals::yo_to_cycle(year_mod_400 as u32, self.of().ordinal());
@ -853,6 +863,42 @@ impl NaiveDate {
Of::new(ordinal, flags)) Of::new(ordinal, flags))
} }
/// Subtracts another `NaiveDate` from the current date.
/// Returns a `Duration` of integral numbers.
///
/// This does not overflow or underflow at all,
/// as all possible output fits in the range of `Duration`.
///
/// # Example
///
/// ~~~~
/// # extern crate chrono; extern crate time; fn main() {
/// use chrono::NaiveDate;
/// use time::Duration;
///
/// let from_ymd = NaiveDate::from_ymd;
/// let since = NaiveDate::signed_duration_since;
///
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2014, 1, 1)), Duration::zero());
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2013, 12, 31)), Duration::days(1));
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2014, 1, 2)), Duration::days(-1));
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2013, 9, 23)), Duration::days(100));
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2013, 1, 1)), Duration::days(365));
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2010, 1, 1)), Duration::days(365*4 + 1));
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(1614, 1, 1)), Duration::days(365*400 + 97));
/// # }
/// ~~~~
pub fn signed_duration_since(self, rhs: NaiveDate) -> OldDuration {
let year1 = self.year();
let year2 = rhs.year();
let (year1_div_400, year1_mod_400) = div_mod_floor(year1, 400);
let (year2_div_400, year2_mod_400) = div_mod_floor(year2, 400);
let cycle1 = internals::yo_to_cycle(year1_mod_400 as u32, self.of().ordinal()) as i64;
let cycle2 = internals::yo_to_cycle(year2_mod_400 as u32, rhs.of().ordinal()) as i64;
OldDuration::days((year1_div_400 as i64 - year2_div_400 as i64) * 146097 +
(cycle1 - cycle2))
}
/// Formats the date with the specified formatting items. /// Formats the date with the specified formatting items.
/// Otherwise it is same to the ordinary `format` method. /// Otherwise it is same to the ordinary `format` method.
/// ///
@ -1290,12 +1336,14 @@ impl hash::Hash for NaiveDate {
/// rounding to the closest integral number of days towards `Duration::zero()`. /// rounding to the closest integral number of days towards `Duration::zero()`.
/// ///
/// Panics on underflow or overflow. /// Panics on underflow or overflow.
/// Use [`NaiveDate::checked_add`](#method.checked_add) to detect that. /// Use [`NaiveDate::checked_add_signed`](#method.checked_add_signed) to detect that.
/// ///
/// # Example /// # Example
/// ///
/// ~~~~ /// ~~~~
/// use chrono::{NaiveDate, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// use chrono::NaiveDate;
/// use time::Duration;
/// ///
/// let from_ymd = NaiveDate::from_ymd; /// let from_ymd = NaiveDate::from_ymd;
/// ///
@ -1307,47 +1355,14 @@ impl hash::Hash for NaiveDate {
/// assert_eq!(from_ymd(2014, 1, 1) + Duration::days(364), from_ymd(2014, 12, 31)); /// assert_eq!(from_ymd(2014, 1, 1) + Duration::days(364), from_ymd(2014, 12, 31));
/// assert_eq!(from_ymd(2014, 1, 1) + Duration::days(365*4 + 1), from_ymd(2018, 1, 1)); /// assert_eq!(from_ymd(2014, 1, 1) + Duration::days(365*4 + 1), from_ymd(2018, 1, 1));
/// assert_eq!(from_ymd(2014, 1, 1) + Duration::days(365*400 + 97), from_ymd(2414, 1, 1)); /// assert_eq!(from_ymd(2014, 1, 1) + Duration::days(365*400 + 97), from_ymd(2414, 1, 1));
/// # }
/// ~~~~ /// ~~~~
impl Add<Duration> for NaiveDate { impl Add<OldDuration> for NaiveDate {
type Output = NaiveDate; type Output = NaiveDate;
#[inline] #[inline]
fn add(self, rhs: Duration) -> NaiveDate { fn add(self, rhs: OldDuration) -> NaiveDate {
self.checked_add(rhs).expect("`NaiveDate + Duration` overflowed") self.checked_add_signed(rhs).expect("`NaiveDate + Duration` overflowed")
}
}
/// A subtraction of `NaiveDate` from `NaiveDate` yields a `Duration` of integral numbers.
///
/// This does not overflow or underflow at all,
/// as all possible output fits in the range of `Duration`.
///
/// # Example
///
/// ~~~~
/// use chrono::{NaiveDate, Duration};
///
/// let from_ymd = NaiveDate::from_ymd;
///
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2014, 1, 1), Duration::zero());
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 12, 31), Duration::days(1));
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2014, 1, 2), Duration::days(-1));
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 9, 23), Duration::days(100));
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 1, 1), Duration::days(365));
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2010, 1, 1), Duration::days(365*4 + 1));
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(1614, 1, 1), Duration::days(365*400 + 97));
/// ~~~~
impl Sub<NaiveDate> for NaiveDate {
type Output = Duration;
fn sub(self, rhs: NaiveDate) -> Duration {
let year1 = self.year();
let year2 = rhs.year();
let (year1_div_400, year1_mod_400) = div_mod_floor(year1, 400);
let (year2_div_400, year2_mod_400) = div_mod_floor(year2, 400);
let cycle1 = internals::yo_to_cycle(year1_mod_400 as u32, self.of().ordinal()) as i64;
let cycle2 = internals::yo_to_cycle(year2_mod_400 as u32, rhs.of().ordinal()) as i64;
Duration::days((year1_div_400 as i64 - year2_div_400 as i64) * 146097 + (cycle1 - cycle2))
} }
} }
@ -1356,12 +1371,14 @@ impl Sub<NaiveDate> for NaiveDate {
/// It is same to the addition with a negated `Duration`. /// It is same to the addition with a negated `Duration`.
/// ///
/// Panics on underflow or overflow. /// Panics on underflow or overflow.
/// Use [`NaiveDate::checked_sub`](#method.checked_sub) to detect that. /// Use [`NaiveDate::checked_sub_signed`](#method.checked_sub_signed) to detect that.
/// ///
/// # Example /// # Example
/// ///
/// ~~~~ /// ~~~~
/// use chrono::{NaiveDate, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// use chrono::NaiveDate;
/// use time::Duration;
/// ///
/// let from_ymd = NaiveDate::from_ymd; /// let from_ymd = NaiveDate::from_ymd;
/// ///
@ -1373,13 +1390,14 @@ impl Sub<NaiveDate> for NaiveDate {
/// assert_eq!(from_ymd(2014, 1, 1) - Duration::days(364), from_ymd(2013, 1, 2)); /// assert_eq!(from_ymd(2014, 1, 1) - Duration::days(364), from_ymd(2013, 1, 2));
/// assert_eq!(from_ymd(2014, 1, 1) - Duration::days(365*4 + 1), from_ymd(2010, 1, 1)); /// assert_eq!(from_ymd(2014, 1, 1) - Duration::days(365*4 + 1), from_ymd(2010, 1, 1));
/// assert_eq!(from_ymd(2014, 1, 1) - Duration::days(365*400 + 97), from_ymd(1614, 1, 1)); /// assert_eq!(from_ymd(2014, 1, 1) - Duration::days(365*400 + 97), from_ymd(1614, 1, 1));
/// # }
/// ~~~~ /// ~~~~
impl Sub<Duration> for NaiveDate { impl Sub<OldDuration> for NaiveDate {
type Output = NaiveDate; type Output = NaiveDate;
#[inline] #[inline]
fn sub(self, rhs: Duration) -> NaiveDate { fn sub(self, rhs: OldDuration) -> NaiveDate {
self.checked_sub(rhs).expect("`NaiveDate - Duration` overflowed") self.checked_sub_signed(rhs).expect("`NaiveDate - Duration` overflowed")
} }
} }
@ -1674,8 +1692,8 @@ mod tests {
use super::{MIN, MIN_YEAR, MIN_DAYS_FROM_YEAR_0}; use super::{MIN, MIN_YEAR, MIN_DAYS_FROM_YEAR_0};
use super::{MAX, MAX_YEAR, MAX_DAYS_FROM_YEAR_0}; use super::{MAX, MAX_YEAR, MAX_DAYS_FROM_YEAR_0};
use {Datelike, Weekday}; use {Datelike, Weekday};
use duration::Duration;
use std::{i32, u32}; use std::{i32, u32};
use oldtime::Duration;
#[test] #[test]
fn test_date_from_ymd() { fn test_date_from_ymd() {
@ -1938,8 +1956,8 @@ mod tests {
fn check((y1,m1,d1): (i32, u32, u32), rhs: Duration, ymd: Option<(i32, u32, u32)>) { fn check((y1,m1,d1): (i32, u32, u32), rhs: Duration, ymd: Option<(i32, u32, u32)>) {
let lhs = NaiveDate::from_ymd(y1, m1, d1); let lhs = NaiveDate::from_ymd(y1, m1, d1);
let sum = ymd.map(|(y,m,d)| NaiveDate::from_ymd(y, m, d)); let sum = ymd.map(|(y,m,d)| NaiveDate::from_ymd(y, m, d));
assert_eq!(lhs.checked_add(rhs), sum); assert_eq!(lhs.checked_add_signed(rhs), sum);
assert_eq!(lhs.checked_sub(-rhs), sum); assert_eq!(lhs.checked_sub_signed(-rhs), sum);
} }
check((2014, 1, 1), Duration::zero(), Some((2014, 1, 1))); check((2014, 1, 1), Duration::zero(), Some((2014, 1, 1)));
@ -1968,8 +1986,8 @@ mod tests {
fn check((y1,m1,d1): (i32, u32, u32), (y2,m2,d2): (i32, u32, u32), diff: Duration) { fn check((y1,m1,d1): (i32, u32, u32), (y2,m2,d2): (i32, u32, u32), diff: Duration) {
let lhs = NaiveDate::from_ymd(y1, m1, d1); let lhs = NaiveDate::from_ymd(y1, m1, d1);
let rhs = NaiveDate::from_ymd(y2, m2, d2); let rhs = NaiveDate::from_ymd(y2, m2, d2);
assert_eq!(lhs - rhs, diff); assert_eq!(lhs.signed_duration_since(rhs), diff);
assert_eq!(rhs - lhs, -diff); assert_eq!(rhs.signed_duration_since(lhs), -diff);
} }
check((2014, 1, 1), (2014, 1, 1), Duration::zero()); check((2014, 1, 1), (2014, 1, 1), Duration::zero());

View File

@ -6,10 +6,10 @@
use std::{str, fmt, hash}; use std::{str, fmt, hash};
use std::ops::{Add, Sub}; use std::ops::{Add, Sub};
use num::traits::ToPrimitive; use num::traits::ToPrimitive;
use oldtime::Duration as OldDuration;
use {Weekday, Timelike, Datelike}; use {Weekday, Timelike, Datelike};
use div::div_mod_floor; use div::div_mod_floor;
use duration::Duration;
use naive::time::NaiveTime; use naive::time::NaiveTime;
use naive::date::NaiveDate; use naive::date::NaiveDate;
use format::{Item, Numeric, Pad, Fixed}; use format::{Item, Numeric, Pad, Fixed};
@ -144,14 +144,16 @@ impl NaiveDateTime {
} }
} }
/// *Deprecated:* Same to [`NaiveDateTime::from_timestamp`](#method.from_timestamp). /// Same to [`NaiveDateTime::from_timestamp`](#method.from_timestamp).
#[inline] #[inline]
#[deprecated(since = "0.2.0", note = "Renamed to `from_timestamp`")]
pub fn from_num_seconds_from_unix_epoch(secs: i64, nsecs: u32) -> NaiveDateTime { pub fn from_num_seconds_from_unix_epoch(secs: i64, nsecs: u32) -> NaiveDateTime {
NaiveDateTime::from_timestamp(secs, nsecs) NaiveDateTime::from_timestamp(secs, nsecs)
} }
/// *Deprecated:* Same to [`NaiveDateTime::from_timestamp_opt`](#method.from_timestamp_opt). /// Same to [`NaiveDateTime::from_timestamp_opt`](#method.from_timestamp_opt).
#[inline] #[inline]
#[deprecated(since = "0.2.0", note = "Renamed to `from_timestamp_opt`")]
pub fn from_num_seconds_from_unix_epoch_opt(secs: i64, nsecs: u32) -> Option<NaiveDateTime> { pub fn from_num_seconds_from_unix_epoch_opt(secs: i64, nsecs: u32) -> Option<NaiveDateTime> {
NaiveDateTime::from_timestamp_opt(secs, nsecs) NaiveDateTime::from_timestamp_opt(secs, nsecs)
} }
@ -339,8 +341,9 @@ impl NaiveDateTime {
self.time.nanosecond() self.time.nanosecond()
} }
/// *Deprecated:* Same to [`NaiveDateTime::timestamp`](#method.timestamp). /// Same to [`NaiveDateTime::timestamp`](#method.timestamp).
#[inline] #[inline]
#[deprecated(since = "0.2.0", note = "Renamed to `timestamp`")]
pub fn num_seconds_from_unix_epoch(&self) -> i64 { pub fn num_seconds_from_unix_epoch(&self) -> i64 {
self.timestamp() self.timestamp()
} }
@ -357,58 +360,77 @@ impl NaiveDateTime {
/// # Example /// # Example
/// ///
/// ~~~~ /// ~~~~
/// use chrono::{NaiveDate, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// use chrono::NaiveDate;
/// use time::Duration;
/// ///
/// let from_ymd = NaiveDate::from_ymd; /// let from_ymd = NaiveDate::from_ymd;
/// ///
/// let d = from_ymd(2016, 7, 8); /// let d = from_ymd(2016, 7, 8);
/// let hms = |h, m, s| d.and_hms(h, m, s); /// let hms = |h, m, s| d.and_hms(h, m, s);
/// assert_eq!(hms(3, 5, 7).checked_add(Duration::zero()), Some(hms(3, 5, 7))); /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::zero()),
/// assert_eq!(hms(3, 5, 7).checked_add(Duration::seconds(1)), Some(hms(3, 5, 8))); /// Some(hms(3, 5, 7)));
/// assert_eq!(hms(3, 5, 7).checked_add(Duration::seconds(-1)), Some(hms(3, 5, 6))); /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::seconds(1)),
/// assert_eq!(hms(3, 5, 7).checked_add(Duration::seconds(3600 + 60)), Some(hms(4, 6, 7))); /// Some(hms(3, 5, 8)));
/// assert_eq!(hms(3, 5, 7).checked_add(Duration::seconds(86400)), /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::seconds(-1)),
/// Some(hms(3, 5, 6)));
/// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::seconds(3600 + 60)),
/// Some(hms(4, 6, 7)));
/// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::seconds(86400)),
/// Some(from_ymd(2016, 7, 9).and_hms(3, 5, 7))); /// Some(from_ymd(2016, 7, 9).and_hms(3, 5, 7)));
/// ///
/// let hmsm = |h, m, s, milli| d.and_hms_milli(h, m, s, milli); /// let hmsm = |h, m, s, milli| d.and_hms_milli(h, m, s, milli);
/// assert_eq!(hmsm(3, 5, 7, 980).checked_add(Duration::milliseconds(450)), /// assert_eq!(hmsm(3, 5, 7, 980).checked_add_signed(Duration::milliseconds(450)),
/// Some(hmsm(3, 5, 8, 430))); /// Some(hmsm(3, 5, 8, 430)));
/// # }
/// ~~~~ /// ~~~~
/// ///
/// Overflow returns `None`. /// Overflow returns `None`.
/// ///
/// ~~~~ /// ~~~~
/// # use chrono::{NaiveDate, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// # use chrono::NaiveDate;
/// # use time::Duration;
/// # let hms = |h, m, s| NaiveDate::from_ymd(2016, 7, 8).and_hms(h, m, s); /// # let hms = |h, m, s| NaiveDate::from_ymd(2016, 7, 8).and_hms(h, m, s);
/// assert_eq!(hms(3, 5, 7).checked_add(Duration::days(1_000_000_000)), None); /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::days(1_000_000_000)), None);
/// # }
/// ~~~~ /// ~~~~
/// ///
/// Leap seconds are handled, /// Leap seconds are handled,
/// but the addition assumes that it is the only leap second happened. /// but the addition assumes that it is the only leap second happened.
/// ///
/// ~~~~ /// ~~~~
/// # use chrono::{NaiveDate, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// # use chrono::NaiveDate;
/// # use time::Duration;
/// # let from_ymd = NaiveDate::from_ymd; /// # let from_ymd = NaiveDate::from_ymd;
/// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli(h, m, s, milli); /// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli(h, m, s, milli);
/// let leap = hmsm(3, 5, 59, 1_300); /// let leap = hmsm(3, 5, 59, 1_300);
/// assert_eq!(leap.checked_add(Duration::zero()), Some(hmsm(3, 5, 59, 1_300))); /// assert_eq!(leap.checked_add_signed(Duration::zero()),
/// assert_eq!(leap.checked_add(Duration::milliseconds(-500)), Some(hmsm(3, 5, 59, 800))); /// Some(hmsm(3, 5, 59, 1_300)));
/// assert_eq!(leap.checked_add(Duration::milliseconds(500)), Some(hmsm(3, 5, 59, 1_800))); /// assert_eq!(leap.checked_add_signed(Duration::milliseconds(-500)),
/// assert_eq!(leap.checked_add(Duration::milliseconds(800)), Some(hmsm(3, 6, 0, 100))); /// Some(hmsm(3, 5, 59, 800)));
/// assert_eq!(leap.checked_add(Duration::seconds(10)), Some(hmsm(3, 6, 9, 300))); /// assert_eq!(leap.checked_add_signed(Duration::milliseconds(500)),
/// assert_eq!(leap.checked_add(Duration::seconds(-10)), Some(hmsm(3, 5, 50, 300))); /// Some(hmsm(3, 5, 59, 1_800)));
/// assert_eq!(leap.checked_add(Duration::days(1)), /// assert_eq!(leap.checked_add_signed(Duration::milliseconds(800)),
/// Some(hmsm(3, 6, 0, 100)));
/// assert_eq!(leap.checked_add_signed(Duration::seconds(10)),
/// Some(hmsm(3, 6, 9, 300)));
/// assert_eq!(leap.checked_add_signed(Duration::seconds(-10)),
/// Some(hmsm(3, 5, 50, 300)));
/// assert_eq!(leap.checked_add_signed(Duration::days(1)),
/// Some(from_ymd(2016, 7, 9).and_hms_milli(3, 5, 59, 300))); /// Some(from_ymd(2016, 7, 9).and_hms_milli(3, 5, 59, 300)));
/// # }
/// ~~~~ /// ~~~~
pub fn checked_add(self, rhs: Duration) -> Option<NaiveDateTime> { pub fn checked_add_signed(self, rhs: OldDuration) -> Option<NaiveDateTime> {
let (time, rhs) = self.time.overflowing_add(rhs); let (time, rhs) = self.time.overflowing_add_signed(rhs);
// early checking to avoid overflow in Duration::seconds // early checking to avoid overflow in OldDuration::seconds
if rhs <= (-1 << MAX_SECS_BITS) || rhs >= (1 << MAX_SECS_BITS) { if rhs <= (-1 << MAX_SECS_BITS) || rhs >= (1 << MAX_SECS_BITS) {
return None; return None;
} }
let date = try_opt!(self.date.checked_add(Duration::seconds(rhs))); let date = try_opt!(self.date.checked_add_signed(OldDuration::seconds(rhs)));
Some(NaiveDateTime { date: date, time: time }) Some(NaiveDateTime { date: date, time: time })
} }
@ -424,59 +446,142 @@ impl NaiveDateTime {
/// # Example /// # Example
/// ///
/// ~~~~ /// ~~~~
/// use chrono::{NaiveDate, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// use chrono::NaiveDate;
/// use time::Duration;
/// ///
/// let from_ymd = NaiveDate::from_ymd; /// let from_ymd = NaiveDate::from_ymd;
/// ///
/// let d = from_ymd(2016, 7, 8); /// let d = from_ymd(2016, 7, 8);
/// let hms = |h, m, s| d.and_hms(h, m, s); /// let hms = |h, m, s| d.and_hms(h, m, s);
/// assert_eq!(hms(3, 5, 7).checked_sub(Duration::zero()), Some(hms(3, 5, 7))); /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::zero()),
/// assert_eq!(hms(3, 5, 7).checked_sub(Duration::seconds(1)), Some(hms(3, 5, 6))); /// Some(hms(3, 5, 7)));
/// assert_eq!(hms(3, 5, 7).checked_sub(Duration::seconds(-1)), Some(hms(3, 5, 8))); /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::seconds(1)),
/// assert_eq!(hms(3, 5, 7).checked_sub(Duration::seconds(3600 + 60)), Some(hms(2, 4, 7))); /// Some(hms(3, 5, 6)));
/// assert_eq!(hms(3, 5, 7).checked_sub(Duration::seconds(86400)), /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::seconds(-1)),
/// Some(hms(3, 5, 8)));
/// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::seconds(3600 + 60)),
/// Some(hms(2, 4, 7)));
/// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::seconds(86400)),
/// Some(from_ymd(2016, 7, 7).and_hms(3, 5, 7))); /// Some(from_ymd(2016, 7, 7).and_hms(3, 5, 7)));
/// ///
/// let hmsm = |h, m, s, milli| d.and_hms_milli(h, m, s, milli); /// let hmsm = |h, m, s, milli| d.and_hms_milli(h, m, s, milli);
/// assert_eq!(hmsm(3, 5, 7, 450).checked_sub(Duration::milliseconds(670)), /// assert_eq!(hmsm(3, 5, 7, 450).checked_sub_signed(Duration::milliseconds(670)),
/// Some(hmsm(3, 5, 6, 780))); /// Some(hmsm(3, 5, 6, 780)));
/// # }
/// ~~~~ /// ~~~~
/// ///
/// Overflow returns `None`. /// Overflow returns `None`.
/// ///
/// ~~~~ /// ~~~~
/// # use chrono::{NaiveDate, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// # use chrono::NaiveDate;
/// # use time::Duration;
/// # let hms = |h, m, s| NaiveDate::from_ymd(2016, 7, 8).and_hms(h, m, s); /// # let hms = |h, m, s| NaiveDate::from_ymd(2016, 7, 8).and_hms(h, m, s);
/// assert_eq!(hms(3, 5, 7).checked_sub(Duration::days(1_000_000_000)), None); /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::days(1_000_000_000)), None);
/// # }
/// ~~~~ /// ~~~~
/// ///
/// Leap seconds are handled, /// Leap seconds are handled,
/// but the subtraction assumes that it is the only leap second happened. /// but the subtraction assumes that it is the only leap second happened.
/// ///
/// ~~~~ /// ~~~~
/// # use chrono::{NaiveDate, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// # use chrono::NaiveDate;
/// # use time::Duration;
/// # let from_ymd = NaiveDate::from_ymd; /// # let from_ymd = NaiveDate::from_ymd;
/// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli(h, m, s, milli); /// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli(h, m, s, milli);
/// let leap = hmsm(3, 5, 59, 1_300); /// let leap = hmsm(3, 5, 59, 1_300);
/// assert_eq!(leap.checked_sub(Duration::zero()), Some(hmsm(3, 5, 59, 1_300))); /// assert_eq!(leap.checked_sub_signed(Duration::zero()),
/// assert_eq!(leap.checked_sub(Duration::milliseconds(200)), Some(hmsm(3, 5, 59, 1_100))); /// Some(hmsm(3, 5, 59, 1_300)));
/// assert_eq!(leap.checked_sub(Duration::milliseconds(500)), Some(hmsm(3, 5, 59, 800))); /// assert_eq!(leap.checked_sub_signed(Duration::milliseconds(200)),
/// assert_eq!(leap.checked_sub(Duration::seconds(60)), Some(hmsm(3, 5, 0, 300))); /// Some(hmsm(3, 5, 59, 1_100)));
/// assert_eq!(leap.checked_sub(Duration::days(1)), /// assert_eq!(leap.checked_sub_signed(Duration::milliseconds(500)),
/// Some(hmsm(3, 5, 59, 800)));
/// assert_eq!(leap.checked_sub_signed(Duration::seconds(60)),
/// Some(hmsm(3, 5, 0, 300)));
/// assert_eq!(leap.checked_sub_signed(Duration::days(1)),
/// Some(from_ymd(2016, 7, 7).and_hms_milli(3, 6, 0, 300))); /// Some(from_ymd(2016, 7, 7).and_hms_milli(3, 6, 0, 300)));
/// # }
/// ~~~~ /// ~~~~
pub fn checked_sub(self, rhs: Duration) -> Option<NaiveDateTime> { pub fn checked_sub_signed(self, rhs: OldDuration) -> Option<NaiveDateTime> {
let (time, rhs) = self.time.overflowing_sub(rhs); let (time, rhs) = self.time.overflowing_sub_signed(rhs);
// early checking to avoid overflow in Duration::seconds // early checking to avoid overflow in OldDuration::seconds
if rhs <= (-1 << MAX_SECS_BITS) || rhs >= (1 << MAX_SECS_BITS) { if rhs <= (-1 << MAX_SECS_BITS) || rhs >= (1 << MAX_SECS_BITS) {
return None; return None;
} }
let date = try_opt!(self.date.checked_sub(Duration::seconds(rhs))); let date = try_opt!(self.date.checked_sub_signed(OldDuration::seconds(rhs)));
Some(NaiveDateTime { date: date, time: time }) Some(NaiveDateTime { date: date, time: time })
} }
/// Subtracts another `NaiveDateTime` from the current date and time.
/// This does not overflow or underflow at all.
///
/// As a part of Chrono's [leap second handling](../time/index.html#leap-second-handling),
/// the subtraction assumes that **there is no leap second ever**,
/// except when any of the `NaiveDateTime`s themselves represents a leap second
/// in which case the assumption becomes that
/// **there are exactly one (or two) leap second(s) ever**.
///
/// # Example
///
/// ~~~~
/// # extern crate chrono; extern crate time; fn main() {
/// use chrono::NaiveDate;
/// use time::Duration;
///
/// let from_ymd = NaiveDate::from_ymd;
///
/// let d = from_ymd(2016, 7, 8);
/// assert_eq!(d.and_hms(3, 5, 7).signed_duration_since(d.and_hms(2, 4, 6)),
/// Duration::seconds(3600 + 60 + 1));
///
/// // July 8 is 190th day in the year 2016
/// let d0 = from_ymd(2016, 1, 1);
/// assert_eq!(d.and_hms_milli(0, 7, 6, 500).signed_duration_since(d0.and_hms(0, 0, 0)),
/// Duration::seconds(189 * 86400 + 7 * 60 + 6) + Duration::milliseconds(500));
/// # }
/// ~~~~
///
/// Leap seconds are handled, but the subtraction assumes that
/// there were no other leap seconds happened.
///
/// ~~~~
/// # extern crate chrono; extern crate time; fn main() {
/// # use chrono::NaiveDate;
/// # use time::Duration;
/// # let from_ymd = NaiveDate::from_ymd;
/// let leap = from_ymd(2015, 6, 30).and_hms_milli(23, 59, 59, 1_500);
/// assert_eq!(leap.signed_duration_since(from_ymd(2015, 6, 30).and_hms(23, 0, 0)),
/// Duration::seconds(3600) + Duration::milliseconds(500));
/// assert_eq!(from_ymd(2015, 7, 1).and_hms(1, 0, 0).signed_duration_since(leap),
/// Duration::seconds(3600) - Duration::milliseconds(500));
/// # }
/// ~~~~
pub fn signed_duration_since(self, rhs: NaiveDateTime) -> OldDuration {
self.date.signed_duration_since(rhs.date) + self.time.signed_duration_since(rhs.time)
}
/// Same to [`NaiveDateTime::checked_add_signed`](#method.checked_add_signed).
#[inline]
#[deprecated(since = "0.2.26",
note = "Renamed to `checked_add_signed`, \
will be replaced with a version with `std::time::Duration`")]
pub fn checked_add(self, rhs: OldDuration) -> Option<NaiveDateTime> {
self.checked_add_signed(rhs)
}
/// Same to [`NaiveDateTime::checked_sub_signed`](#method.checked_sub_signed).
#[inline]
#[deprecated(since = "0.2.26",
note = "Renamed to `checked_sub_signed`, \
will be replaced with a version with `std::time::Duration`")]
pub fn checked_sub(self, rhs: OldDuration) -> Option<NaiveDateTime> {
self.checked_sub_signed(rhs)
}
/// Formats the combined date and time with the specified formatting items. /// Formats the combined date and time with the specified formatting items.
/// Otherwise it is same to the ordinary [`format`](#method.format) method. /// Otherwise it is same to the ordinary [`format`](#method.format) method.
/// ///
@ -1053,12 +1158,14 @@ impl hash::Hash for NaiveDateTime {
/// in which case the assumption becomes that **there is exactly a single leap second ever**. /// in which case the assumption becomes that **there is exactly a single leap second ever**.
/// ///
/// Panics on underflow or overflow. /// Panics on underflow or overflow.
/// Use [`NaiveDateTime::checked_add`](#method.checked_add) to detect that. /// Use [`NaiveDateTime::checked_add_signed`](#method.checked_add_signed) to detect that.
/// ///
/// # Example /// # Example
/// ///
/// ~~~~ /// ~~~~
/// use chrono::{NaiveDate, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// use chrono::NaiveDate;
/// use time::Duration;
/// ///
/// let from_ymd = NaiveDate::from_ymd; /// let from_ymd = NaiveDate::from_ymd;
/// ///
@ -1075,13 +1182,16 @@ impl hash::Hash for NaiveDateTime {
/// ///
/// let hmsm = |h, m, s, milli| d.and_hms_milli(h, m, s, milli); /// let hmsm = |h, m, s, milli| d.and_hms_milli(h, m, s, milli);
/// assert_eq!(hmsm(3, 5, 7, 980) + Duration::milliseconds(450), hmsm(3, 5, 8, 430)); /// assert_eq!(hmsm(3, 5, 7, 980) + Duration::milliseconds(450), hmsm(3, 5, 8, 430));
/// # }
/// ~~~~ /// ~~~~
/// ///
/// Leap seconds are handled, /// Leap seconds are handled,
/// but the addition assumes that it is the only leap second happened. /// but the addition assumes that it is the only leap second happened.
/// ///
/// ~~~~ /// ~~~~
/// # use chrono::{NaiveDate, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// # use chrono::NaiveDate;
/// # use time::Duration;
/// # let from_ymd = NaiveDate::from_ymd; /// # let from_ymd = NaiveDate::from_ymd;
/// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli(h, m, s, milli); /// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli(h, m, s, milli);
/// let leap = hmsm(3, 5, 59, 1_300); /// let leap = hmsm(3, 5, 59, 1_300);
@ -1093,59 +1203,26 @@ impl hash::Hash for NaiveDateTime {
/// assert_eq!(leap + Duration::seconds(-10), hmsm(3, 5, 50, 300)); /// assert_eq!(leap + Duration::seconds(-10), hmsm(3, 5, 50, 300));
/// assert_eq!(leap + Duration::days(1), /// assert_eq!(leap + Duration::days(1),
/// from_ymd(2016, 7, 9).and_hms_milli(3, 5, 59, 300)); /// from_ymd(2016, 7, 9).and_hms_milli(3, 5, 59, 300));
/// # }
/// ~~~~ /// ~~~~
impl Add<Duration> for NaiveDateTime { impl Add<OldDuration> for NaiveDateTime {
type Output = NaiveDateTime; type Output = NaiveDateTime;
#[inline] #[inline]
fn add(self, rhs: Duration) -> NaiveDateTime { fn add(self, rhs: OldDuration) -> NaiveDateTime {
self.checked_add(rhs).expect("`NaiveDateTime + Duration` overflowed") self.checked_add_signed(rhs).expect("`NaiveDateTime + Duration` overflowed")
} }
} }
/// A subtraction of `NaiveDateTime` from `NaiveDateTime` yields a `Duration`. /// Use [`NaiveDateTime::signed_duration_since`](#method.signed_duration_since) instead.
/// This does not overflow or underflow at all. // XXX this does not really work yet
/// #[deprecated(since = "0.2.26", note = "Use `signed_duration_since` method instead")]
/// As a part of Chrono's [leap second handling](../time/index.html#leap-second-handling),
/// the subtraction assumes that **there is no leap second ever**,
/// except when any of the `NaiveDateTime`s themselves represents a leap second
/// in which case the assumption becomes that
/// **there are exactly one (or two) leap second(s) ever**.
///
/// # Example
///
/// ~~~~
/// use chrono::{NaiveDate, Duration};
///
/// let from_ymd = NaiveDate::from_ymd;
///
/// let d = from_ymd(2016, 7, 8);
/// assert_eq!(d.and_hms(3, 5, 7) - d.and_hms(2, 4, 6),
/// Duration::seconds(3600 + 60 + 1));
///
/// // July 8 is 190th day in the year 2016
/// let d0 = from_ymd(2016, 1, 1);
/// assert_eq!(d.and_hms_milli(0, 7, 6, 500) - d0.and_hms(0, 0, 0),
/// Duration::seconds(189 * 86400 + 7 * 60 + 6) + Duration::milliseconds(500));
/// ~~~~
///
/// Leap seconds are handled, but the subtraction assumes that
/// there were no other leap seconds happened.
///
/// ~~~~
/// # use chrono::{NaiveDate, Duration};
/// # let from_ymd = NaiveDate::from_ymd;
/// let leap = from_ymd(2015, 6, 30).and_hms_milli(23, 59, 59, 1_500);
/// assert_eq!(leap - from_ymd(2015, 6, 30).and_hms(23, 0, 0),
/// Duration::seconds(3600) + Duration::milliseconds(500));
/// assert_eq!(from_ymd(2015, 7, 1).and_hms(1, 0, 0) - leap,
/// Duration::seconds(3600) - Duration::milliseconds(500));
/// ~~~~
impl Sub<NaiveDateTime> for NaiveDateTime { impl Sub<NaiveDateTime> for NaiveDateTime {
type Output = Duration; type Output = OldDuration;
fn sub(self, rhs: NaiveDateTime) -> Duration { #[inline]
(self.date - rhs.date) + (self.time - rhs.time) fn sub(self, rhs: NaiveDateTime) -> OldDuration {
self.signed_duration_since(rhs)
} }
} }
@ -1158,12 +1235,14 @@ impl Sub<NaiveDateTime> for NaiveDateTime {
/// in which case the assumption becomes that **there is exactly a single leap second ever**. /// in which case the assumption becomes that **there is exactly a single leap second ever**.
/// ///
/// Panics on underflow or overflow. /// Panics on underflow or overflow.
/// Use [`NaiveDateTime::checked_sub`](#method.checked_sub) to detect that. /// Use [`NaiveDateTime::checked_sub_signed`](#method.checked_sub_signed) to detect that.
/// ///
/// # Example /// # Example
/// ///
/// ~~~~ /// ~~~~
/// use chrono::{NaiveDate, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// use chrono::NaiveDate;
/// use time::Duration;
/// ///
/// let from_ymd = NaiveDate::from_ymd; /// let from_ymd = NaiveDate::from_ymd;
/// ///
@ -1180,13 +1259,16 @@ impl Sub<NaiveDateTime> for NaiveDateTime {
/// ///
/// let hmsm = |h, m, s, milli| d.and_hms_milli(h, m, s, milli); /// let hmsm = |h, m, s, milli| d.and_hms_milli(h, m, s, milli);
/// assert_eq!(hmsm(3, 5, 7, 450) - Duration::milliseconds(670), hmsm(3, 5, 6, 780)); /// assert_eq!(hmsm(3, 5, 7, 450) - Duration::milliseconds(670), hmsm(3, 5, 6, 780));
/// # }
/// ~~~~ /// ~~~~
/// ///
/// Leap seconds are handled, /// Leap seconds are handled,
/// but the subtraction assumes that it is the only leap second happened. /// but the subtraction assumes that it is the only leap second happened.
/// ///
/// ~~~~ /// ~~~~
/// # use chrono::{NaiveDate, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// # use chrono::NaiveDate;
/// # use time::Duration;
/// # let from_ymd = NaiveDate::from_ymd; /// # let from_ymd = NaiveDate::from_ymd;
/// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli(h, m, s, milli); /// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli(h, m, s, milli);
/// let leap = hmsm(3, 5, 59, 1_300); /// let leap = hmsm(3, 5, 59, 1_300);
@ -1196,13 +1278,14 @@ impl Sub<NaiveDateTime> for NaiveDateTime {
/// assert_eq!(leap - Duration::seconds(60), hmsm(3, 5, 0, 300)); /// assert_eq!(leap - Duration::seconds(60), hmsm(3, 5, 0, 300));
/// assert_eq!(leap - Duration::days(1), /// assert_eq!(leap - Duration::days(1),
/// from_ymd(2016, 7, 7).and_hms_milli(3, 6, 0, 300)); /// from_ymd(2016, 7, 7).and_hms_milli(3, 6, 0, 300));
/// # }
/// ~~~~ /// ~~~~
impl Sub<Duration> for NaiveDateTime { impl Sub<OldDuration> for NaiveDateTime {
type Output = NaiveDateTime; type Output = NaiveDateTime;
#[inline] #[inline]
fn sub(self, rhs: Duration) -> NaiveDateTime { fn sub(self, rhs: OldDuration) -> NaiveDateTime {
self.checked_sub(rhs).expect("`NaiveDateTime - Duration` overflowed") self.checked_sub_signed(rhs).expect("`NaiveDateTime - Duration` overflowed")
} }
} }
@ -1557,10 +1640,10 @@ mod serde {
mod tests { mod tests {
use super::NaiveDateTime; use super::NaiveDateTime;
use Datelike; use Datelike;
use duration::Duration;
use naive::date as naive_date; use naive::date as naive_date;
use naive::date::NaiveDate; use naive::date::NaiveDate;
use std::i64; use std::i64;
use oldtime::Duration;
#[test] #[test]
fn test_datetime_from_timestamp() { fn test_datetime_from_timestamp() {
@ -1581,8 +1664,8 @@ mod tests {
result: Option<(i32,u32,u32,u32,u32,u32)>) { result: Option<(i32,u32,u32,u32,u32,u32)>) {
let lhs = NaiveDate::from_ymd(y, m, d).and_hms(h, n, s); let lhs = NaiveDate::from_ymd(y, m, d).and_hms(h, n, s);
let sum = result.map(|(y,m,d,h,n,s)| NaiveDate::from_ymd(y, m, d).and_hms(h, n, s)); let sum = result.map(|(y,m,d,h,n,s)| NaiveDate::from_ymd(y, m, d).and_hms(h, n, s));
assert_eq!(lhs.checked_add(rhs), sum); assert_eq!(lhs.checked_add_signed(rhs), sum);
assert_eq!(lhs.checked_sub(-rhs), sum); assert_eq!(lhs.checked_sub_signed(-rhs), sum);
}; };
check((2014,5,6, 7,8,9), Duration::seconds(3600 + 60 + 1), Some((2014,5,6, 8,9,10))); check((2014,5,6, 7,8,9), Duration::seconds(3600 + 60 + 1), Some((2014,5,6, 8,9,10)));
@ -1595,14 +1678,16 @@ mod tests {
// overflow check // overflow check
// assumes that we have correct values for MAX/MIN_DAYS_FROM_YEAR_0 from `naive::date`. // assumes that we have correct values for MAX/MIN_DAYS_FROM_YEAR_0 from `naive::date`.
// (they are private constants, but the equivalence is tested in that module.) // (they are private constants, but the equivalence is tested in that module.)
let max_days_from_year_0 = naive_date::MAX - NaiveDate::from_ymd(0,1,1); let max_days_from_year_0 =
naive_date::MAX.signed_duration_since(NaiveDate::from_ymd(0,1,1));
check((0,1,1, 0,0,0), max_days_from_year_0, Some((naive_date::MAX.year(),12,31, 0,0,0))); check((0,1,1, 0,0,0), max_days_from_year_0, Some((naive_date::MAX.year(),12,31, 0,0,0)));
check((0,1,1, 0,0,0), max_days_from_year_0 + Duration::seconds(86399), check((0,1,1, 0,0,0), max_days_from_year_0 + Duration::seconds(86399),
Some((naive_date::MAX.year(),12,31, 23,59,59))); Some((naive_date::MAX.year(),12,31, 23,59,59)));
check((0,1,1, 0,0,0), max_days_from_year_0 + Duration::seconds(86400), None); check((0,1,1, 0,0,0), max_days_from_year_0 + Duration::seconds(86400), None);
check((0,1,1, 0,0,0), Duration::max_value(), None); check((0,1,1, 0,0,0), Duration::max_value(), None);
let min_days_from_year_0 = naive_date::MIN - NaiveDate::from_ymd(0,1,1); let min_days_from_year_0 =
naive_date::MIN.signed_duration_since(NaiveDate::from_ymd(0,1,1));
check((0,1,1, 0,0,0), min_days_from_year_0, Some((naive_date::MIN.year(),1,1, 0,0,0))); check((0,1,1, 0,0,0), min_days_from_year_0, Some((naive_date::MIN.year(),1,1, 0,0,0)));
check((0,1,1, 0,0,0), min_days_from_year_0 - Duration::seconds(1), None); check((0,1,1, 0,0,0), min_days_from_year_0 - Duration::seconds(1), None);
check((0,1,1, 0,0,0), Duration::min_value(), None); check((0,1,1, 0,0,0), Duration::min_value(), None);
@ -1611,14 +1696,16 @@ mod tests {
#[test] #[test]
fn test_datetime_sub() { fn test_datetime_sub() {
let ymdhms = |y,m,d,h,n,s| NaiveDate::from_ymd(y,m,d).and_hms(h,n,s); let ymdhms = |y,m,d,h,n,s| NaiveDate::from_ymd(y,m,d).and_hms(h,n,s);
assert_eq!(ymdhms(2014, 5, 6, 7, 8, 9) - ymdhms(2014, 5, 6, 7, 8, 9), Duration::zero()); let since = NaiveDateTime::signed_duration_since;
assert_eq!(ymdhms(2014, 5, 6, 7, 8, 10) - ymdhms(2014, 5, 6, 7, 8, 9), assert_eq!(since(ymdhms(2014, 5, 6, 7, 8, 9), ymdhms(2014, 5, 6, 7, 8, 9)),
Duration::zero());
assert_eq!(since(ymdhms(2014, 5, 6, 7, 8, 10), ymdhms(2014, 5, 6, 7, 8, 9)),
Duration::seconds(1)); Duration::seconds(1));
assert_eq!(ymdhms(2014, 5, 6, 7, 8, 9) - ymdhms(2014, 5, 6, 7, 8, 10), assert_eq!(since(ymdhms(2014, 5, 6, 7, 8, 9), ymdhms(2014, 5, 6, 7, 8, 10)),
Duration::seconds(-1)); Duration::seconds(-1));
assert_eq!(ymdhms(2014, 5, 7, 7, 8, 9) - ymdhms(2014, 5, 6, 7, 8, 10), assert_eq!(since(ymdhms(2014, 5, 7, 7, 8, 9), ymdhms(2014, 5, 6, 7, 8, 10)),
Duration::seconds(86399)); Duration::seconds(86399));
assert_eq!(ymdhms(2001, 9, 9, 1, 46, 39) - ymdhms(1970, 1, 1, 0, 0, 0), assert_eq!(since(ymdhms(2001, 9, 9, 1, 46, 39), ymdhms(1970, 1, 1, 0, 0, 0)),
Duration::seconds(999_999_999)); Duration::seconds(999_999_999));
} }
@ -1704,6 +1791,6 @@ mod tests {
let base = NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0); let base = NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0);
let t = -946684799990000; let t = -946684799990000;
let time = base + Duration::microseconds(t); let time = base + Duration::microseconds(t);
assert_eq!(t, (time - base).num_microseconds().unwrap()); assert_eq!(t, time.signed_duration_since(base).num_microseconds().unwrap());
} }
} }

View File

@ -158,10 +158,10 @@
use std::{str, fmt, hash}; use std::{str, fmt, hash};
use std::ops::{Add, Sub}; use std::ops::{Add, Sub};
use oldtime::Duration as OldDuration;
use Timelike; use Timelike;
use div::div_mod_floor; use div::div_mod_floor;
use duration::Duration;
use format::{Item, Numeric, Pad, Fixed}; use format::{Item, Numeric, Pad, Fixed};
use format::{parse, Parsed, ParseError, ParseResult, DelayedFormat, StrftimeItems}; use format::{parse, Parsed, ParseError, ParseResult, DelayedFormat, StrftimeItems};
@ -522,18 +522,21 @@ impl NaiveTime {
/// # Example /// # Example
/// ///
/// ~~~~ /// ~~~~
/// use chrono::{NaiveTime, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// use chrono::NaiveTime;
/// use time::Duration;
/// ///
/// let from_hms = NaiveTime::from_hms; /// let from_hms = NaiveTime::from_hms;
/// ///
/// assert_eq!(from_hms(3, 4, 5).overflowing_add(Duration::hours(11)), /// assert_eq!(from_hms(3, 4, 5).overflowing_add_signed(Duration::hours(11)),
/// (from_hms(14, 4, 5), 0)); /// (from_hms(14, 4, 5), 0));
/// assert_eq!(from_hms(3, 4, 5).overflowing_add(Duration::hours(23)), /// assert_eq!(from_hms(3, 4, 5).overflowing_add_signed(Duration::hours(23)),
/// (from_hms(2, 4, 5), 86400)); /// (from_hms(2, 4, 5), 86400));
/// assert_eq!(from_hms(3, 4, 5).overflowing_add(Duration::hours(-7)), /// assert_eq!(from_hms(3, 4, 5).overflowing_add_signed(Duration::hours(-7)),
/// (from_hms(20, 4, 5), -86400)); /// (from_hms(20, 4, 5), -86400));
/// # }
/// ~~~~ /// ~~~~
pub fn overflowing_add(&self, mut rhs: Duration) -> (NaiveTime, i64) { pub fn overflowing_add_signed(&self, mut rhs: OldDuration) -> (NaiveTime, i64) {
let mut secs = self.secs; let mut secs = self.secs;
let mut frac = self.frac; let mut frac = self.frac;
@ -542,12 +545,12 @@ impl NaiveTime {
// otherwise the addition immediately finishes. // otherwise the addition immediately finishes.
if frac >= 1_000_000_000 { if frac >= 1_000_000_000 {
let rfrac = 2_000_000_000 - frac; let rfrac = 2_000_000_000 - frac;
if rhs >= Duration::nanoseconds(rfrac as i64) { if rhs >= OldDuration::nanoseconds(rfrac as i64) {
rhs = rhs - Duration::nanoseconds(rfrac as i64); rhs = rhs - OldDuration::nanoseconds(rfrac as i64);
secs += 1; secs += 1;
frac = 0; frac = 0;
} else if rhs < Duration::nanoseconds(-(frac as i64)) { } else if rhs < OldDuration::nanoseconds(-(frac as i64)) {
rhs = rhs + Duration::nanoseconds(frac as i64); rhs = rhs + OldDuration::nanoseconds(frac as i64);
frac = 0; frac = 0;
} else { } else {
frac = (frac as i64 + rhs.num_nanoseconds().unwrap()) as u32; frac = (frac as i64 + rhs.num_nanoseconds().unwrap()) as u32;
@ -559,8 +562,8 @@ impl NaiveTime {
debug_assert!(frac < 1_000_000_000); debug_assert!(frac < 1_000_000_000);
let rhssecs = rhs.num_seconds(); let rhssecs = rhs.num_seconds();
let rhsfrac = (rhs - Duration::seconds(rhssecs)).num_nanoseconds().unwrap(); let rhsfrac = (rhs - OldDuration::seconds(rhssecs)).num_nanoseconds().unwrap();
debug_assert!(Duration::seconds(rhssecs) + Duration::nanoseconds(rhsfrac) == rhs); debug_assert!(OldDuration::seconds(rhssecs) + OldDuration::nanoseconds(rhsfrac) == rhs);
let rhssecsinday = rhssecs % 86400; let rhssecsinday = rhssecs % 86400;
let mut morerhssecs = rhssecs - rhssecsinday; let mut morerhssecs = rhssecs - rhssecsinday;
let rhssecs = rhssecsinday as i32; let rhssecs = rhssecsinday as i32;
@ -604,23 +607,130 @@ impl NaiveTime {
/// # Example /// # Example
/// ///
/// ~~~~ /// ~~~~
/// use chrono::{NaiveTime, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// use chrono::NaiveTime;
/// use time::Duration;
/// ///
/// let from_hms = NaiveTime::from_hms; /// let from_hms = NaiveTime::from_hms;
/// ///
/// assert_eq!(from_hms(3, 4, 5).overflowing_sub(Duration::hours(2)), /// assert_eq!(from_hms(3, 4, 5).overflowing_sub_signed(Duration::hours(2)),
/// (from_hms(1, 4, 5), 0)); /// (from_hms(1, 4, 5), 0));
/// assert_eq!(from_hms(3, 4, 5).overflowing_sub(Duration::hours(17)), /// assert_eq!(from_hms(3, 4, 5).overflowing_sub_signed(Duration::hours(17)),
/// (from_hms(10, 4, 5), 86400)); /// (from_hms(10, 4, 5), 86400));
/// assert_eq!(from_hms(3, 4, 5).overflowing_sub(Duration::hours(-22)), /// assert_eq!(from_hms(3, 4, 5).overflowing_sub_signed(Duration::hours(-22)),
/// (from_hms(1, 4, 5), -86400)); /// (from_hms(1, 4, 5), -86400));
/// # }
/// ~~~~ /// ~~~~
#[inline] #[inline]
pub fn overflowing_sub(&self, rhs: Duration) -> (NaiveTime, i64) { pub fn overflowing_sub_signed(&self, rhs: OldDuration) -> (NaiveTime, i64) {
let (time, rhs) = self.overflowing_add(-rhs); let (time, rhs) = self.overflowing_add_signed(-rhs);
(time, -rhs) // safe to negate, rhs is within +/- (2^63 / 1000) (time, -rhs) // safe to negate, rhs is within +/- (2^63 / 1000)
} }
/// Subtracts another `NaiveTime` from the current time.
/// Returns a `Duration` within +/- 1 day.
/// This does not overflow or underflow at all.
///
/// As a part of Chrono's [leap second handling](./index.html#leap-second-handling),
/// the subtraction assumes that **there is no leap second ever**,
/// except when any of the `NaiveTime`s themselves represents a leap second
/// in which case the assumption becomes that
/// **there are exactly one (or two) leap second(s) ever**.
///
/// # Example
///
/// ~~~~
/// # extern crate chrono; extern crate time; fn main() {
/// use chrono::NaiveTime;
/// use time::Duration;
///
/// let from_hmsm = NaiveTime::from_hms_milli;
/// let since = NaiveTime::signed_duration_since;
///
/// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 7, 900)),
/// Duration::zero());
/// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 7, 875)),
/// Duration::milliseconds(25));
/// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 6, 925)),
/// Duration::milliseconds(975));
/// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 0, 900)),
/// Duration::seconds(7));
/// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 0, 7, 900)),
/// Duration::seconds(5 * 60));
/// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(0, 5, 7, 900)),
/// Duration::seconds(3 * 3600));
/// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(4, 5, 7, 900)),
/// Duration::seconds(-3600));
/// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(2, 4, 6, 800)),
/// Duration::seconds(3600 + 60 + 1) + Duration::milliseconds(100));
/// # }
/// ~~~~
///
/// Leap seconds are handled, but the subtraction assumes that
/// there were no other leap seconds happened.
///
/// ~~~~
/// # extern crate chrono; extern crate time; fn main() {
/// # use chrono::NaiveTime;
/// # use time::Duration;
/// # let from_hmsm = NaiveTime::from_hms_milli;
/// # let since = NaiveTime::signed_duration_since;
/// assert_eq!(since(from_hmsm(3, 0, 59, 1_000), from_hmsm(3, 0, 59, 0)),
/// Duration::seconds(1));
/// assert_eq!(since(from_hmsm(3, 0, 59, 1_500), from_hmsm(3, 0, 59, 0)),
/// Duration::milliseconds(1500));
/// assert_eq!(since(from_hmsm(3, 0, 59, 1_000), from_hmsm(3, 0, 0, 0)),
/// Duration::seconds(60));
/// assert_eq!(since(from_hmsm(3, 0, 0, 0), from_hmsm(2, 59, 59, 1_000)),
/// Duration::seconds(1));
/// assert_eq!(since(from_hmsm(3, 0, 59, 1_000), from_hmsm(2, 59, 59, 1_000)),
/// Duration::seconds(61));
/// # }
/// ~~~~
pub fn signed_duration_since(self, rhs: NaiveTime) -> OldDuration {
// | | :leap| | | | | | | :leap| |
// | | : | | | | | | | : | |
// ----+----+-----*---+----+----+----+----+----+----+-------*-+----+----
// | `rhs` | | `self`
// |======================================>| |
// | | `self.secs - rhs.secs` |`self.frac`
// |====>| | |======>|
// `rhs.frac`|========================================>|
// | | | `self - rhs` | |
use std::cmp::Ordering;
let secs = self.secs as i64 - rhs.secs as i64;
let frac = self.frac as i64 - rhs.frac as i64;
// `secs` may contain a leap second yet to be counted
let adjust = match self.secs.cmp(&rhs.secs) {
Ordering::Greater => if rhs.frac >= 1_000_000_000 { 1 } else { 0 },
Ordering::Equal => 0,
Ordering::Less => if self.frac >= 1_000_000_000 { -1 } else { 0 },
};
OldDuration::seconds(secs + adjust) + OldDuration::nanoseconds(frac)
}
/// Same to [`NaiveTime::overflowing_add_signed`](#method.overflowing_add_signed).
#[inline]
#[deprecated(since = "0.2.26",
note = "Renamed to `overflowing_add_signed`, \
will be replaced with a version with `std::time::Duration`")]
pub fn overflowing_add(self, rhs: OldDuration) -> (NaiveTime, i64) {
self.overflowing_add_signed(rhs)
}
/// Same to [`NaiveTime::overflowing_sub_signed`](#method.overflowing_sub_signed).
#[inline]
#[deprecated(since = "0.2.26",
note = "Renamed to `overflowing_sub_signed`, \
will be replaced with a version with `std::time::Duration`")]
pub fn overflowing_sub(self, rhs: OldDuration) -> (NaiveTime, i64) {
self.overflowing_sub_signed(rhs)
}
/// Formats the time with the specified formatting items. /// Formats the time with the specified formatting items.
/// Otherwise it is same to the ordinary [`format`](#method.format) method. /// Otherwise it is same to the ordinary [`format`](#method.format) method.
/// ///
@ -924,7 +1034,9 @@ impl hash::Hash for NaiveTime {
/// # Example /// # Example
/// ///
/// ~~~~ /// ~~~~
/// use chrono::{NaiveTime, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// use chrono::NaiveTime;
/// use time::Duration;
/// ///
/// let from_hmsm = NaiveTime::from_hms_milli; /// let from_hmsm = NaiveTime::from_hms_milli;
/// ///
@ -936,22 +1048,28 @@ impl hash::Hash for NaiveTime {
/// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::milliseconds(80), from_hmsm(3, 5, 7, 80)); /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::milliseconds(80), from_hmsm(3, 5, 7, 80));
/// assert_eq!(from_hmsm(3, 5, 7, 950) + Duration::milliseconds(280), from_hmsm(3, 5, 8, 230)); /// assert_eq!(from_hmsm(3, 5, 7, 950) + Duration::milliseconds(280), from_hmsm(3, 5, 8, 230));
/// assert_eq!(from_hmsm(3, 5, 7, 950) + Duration::milliseconds(-980), from_hmsm(3, 5, 6, 970)); /// assert_eq!(from_hmsm(3, 5, 7, 950) + Duration::milliseconds(-980), from_hmsm(3, 5, 6, 970));
/// # }
/// ~~~~ /// ~~~~
/// ///
/// The addition wraps around. /// The addition wraps around.
/// ///
/// ~~~~ /// ~~~~
/// # use chrono::{NaiveTime, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// # use chrono::NaiveTime;
/// # use time::Duration;
/// # let from_hmsm = NaiveTime::from_hms_milli; /// # let from_hmsm = NaiveTime::from_hms_milli;
/// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(22*60*60), from_hmsm(1, 5, 7, 0)); /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(22*60*60), from_hmsm(1, 5, 7, 0));
/// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(-8*60*60), from_hmsm(19, 5, 7, 0)); /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(-8*60*60), from_hmsm(19, 5, 7, 0));
/// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::days(800), from_hmsm(3, 5, 7, 0)); /// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::days(800), from_hmsm(3, 5, 7, 0));
/// # }
/// ~~~~ /// ~~~~
/// ///
/// Leap seconds are handled, but the addition assumes that it is the only leap second happened. /// Leap seconds are handled, but the addition assumes that it is the only leap second happened.
/// ///
/// ~~~~ /// ~~~~
/// # use chrono::{NaiveTime, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// # use chrono::NaiveTime;
/// # use time::Duration;
/// # let from_hmsm = NaiveTime::from_hms_milli; /// # let from_hmsm = NaiveTime::from_hms_milli;
/// let leap = from_hmsm(3, 5, 59, 1_300); /// let leap = from_hmsm(3, 5, 59, 1_300);
/// assert_eq!(leap + Duration::zero(), from_hmsm(3, 5, 59, 1_300)); /// assert_eq!(leap + Duration::zero(), from_hmsm(3, 5, 59, 1_300));
@ -961,82 +1079,26 @@ impl hash::Hash for NaiveTime {
/// assert_eq!(leap + Duration::seconds(10), from_hmsm(3, 6, 9, 300)); /// assert_eq!(leap + Duration::seconds(10), from_hmsm(3, 6, 9, 300));
/// assert_eq!(leap + Duration::seconds(-10), from_hmsm(3, 5, 50, 300)); /// assert_eq!(leap + Duration::seconds(-10), from_hmsm(3, 5, 50, 300));
/// assert_eq!(leap + Duration::days(1), from_hmsm(3, 5, 59, 300)); /// assert_eq!(leap + Duration::days(1), from_hmsm(3, 5, 59, 300));
/// # }
/// ~~~~ /// ~~~~
impl Add<Duration> for NaiveTime { impl Add<OldDuration> for NaiveTime {
type Output = NaiveTime; type Output = NaiveTime;
#[inline] #[inline]
fn add(self, rhs: Duration) -> NaiveTime { fn add(self, rhs: OldDuration) -> NaiveTime {
self.overflowing_add(rhs).0 self.overflowing_add_signed(rhs).0
} }
} }
/// A subtraction of `NaiveTime` from `NaiveTime` yields a `Duration` within +/- 1 day. /// Use [`NaiveTime::signed_duration_since`](#method.signed_duration_since) instead.
/// This does not overflow or underflow at all. // XXX this does not really work yet
/// #[deprecated(since = "0.2.26", note = "Use `signed_duration_since` method instead")]
/// As a part of Chrono's [leap second handling](./index.html#leap-second-handling),
/// the subtraction assumes that **there is no leap second ever**,
/// except when any of the `NaiveTime`s themselves represents a leap second
/// in which case the assumption becomes that
/// **there are exactly one (or two) leap second(s) ever**.
///
/// # Example
///
/// ~~~~
/// use chrono::{NaiveTime, Duration};
///
/// let from_hmsm = NaiveTime::from_hms_milli;
///
/// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(3, 5, 7, 900), Duration::zero());
/// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(3, 5, 7, 875), Duration::milliseconds(25));
/// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(3, 5, 6, 925), Duration::milliseconds(975));
/// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(3, 5, 0, 900), Duration::seconds(7));
/// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(3, 0, 7, 900), Duration::seconds(5 * 60));
/// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(0, 5, 7, 900), Duration::seconds(3 * 3600));
/// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(4, 5, 7, 900), Duration::seconds(-3600));
/// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(2, 4, 6, 800),
/// Duration::seconds(3600 + 60 + 1) + Duration::milliseconds(100));
/// ~~~~
///
/// Leap seconds are handled, but the subtraction assumes that
/// there were no other leap seconds happened.
///
/// ~~~~
/// # use chrono::{NaiveTime, Duration};
/// # let from_hmsm = NaiveTime::from_hms_milli;
/// assert_eq!(from_hmsm(3, 0, 59, 1_000) - from_hmsm(3, 0, 59, 0), Duration::seconds(1));
/// assert_eq!(from_hmsm(3, 0, 59, 1_500) - from_hmsm(3, 0, 59, 0), Duration::milliseconds(1500));
/// assert_eq!(from_hmsm(3, 0, 59, 1_000) - from_hmsm(3, 0, 0, 0), Duration::seconds(60));
/// assert_eq!(from_hmsm(3, 0, 0, 0) - from_hmsm(2, 59, 59, 1_000), Duration::seconds(1));
/// assert_eq!(from_hmsm(3, 0, 59, 1_000) - from_hmsm(2, 59, 59, 1_000), Duration::seconds(61));
/// ~~~~
impl Sub<NaiveTime> for NaiveTime { impl Sub<NaiveTime> for NaiveTime {
type Output = Duration; type Output = OldDuration;
fn sub(self, rhs: NaiveTime) -> Duration { #[inline]
// | | :leap| | | | | | | :leap| | fn sub(self, rhs: NaiveTime) -> OldDuration {
// | | : | | | | | | | : | | self.signed_duration_since(rhs)
// ----+----+-----*---+----+----+----+----+----+----+-------*-+----+----
// | `rhs` | | `self`
// |======================================>| |
// | | `self.secs - rhs.secs` |`self.frac`
// |====>| | |======>|
// `rhs.frac`|========================================>|
// | | | `self - rhs` | |
use std::cmp::Ordering;
let secs = self.secs as i64 - rhs.secs as i64;
let frac = self.frac as i64 - rhs.frac as i64;
// `secs` may contain a leap second yet to be counted
let adjust = match self.secs.cmp(&rhs.secs) {
Ordering::Greater => if rhs.frac >= 1_000_000_000 { 1 } else { 0 },
Ordering::Equal => 0,
Ordering::Less => if self.frac >= 1_000_000_000 { -1 } else { 0 },
};
Duration::seconds(secs + adjust) + Duration::nanoseconds(frac)
} }
} }
@ -1052,7 +1114,9 @@ impl Sub<NaiveTime> for NaiveTime {
/// # Example /// # Example
/// ///
/// ~~~~ /// ~~~~
/// use chrono::{NaiveTime, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// use chrono::NaiveTime;
/// use time::Duration;
/// ///
/// let from_hmsm = NaiveTime::from_hms_milli; /// let from_hmsm = NaiveTime::from_hms_milli;
/// ///
@ -1062,21 +1126,27 @@ impl Sub<NaiveTime> for NaiveTime {
/// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::seconds(2*60*60 + 6*60), from_hmsm(0, 59, 7, 0)); /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::seconds(2*60*60 + 6*60), from_hmsm(0, 59, 7, 0));
/// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::milliseconds(80), from_hmsm(3, 5, 6, 920)); /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::milliseconds(80), from_hmsm(3, 5, 6, 920));
/// assert_eq!(from_hmsm(3, 5, 7, 950) - Duration::milliseconds(280), from_hmsm(3, 5, 7, 670)); /// assert_eq!(from_hmsm(3, 5, 7, 950) - Duration::milliseconds(280), from_hmsm(3, 5, 7, 670));
/// # }
/// ~~~~ /// ~~~~
/// ///
/// The subtraction wraps around. /// The subtraction wraps around.
/// ///
/// ~~~~ /// ~~~~
/// # use chrono::{NaiveTime, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// # use chrono::NaiveTime;
/// # use time::Duration;
/// # let from_hmsm = NaiveTime::from_hms_milli; /// # let from_hmsm = NaiveTime::from_hms_milli;
/// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::seconds(8*60*60), from_hmsm(19, 5, 7, 0)); /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::seconds(8*60*60), from_hmsm(19, 5, 7, 0));
/// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::days(800), from_hmsm(3, 5, 7, 0)); /// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::days(800), from_hmsm(3, 5, 7, 0));
/// # }
/// ~~~~ /// ~~~~
/// ///
/// Leap seconds are handled, but the subtraction assumes that it is the only leap second happened. /// Leap seconds are handled, but the subtraction assumes that it is the only leap second happened.
/// ///
/// ~~~~ /// ~~~~
/// # use chrono::{NaiveTime, Duration}; /// # extern crate chrono; extern crate time; fn main() {
/// # use chrono::NaiveTime;
/// # use time::Duration;
/// # let from_hmsm = NaiveTime::from_hms_milli; /// # let from_hmsm = NaiveTime::from_hms_milli;
/// let leap = from_hmsm(3, 5, 59, 1_300); /// let leap = from_hmsm(3, 5, 59, 1_300);
/// assert_eq!(leap - Duration::zero(), from_hmsm(3, 5, 59, 1_300)); /// assert_eq!(leap - Duration::zero(), from_hmsm(3, 5, 59, 1_300));
@ -1084,13 +1154,14 @@ impl Sub<NaiveTime> for NaiveTime {
/// assert_eq!(leap - Duration::milliseconds(500), from_hmsm(3, 5, 59, 800)); /// assert_eq!(leap - Duration::milliseconds(500), from_hmsm(3, 5, 59, 800));
/// assert_eq!(leap - Duration::seconds(60), from_hmsm(3, 5, 0, 300)); /// assert_eq!(leap - Duration::seconds(60), from_hmsm(3, 5, 0, 300));
/// assert_eq!(leap - Duration::days(1), from_hmsm(3, 6, 0, 300)); /// assert_eq!(leap - Duration::days(1), from_hmsm(3, 6, 0, 300));
/// # }
/// ~~~~ /// ~~~~
impl Sub<Duration> for NaiveTime { impl Sub<OldDuration> for NaiveTime {
type Output = NaiveTime; type Output = NaiveTime;
#[inline] #[inline]
fn sub(self, rhs: Duration) -> NaiveTime { fn sub(self, rhs: OldDuration) -> NaiveTime {
self.overflowing_sub(rhs).0 self.overflowing_sub_signed(rhs).0
} }
} }
@ -1434,8 +1505,8 @@ mod serde {
mod tests { mod tests {
use super::NaiveTime; use super::NaiveTime;
use Timelike; use Timelike;
use duration::Duration;
use std::u32; use std::u32;
use oldtime::Duration;
#[test] #[test]
fn test_time_from_hms_milli() { fn test_time_from_hms_milli() {
@ -1526,17 +1597,17 @@ mod tests {
fn test_time_overflowing_add() { fn test_time_overflowing_add() {
let hmsm = NaiveTime::from_hms_milli; let hmsm = NaiveTime::from_hms_milli;
assert_eq!(hmsm(3, 4, 5, 678).overflowing_add(Duration::hours(11)), assert_eq!(hmsm(3, 4, 5, 678).overflowing_add_signed(Duration::hours(11)),
(hmsm(14, 4, 5, 678), 0)); (hmsm(14, 4, 5, 678), 0));
assert_eq!(hmsm(3, 4, 5, 678).overflowing_add(Duration::hours(23)), assert_eq!(hmsm(3, 4, 5, 678).overflowing_add_signed(Duration::hours(23)),
(hmsm(2, 4, 5, 678), 86400)); (hmsm(2, 4, 5, 678), 86400));
assert_eq!(hmsm(3, 4, 5, 678).overflowing_add(Duration::hours(-7)), assert_eq!(hmsm(3, 4, 5, 678).overflowing_add_signed(Duration::hours(-7)),
(hmsm(20, 4, 5, 678), -86400)); (hmsm(20, 4, 5, 678), -86400));
// overflowing_add with leap seconds may be counter-intuitive // overflowing_add_signed with leap seconds may be counter-intuitive
assert_eq!(hmsm(3, 4, 5, 1_678).overflowing_add(Duration::days(1)), assert_eq!(hmsm(3, 4, 5, 1_678).overflowing_add_signed(Duration::days(1)),
(hmsm(3, 4, 5, 678), 86400)); (hmsm(3, 4, 5, 678), 86400));
assert_eq!(hmsm(3, 4, 5, 1_678).overflowing_add(Duration::days(-1)), assert_eq!(hmsm(3, 4, 5, 1_678).overflowing_add_signed(Duration::days(-1)),
(hmsm(3, 4, 6, 678), -86400)); (hmsm(3, 4, 6, 678), -86400));
} }
@ -1545,8 +1616,8 @@ mod tests {
macro_rules! check { macro_rules! check {
($lhs:expr, $rhs:expr, $diff:expr) => ({ ($lhs:expr, $rhs:expr, $diff:expr) => ({
// `time1 - time2 = duration` is equivalent to `time2 - time1 = -duration` // `time1 - time2 = duration` is equivalent to `time2 - time1 = -duration`
assert_eq!($lhs - $rhs, $diff); assert_eq!($lhs.signed_duration_since($rhs), $diff);
assert_eq!($rhs - $lhs, -$diff); assert_eq!($rhs.signed_duration_since($lhs), -$diff);
}) })
} }

View File

@ -1,14 +1,12 @@
// This is a part of Chrono. // This is a part of Chrono.
// See README.md and LICENSE.txt for details. // See README.md and LICENSE.txt for details.
/*! //! The time zone which has a fixed offset from UTC.
* The time zone which has a fixed offset from UTC.
*/
use std::fmt; use std::fmt;
use oldtime::Duration as OldDuration;
use div::div_mod_floor; use div::div_mod_floor;
use duration::Duration;
use naive::date::NaiveDate; use naive::date::NaiveDate;
use naive::datetime::NaiveDateTime; use naive::datetime::NaiveDateTime;
use super::{TimeZone, Offset, LocalResult}; use super::{TimeZone, Offset, LocalResult};
@ -120,7 +118,7 @@ impl TimeZone for FixedOffset {
} }
impl Offset for FixedOffset { impl Offset for FixedOffset {
fn local_minus_utc(&self) -> Duration { Duration::seconds(self.local_minus_utc as i64) } fn local_minus_utc(&self) -> OldDuration { OldDuration::seconds(self.local_minus_utc as i64) }
} }
impl fmt::Debug for FixedOffset { impl fmt::Debug for FixedOffset {

View File

@ -1,14 +1,12 @@
// This is a part of Chrono. // This is a part of Chrono.
// See README.md and LICENSE.txt for details. // See README.md and LICENSE.txt for details.
/*! //! The local (system) time zone.
* The local (system) time zone.
*/
use stdtime; use oldtime;
use oldtime::Duration as OldDuration;
use {Datelike, Timelike}; use {Datelike, Timelike};
use duration::Duration;
use naive::date::NaiveDate; use naive::date::NaiveDate;
use naive::time::NaiveTime; use naive::time::NaiveTime;
use naive::datetime::NaiveDateTime; use naive::datetime::NaiveDateTime;
@ -19,20 +17,20 @@ use super::fixed::FixedOffset;
/// Converts a `time::Tm` struct into the timezone-aware `DateTime`. /// Converts a `time::Tm` struct into the timezone-aware `DateTime`.
/// This assumes that `time` is working correctly, i.e. any error is fatal. /// This assumes that `time` is working correctly, i.e. any error is fatal.
fn tm_to_datetime(mut tm: stdtime::Tm) -> DateTime<Local> { fn tm_to_datetime(mut tm: oldtime::Tm) -> DateTime<Local> {
if tm.tm_sec >= 60 { if tm.tm_sec >= 60 {
tm.tm_nsec += (tm.tm_sec - 59) * 1_000_000_000; tm.tm_nsec += (tm.tm_sec - 59) * 1_000_000_000;
tm.tm_sec = 59; tm.tm_sec = 59;
} }
#[cfg(not(windows))] #[cfg(not(windows))]
fn tm_to_naive_date(tm: &stdtime::Tm) -> NaiveDate { fn tm_to_naive_date(tm: &oldtime::Tm) -> NaiveDate {
// from_yo is more efficient than from_ymd (since it's the internal representation). // from_yo is more efficient than from_ymd (since it's the internal representation).
NaiveDate::from_yo(tm.tm_year + 1900, tm.tm_yday as u32 + 1) NaiveDate::from_yo(tm.tm_year + 1900, tm.tm_yday as u32 + 1)
} }
#[cfg(windows)] #[cfg(windows)]
fn tm_to_naive_date(tm: &stdtime::Tm) -> NaiveDate { fn tm_to_naive_date(tm: &oldtime::Tm) -> NaiveDate {
// ...but tm_yday is broken in Windows (issue #85) // ...but tm_yday is broken in Windows (issue #85)
NaiveDate::from_ymd(tm.tm_year + 1900, tm.tm_mon as u32 + 1, tm.tm_mday as u32) NaiveDate::from_ymd(tm.tm_year + 1900, tm.tm_mon as u32 + 1, tm.tm_mday as u32)
} }
@ -41,17 +39,17 @@ fn tm_to_datetime(mut tm: stdtime::Tm) -> DateTime<Local> {
let time = NaiveTime::from_hms_nano(tm.tm_hour as u32, tm.tm_min as u32, let time = NaiveTime::from_hms_nano(tm.tm_hour as u32, tm.tm_min as u32,
tm.tm_sec as u32, tm.tm_nsec as u32); tm.tm_sec as u32, tm.tm_nsec as u32);
let offset = FixedOffset::east(tm.tm_utcoff); let offset = FixedOffset::east(tm.tm_utcoff);
DateTime::from_utc(date.and_time(time) + Duration::seconds(-tm.tm_utcoff as i64), offset) DateTime::from_utc(date.and_time(time) + OldDuration::seconds(-tm.tm_utcoff as i64), offset)
} }
/// Converts a local `NaiveDateTime` to the `time::Timespec`. /// Converts a local `NaiveDateTime` to the `time::Timespec`.
fn datetime_to_timespec(d: &NaiveDateTime, local: bool) -> stdtime::Timespec { fn datetime_to_timespec(d: &NaiveDateTime, local: bool) -> oldtime::Timespec {
// well, this exploits an undocumented `Tm::to_timespec` behavior // well, this exploits an undocumented `Tm::to_timespec` behavior
// to get the exact function we want (either `timegm` or `mktime`). // to get the exact function we want (either `timegm` or `mktime`).
// the number 1 is arbitrary but should be non-zero to trigger `mktime`. // the number 1 is arbitrary but should be non-zero to trigger `mktime`.
let tm_utcoff = if local {1} else {0}; let tm_utcoff = if local {1} else {0};
let tm = stdtime::Tm { let tm = oldtime::Tm {
tm_sec: d.second() as i32, tm_sec: d.second() as i32,
tm_min: d.minute() as i32, tm_min: d.minute() as i32,
tm_hour: d.hour() as i32, tm_hour: d.hour() as i32,
@ -93,7 +91,7 @@ impl Local {
/// Returns a `DateTime` which corresponds to the current date. /// Returns a `DateTime` which corresponds to the current date.
pub fn now() -> DateTime<Local> { pub fn now() -> DateTime<Local> {
tm_to_datetime(stdtime::now()) tm_to_datetime(oldtime::now())
} }
} }
@ -127,7 +125,7 @@ impl TimeZone for Local {
} }
fn from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<DateTime<Local>> { fn from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<DateTime<Local>> {
let timespec = datetime_to_timespec(local, true); let timespec = datetime_to_timespec(local, true);
LocalResult::Single(tm_to_datetime(stdtime::at(timespec))) LocalResult::Single(tm_to_datetime(oldtime::at(timespec)))
} }
fn from_utc_date(&self, utc: &NaiveDate) -> Date<Local> { fn from_utc_date(&self, utc: &NaiveDate) -> Date<Local> {
@ -136,7 +134,7 @@ impl TimeZone for Local {
} }
fn from_utc_datetime(&self, utc: &NaiveDateTime) -> DateTime<Local> { fn from_utc_datetime(&self, utc: &NaiveDateTime) -> DateTime<Local> {
let timespec = datetime_to_timespec(utc, false); let timespec = datetime_to_timespec(utc, false);
tm_to_datetime(stdtime::at(timespec)) tm_to_datetime(oldtime::at(timespec))
} }
} }

View File

@ -22,10 +22,10 @@
use std::fmt; use std::fmt;
use std::ops::Add; use std::ops::Add;
use oldtime::Duration as OldDuration;
use Weekday; use Weekday;
use Timelike; use Timelike;
use duration::Duration;
use naive::date::NaiveDate; use naive::date::NaiveDate;
use naive::time::NaiveTime; use naive::time::NaiveTime;
use naive::datetime::NaiveDateTime; use naive::datetime::NaiveDateTime;
@ -36,8 +36,10 @@ use format::{parse, Parsed, ParseResult, StrftimeItems};
/// Same to `*lhs + *rhs`, but keeps the leap second information. /// Same to `*lhs + *rhs`, but keeps the leap second information.
/// `rhs` should *not* have a fractional second. /// `rhs` should *not* have a fractional second.
// TODO this should be replaced by the addition with FixedOffset in 0.3! // TODO this should be replaced by the addition with FixedOffset in 0.3!
pub fn add_with_leapsecond<T: Timelike + Add<Duration, Output=T>>(lhs: &T, rhs: &Duration) -> T { pub fn add_with_leapsecond<T>(lhs: &T, rhs: &OldDuration) -> T
debug_assert!(*rhs == Duration::seconds(rhs.num_seconds())); where T: Timelike + Add<OldDuration, Output=T>
{
debug_assert!(*rhs == OldDuration::seconds(rhs.num_seconds()));
// extract and temporarily remove the fractional part and later recover it // extract and temporarily remove the fractional part and later recover it
let nanos = lhs.nanosecond(); let nanos = lhs.nanosecond();
@ -174,7 +176,7 @@ impl<T: fmt::Debug> LocalResult<T> {
/// The offset from the local time to UTC. /// The offset from the local time to UTC.
pub trait Offset: Sized + Clone + fmt::Debug { pub trait Offset: Sized + Clone + fmt::Debug {
/// Returns the offset from UTC to the local time stored. /// Returns the offset from UTC to the local time stored.
fn local_minus_utc(&self) -> Duration; fn local_minus_utc(&self) -> OldDuration;
} }
/// The time zone. /// The time zone.

View File

@ -6,9 +6,9 @@
*/ */
use std::fmt; use std::fmt;
use stdtime; use oldtime;
use oldtime::Duration as OldDuration;
use duration::Duration;
use naive::date::NaiveDate; use naive::date::NaiveDate;
use naive::datetime::NaiveDateTime; use naive::datetime::NaiveDateTime;
use date::Date; use date::Date;
@ -42,7 +42,7 @@ impl UTC {
/// Returns a `DateTime` which corresponds to the current date. /// Returns a `DateTime` which corresponds to the current date.
pub fn now() -> DateTime<UTC> { pub fn now() -> DateTime<UTC> {
let spec = stdtime::get_time(); let spec = oldtime::get_time();
let naive = NaiveDateTime::from_timestamp(spec.sec, spec.nsec as u32); let naive = NaiveDateTime::from_timestamp(spec.sec, spec.nsec as u32);
DateTime::from_utc(naive, UTC) DateTime::from_utc(naive, UTC)
} }
@ -65,7 +65,7 @@ impl TimeZone for UTC {
} }
impl Offset for UTC { impl Offset for UTC {
fn local_minus_utc(&self) -> Duration { Duration::zero() } fn local_minus_utc(&self) -> OldDuration { OldDuration::zero() }
} }
impl fmt::Debug for UTC { impl fmt::Debug for UTC {