language changes: namespaced enums, no more std::num::{Zero,Bounded}.
This commit is contained in:
parent
fdcaff7ce1
commit
ec6c874042
16
Cargo.toml
16
Cargo.toml
|
@ -1,13 +1,19 @@
|
|||
[package]
|
||||
|
||||
name = "chrono"
|
||||
version = "0.1.0"
|
||||
authors = ["Kang Seonghoon <public+rust@mearie.org>"]
|
||||
|
||||
[dependencies.num]
|
||||
|
||||
git = "https://github.com/rust-lang/num"
|
||||
description = "Date and time library for Rust"
|
||||
homepage = "https://github.com/lifthrasiir/rust-chrono"
|
||||
readme = "README.md"
|
||||
license = "MIT/Apache-2.0"
|
||||
|
||||
[lib]
|
||||
|
||||
name = "chrono"
|
||||
|
||||
[dependencies.num]
|
||||
git = "https://github.com/rust-lang/num"
|
||||
|
||||
[dependencies.time]
|
||||
git = "https://github.com/rust-lang/time"
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* ISO 8601 calendar date with timezone.
|
||||
*/
|
||||
|
||||
use std::{fmt, num, hash};
|
||||
use std::{fmt, hash};
|
||||
|
||||
use {Weekday, Datelike};
|
||||
use duration::Duration;
|
||||
|
@ -232,11 +232,6 @@ impl<Off:Offset> Datelike for Date<Off> {
|
|||
}
|
||||
}
|
||||
|
||||
impl num::Bounded for Date<UTC> {
|
||||
#[inline] fn min_value() -> Date<UTC> { MIN }
|
||||
#[inline] fn max_value() -> Date<UTC> { MAX }
|
||||
}
|
||||
|
||||
impl<Off:Offset> PartialEq for Date<Off> {
|
||||
fn eq(&self, other: &Date<Off>) -> bool { self.date == other.date }
|
||||
}
|
||||
|
|
84
src/lib.rs
84
src/lib.rs
|
@ -74,13 +74,13 @@ impl Weekday {
|
|||
#[inline]
|
||||
pub fn succ(&self) -> Weekday {
|
||||
match *self {
|
||||
Mon => Tue,
|
||||
Tue => Wed,
|
||||
Wed => Thu,
|
||||
Thu => Fri,
|
||||
Fri => Sat,
|
||||
Sat => Sun,
|
||||
Sun => Mon,
|
||||
Weekday::Mon => Weekday::Tue,
|
||||
Weekday::Tue => Weekday::Wed,
|
||||
Weekday::Wed => Weekday::Thu,
|
||||
Weekday::Thu => Weekday::Fri,
|
||||
Weekday::Fri => Weekday::Sat,
|
||||
Weekday::Sat => Weekday::Sun,
|
||||
Weekday::Sun => Weekday::Mon,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,13 +88,13 @@ impl Weekday {
|
|||
#[inline]
|
||||
pub fn pred(&self) -> Weekday {
|
||||
match *self {
|
||||
Mon => Sun,
|
||||
Tue => Mon,
|
||||
Wed => Tue,
|
||||
Thu => Wed,
|
||||
Fri => Thu,
|
||||
Sat => Fri,
|
||||
Sun => Sat,
|
||||
Weekday::Mon => Weekday::Sun,
|
||||
Weekday::Tue => Weekday::Mon,
|
||||
Weekday::Wed => Weekday::Tue,
|
||||
Weekday::Thu => Weekday::Wed,
|
||||
Weekday::Fri => Weekday::Thu,
|
||||
Weekday::Sat => Weekday::Fri,
|
||||
Weekday::Sun => Weekday::Sat,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,13 +102,13 @@ impl Weekday {
|
|||
#[inline]
|
||||
pub fn number_from_monday(&self) -> u32 {
|
||||
match *self {
|
||||
Mon => 1,
|
||||
Tue => 2,
|
||||
Wed => 3,
|
||||
Thu => 4,
|
||||
Fri => 5,
|
||||
Sat => 6,
|
||||
Sun => 7,
|
||||
Weekday::Mon => 1,
|
||||
Weekday::Tue => 2,
|
||||
Weekday::Wed => 3,
|
||||
Weekday::Thu => 4,
|
||||
Weekday::Fri => 5,
|
||||
Weekday::Sat => 6,
|
||||
Weekday::Sun => 7,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,13 +116,13 @@ impl Weekday {
|
|||
#[inline]
|
||||
pub fn number_from_sunday(&self) -> u32 {
|
||||
match *self {
|
||||
Mon => 2,
|
||||
Tue => 3,
|
||||
Wed => 4,
|
||||
Thu => 5,
|
||||
Fri => 6,
|
||||
Sat => 7,
|
||||
Sun => 1,
|
||||
Weekday::Mon => 2,
|
||||
Weekday::Tue => 3,
|
||||
Weekday::Wed => 4,
|
||||
Weekday::Thu => 5,
|
||||
Weekday::Fri => 6,
|
||||
Weekday::Sat => 7,
|
||||
Weekday::Sun => 1,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,13 +130,13 @@ impl Weekday {
|
|||
#[inline]
|
||||
pub fn num_days_from_monday(&self) -> u32 {
|
||||
match *self {
|
||||
Mon => 0,
|
||||
Tue => 1,
|
||||
Wed => 2,
|
||||
Thu => 3,
|
||||
Fri => 4,
|
||||
Sat => 5,
|
||||
Sun => 6,
|
||||
Weekday::Mon => 0,
|
||||
Weekday::Tue => 1,
|
||||
Weekday::Wed => 2,
|
||||
Weekday::Thu => 3,
|
||||
Weekday::Fri => 4,
|
||||
Weekday::Sat => 5,
|
||||
Weekday::Sun => 6,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,13 +144,13 @@ impl Weekday {
|
|||
#[inline]
|
||||
pub fn num_days_from_sunday(&self) -> u32 {
|
||||
match *self {
|
||||
Mon => 1,
|
||||
Tue => 2,
|
||||
Wed => 3,
|
||||
Thu => 4,
|
||||
Fri => 5,
|
||||
Sat => 6,
|
||||
Sun => 0,
|
||||
Weekday::Mon => 1,
|
||||
Weekday::Tue => 2,
|
||||
Weekday::Wed => 3,
|
||||
Weekday::Thu => 4,
|
||||
Weekday::Fri => 5,
|
||||
Weekday::Sat => 6,
|
||||
Weekday::Sun => 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
* ISO 8601 calendar date without timezone.
|
||||
*/
|
||||
|
||||
use std::{fmt, num};
|
||||
use std::fmt;
|
||||
use std::num::Int;
|
||||
use num::Integer;
|
||||
|
||||
use {Weekday, Datelike};
|
||||
|
@ -376,11 +377,6 @@ impl Datelike for NaiveDate {
|
|||
}
|
||||
}
|
||||
|
||||
impl num::Bounded for NaiveDate {
|
||||
#[inline] fn min_value() -> NaiveDate { MIN }
|
||||
#[inline] fn max_value() -> NaiveDate { MAX }
|
||||
}
|
||||
|
||||
impl Add<Duration,NaiveDate> for NaiveDate {
|
||||
fn add(&self, rhs: &Duration) -> NaiveDate {
|
||||
// TODO overflow currently fails
|
||||
|
@ -388,7 +384,7 @@ impl Add<Duration,NaiveDate> for NaiveDate {
|
|||
let year = self.year();
|
||||
let (mut year_div_400, year_mod_400) = year.div_mod_floor(&400);
|
||||
let cycle = internals::yo_to_cycle(year_mod_400 as u32, self.of().ordinal());
|
||||
let cycle = (cycle as i32).checked_add(&rhs.num_days().to_i32().unwrap()).unwrap();
|
||||
let cycle = (cycle as i32).checked_add(rhs.num_days().to_i32().unwrap()).unwrap();
|
||||
let (cycle_div_400y, cycle) = cycle.div_mod_floor(&146097);
|
||||
year_div_400 += cycle_div_400y;
|
||||
|
||||
|
@ -435,11 +431,9 @@ impl fmt::Show for NaiveDate {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{NaiveDate, MIN, MAX};
|
||||
use Datelike;
|
||||
use {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
|
||||
use {Datelike, Weekday};
|
||||
use duration::Duration;
|
||||
use std::{i32, u32};
|
||||
use std::num::Zero;
|
||||
use std::iter::{range_inclusive, range_step_inclusive};
|
||||
|
||||
#[test]
|
||||
|
@ -493,35 +487,36 @@ mod tests {
|
|||
let isoywd_opt = |y,w,d| NaiveDate::from_isoywd_opt(y, w, d);
|
||||
let ymd = |y,m,d| NaiveDate::from_ymd(y, m, d);
|
||||
|
||||
assert_eq!(isoywd_opt(2004, 0, Sun), None);
|
||||
assert_eq!(isoywd_opt(2004, 1, Mon), Some(ymd(2003, 12, 29)));
|
||||
assert_eq!(isoywd_opt(2004, 1, Sun), Some(ymd(2004, 1, 4)));
|
||||
assert_eq!(isoywd_opt(2004, 2, Mon), Some(ymd(2004, 1, 5)));
|
||||
assert_eq!(isoywd_opt(2004, 2, Sun), Some(ymd(2004, 1, 11)));
|
||||
assert_eq!(isoywd_opt(2004, 52, Mon), Some(ymd(2004, 12, 20)));
|
||||
assert_eq!(isoywd_opt(2004, 52, Sun), Some(ymd(2004, 12, 26)));
|
||||
assert_eq!(isoywd_opt(2004, 53, Mon), Some(ymd(2004, 12, 27)));
|
||||
assert_eq!(isoywd_opt(2004, 53, Sun), Some(ymd(2005, 1, 2)));
|
||||
assert_eq!(isoywd_opt(2004, 54, Mon), None);
|
||||
assert_eq!(isoywd_opt(2004, 0, Weekday::Sun), None);
|
||||
assert_eq!(isoywd_opt(2004, 1, Weekday::Mon), Some(ymd(2003, 12, 29)));
|
||||
assert_eq!(isoywd_opt(2004, 1, Weekday::Sun), Some(ymd(2004, 1, 4)));
|
||||
assert_eq!(isoywd_opt(2004, 2, Weekday::Mon), Some(ymd(2004, 1, 5)));
|
||||
assert_eq!(isoywd_opt(2004, 2, Weekday::Sun), Some(ymd(2004, 1, 11)));
|
||||
assert_eq!(isoywd_opt(2004, 52, Weekday::Mon), Some(ymd(2004, 12, 20)));
|
||||
assert_eq!(isoywd_opt(2004, 52, Weekday::Sun), Some(ymd(2004, 12, 26)));
|
||||
assert_eq!(isoywd_opt(2004, 53, Weekday::Mon), Some(ymd(2004, 12, 27)));
|
||||
assert_eq!(isoywd_opt(2004, 53, Weekday::Sun), Some(ymd(2005, 1, 2)));
|
||||
assert_eq!(isoywd_opt(2004, 54, Weekday::Mon), None);
|
||||
|
||||
assert_eq!(isoywd_opt(2011, 0, Sun), None);
|
||||
assert_eq!(isoywd_opt(2011, 1, Mon), Some(ymd(2011, 1, 3)));
|
||||
assert_eq!(isoywd_opt(2011, 1, Sun), Some(ymd(2011, 1, 9)));
|
||||
assert_eq!(isoywd_opt(2011, 2, Mon), Some(ymd(2011, 1, 10)));
|
||||
assert_eq!(isoywd_opt(2011, 2, Sun), Some(ymd(2011, 1, 16)));
|
||||
assert_eq!(isoywd_opt(2011, 0, Weekday::Sun), None);
|
||||
assert_eq!(isoywd_opt(2011, 1, Weekday::Mon), Some(ymd(2011, 1, 3)));
|
||||
assert_eq!(isoywd_opt(2011, 1, Weekday::Sun), Some(ymd(2011, 1, 9)));
|
||||
assert_eq!(isoywd_opt(2011, 2, Weekday::Mon), Some(ymd(2011, 1, 10)));
|
||||
assert_eq!(isoywd_opt(2011, 2, Weekday::Sun), Some(ymd(2011, 1, 16)));
|
||||
|
||||
assert_eq!(isoywd_opt(2018, 51, Mon), Some(ymd(2018, 12, 17)));
|
||||
assert_eq!(isoywd_opt(2018, 51, Sun), Some(ymd(2018, 12, 23)));
|
||||
assert_eq!(isoywd_opt(2018, 52, Mon), Some(ymd(2018, 12, 24)));
|
||||
assert_eq!(isoywd_opt(2018, 52, Sun), Some(ymd(2018, 12, 30)));
|
||||
assert_eq!(isoywd_opt(2018, 53, Mon), None);
|
||||
assert_eq!(isoywd_opt(2018, 51, Weekday::Mon), Some(ymd(2018, 12, 17)));
|
||||
assert_eq!(isoywd_opt(2018, 51, Weekday::Sun), Some(ymd(2018, 12, 23)));
|
||||
assert_eq!(isoywd_opt(2018, 52, Weekday::Mon), Some(ymd(2018, 12, 24)));
|
||||
assert_eq!(isoywd_opt(2018, 52, Weekday::Sun), Some(ymd(2018, 12, 30)));
|
||||
assert_eq!(isoywd_opt(2018, 53, Weekday::Mon), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_date_from_isoymd_and_isoweekdate() {
|
||||
for year in range_inclusive(2000i32, 2400) {
|
||||
for week in range_inclusive(1u32, 53) {
|
||||
for &weekday in [Mon, Tue, Wed, Thu, Fri, Sat, Sun].iter() {
|
||||
for &weekday in [Weekday::Mon, Weekday::Tue, Weekday::Wed, Weekday::Thu,
|
||||
Weekday::Fri, Weekday::Sat, Weekday::Sun].iter() {
|
||||
let d = NaiveDate::from_isoywd_opt(year, week, weekday);
|
||||
if d.is_some() {
|
||||
let d = d.unwrap();
|
||||
|
@ -622,9 +617,10 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_date_weekday() {
|
||||
assert_eq!(NaiveDate::from_ymd(1582, 10, 15).weekday(), Fri);
|
||||
assert_eq!(NaiveDate::from_ymd(1875, 5, 20).weekday(), Thu); // ISO 8601 reference date
|
||||
assert_eq!(NaiveDate::from_ymd(2000, 1, 1).weekday(), Sat);
|
||||
assert_eq!(NaiveDate::from_ymd(1582, 10, 15).weekday(), Weekday::Fri);
|
||||
// May 20, 1875 = ISO 8601 reference date
|
||||
assert_eq!(NaiveDate::from_ymd(1875, 5, 20).weekday(), Weekday::Thu);
|
||||
assert_eq!(NaiveDate::from_ymd(2000, 1, 1).weekday(), Weekday::Sat);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -705,7 +701,7 @@ mod tests {
|
|||
//assert_eq!(rhs + lhs, sum);
|
||||
}
|
||||
|
||||
check((2014, 1, 1), Zero::zero(), (2014, 1, 1));
|
||||
check((2014, 1, 1), Duration::zero(), (2014, 1, 1));
|
||||
check((2014, 1, 1), Duration::seconds(86399), (2014, 1, 1));
|
||||
check((2014, 1, 1), Duration::seconds(-86399), (2014, 1, 1)); // always round towards zero
|
||||
check((2014, 1, 1), Duration::days(1), (2014, 1, 2));
|
||||
|
@ -726,7 +722,7 @@ mod tests {
|
|||
assert_eq!(rhs - lhs, -diff);
|
||||
}
|
||||
|
||||
check((2014, 1, 1), (2014, 1, 1), Zero::zero());
|
||||
check((2014, 1, 1), (2014, 1, 1), Duration::zero());
|
||||
check((2014, 1, 2), (2014, 1, 1), Duration::days(1));
|
||||
check((2014, 12, 31), (2014, 1, 1), Duration::days(364));
|
||||
check((2015, 1, 3), (2014, 1, 1), Duration::days(365 + 2));
|
||||
|
@ -1238,9 +1234,9 @@ mod internals {
|
|||
mod tests {
|
||||
extern crate test;
|
||||
|
||||
use Weekday;
|
||||
use super::{Of, Mdf};
|
||||
use super::{YearFlags, A, B, C, D, E, F, G, AG, BA, CB, DC, ED, FE, GF};
|
||||
use {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
|
||||
use std::iter::range_inclusive;
|
||||
use std::u32;
|
||||
|
||||
|
@ -1413,20 +1409,20 @@ mod internals {
|
|||
|
||||
#[test]
|
||||
fn test_of_weekday() {
|
||||
assert_eq!(Of::new(1, A).weekday(), Sun);
|
||||
assert_eq!(Of::new(1, B).weekday(), Sat);
|
||||
assert_eq!(Of::new(1, C).weekday(), Fri);
|
||||
assert_eq!(Of::new(1, D).weekday(), Thu);
|
||||
assert_eq!(Of::new(1, E).weekday(), Wed);
|
||||
assert_eq!(Of::new(1, F).weekday(), Tue);
|
||||
assert_eq!(Of::new(1, G).weekday(), Mon);
|
||||
assert_eq!(Of::new(1, AG).weekday(), Sun);
|
||||
assert_eq!(Of::new(1, BA).weekday(), Sat);
|
||||
assert_eq!(Of::new(1, CB).weekday(), Fri);
|
||||
assert_eq!(Of::new(1, DC).weekday(), Thu);
|
||||
assert_eq!(Of::new(1, ED).weekday(), Wed);
|
||||
assert_eq!(Of::new(1, FE).weekday(), Tue);
|
||||
assert_eq!(Of::new(1, GF).weekday(), Mon);
|
||||
assert_eq!(Of::new(1, A).weekday(), Weekday::Sun);
|
||||
assert_eq!(Of::new(1, B).weekday(), Weekday::Sat);
|
||||
assert_eq!(Of::new(1, C).weekday(), Weekday::Fri);
|
||||
assert_eq!(Of::new(1, D).weekday(), Weekday::Thu);
|
||||
assert_eq!(Of::new(1, E).weekday(), Weekday::Wed);
|
||||
assert_eq!(Of::new(1, F).weekday(), Weekday::Tue);
|
||||
assert_eq!(Of::new(1, G).weekday(), Weekday::Mon);
|
||||
assert_eq!(Of::new(1, AG).weekday(), Weekday::Sun);
|
||||
assert_eq!(Of::new(1, BA).weekday(), Weekday::Sat);
|
||||
assert_eq!(Of::new(1, CB).weekday(), Weekday::Fri);
|
||||
assert_eq!(Of::new(1, DC).weekday(), Weekday::Thu);
|
||||
assert_eq!(Of::new(1, ED).weekday(), Weekday::Wed);
|
||||
assert_eq!(Of::new(1, FE).weekday(), Weekday::Tue);
|
||||
assert_eq!(Of::new(1, GF).weekday(), Weekday::Mon);
|
||||
|
||||
for &flags in FLAGS.iter() {
|
||||
let mut prev = Of::new(1, flags).weekday();
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
use std::fmt;
|
||||
use std::num::Int;
|
||||
use num::Integer;
|
||||
|
||||
use {Weekday, Timelike, Datelike};
|
||||
|
@ -49,7 +50,7 @@ impl NaiveDateTime {
|
|||
#[inline]
|
||||
pub fn from_num_seconds_from_unix_epoch_opt(secs: i64, nsecs: u32) -> Option<NaiveDateTime> {
|
||||
let (days, secs) = secs.div_mod_floor(&86400);
|
||||
let date = days.to_i32().and_then(|days| days.checked_add(&719163))
|
||||
let date = days.to_i32().and_then(|days| days.checked_add(719163))
|
||||
.and_then(|days_ce| NaiveDate::from_num_days_from_ce_opt(days_ce));
|
||||
let time = NaiveTime::from_num_seconds_from_midnight_opt(secs as u32, nsecs);
|
||||
match (date, time) {
|
||||
|
@ -208,7 +209,6 @@ mod tests {
|
|||
use duration::Duration;
|
||||
use naive::date::NaiveDate;
|
||||
use std::i64;
|
||||
use std::num::Zero;
|
||||
|
||||
#[test]
|
||||
fn test_datetime_from_num_seconds_from_unix_epoch() {
|
||||
|
@ -241,7 +241,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_datetime_sub() {
|
||||
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), Zero::zero());
|
||||
assert_eq!(ymdhms(2014, 5, 6, 7, 8, 9) - ymdhms(2014, 5, 6, 7, 8, 9), Duration::zero());
|
||||
assert_eq!(ymdhms(2014, 5, 6, 7, 8, 10) - ymdhms(2014, 5, 6, 7, 8, 9),
|
||||
Duration::seconds(1));
|
||||
assert_eq!(ymdhms(2014, 5, 6, 7, 8, 9) - ymdhms(2014, 5, 6, 7, 8, 10),
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
use std::fmt;
|
||||
use std::num::Int;
|
||||
use num::Integer;
|
||||
|
||||
use Timelike;
|
||||
|
@ -54,7 +55,7 @@ impl NaiveTime {
|
|||
/// Returns `None` on invalid hour, minute, second and/or millisecond.
|
||||
#[inline]
|
||||
pub fn from_hms_milli_opt(hour: u32, min: u32, sec: u32, milli: u32) -> Option<NaiveTime> {
|
||||
milli.checked_mul(&1_000_000)
|
||||
milli.checked_mul(1_000_000)
|
||||
.and_then(|nano| NaiveTime::from_hms_nano_opt(hour, min, sec, nano))
|
||||
}
|
||||
|
||||
|
@ -73,7 +74,7 @@ impl NaiveTime {
|
|||
/// Returns `None` on invalid hour, minute, second and/or microsecond.
|
||||
#[inline]
|
||||
pub fn from_hms_micro_opt(hour: u32, min: u32, sec: u32, micro: u32) -> Option<NaiveTime> {
|
||||
micro.checked_mul(&1_000)
|
||||
micro.checked_mul(1_000)
|
||||
.and_then(|nano| NaiveTime::from_hms_nano_opt(hour, min, sec, nano))
|
||||
}
|
||||
|
||||
|
@ -242,7 +243,6 @@ mod tests {
|
|||
use Timelike;
|
||||
use duration::Duration;
|
||||
use std::u32;
|
||||
use std::num::Zero;
|
||||
|
||||
#[test]
|
||||
fn test_time_from_hms_milli() {
|
||||
|
@ -308,7 +308,7 @@ mod tests {
|
|||
|
||||
let hmsm = |h,m,s,mi| NaiveTime::from_hms_milli(h, m, s, mi);
|
||||
|
||||
check(hmsm(3, 5, 7, 900), Zero::zero(), hmsm(3, 5, 7, 900));
|
||||
check(hmsm(3, 5, 7, 900), Duration::zero(), hmsm(3, 5, 7, 900));
|
||||
check(hmsm(3, 5, 7, 900), Duration::milliseconds(100), hmsm(3, 5, 8, 0));
|
||||
check(hmsm(3, 5, 7, 1_300), Duration::milliseconds(800), hmsm(3, 5, 8, 100));
|
||||
check(hmsm(3, 5, 7, 900), Duration::seconds(86399), hmsm(3, 5, 6, 900)); // overwrap
|
||||
|
@ -326,7 +326,7 @@ mod tests {
|
|||
|
||||
let hmsm = |h,m,s,mi| NaiveTime::from_hms_milli(h, m, s, mi);
|
||||
|
||||
check(hmsm(3, 5, 7, 900), hmsm(3, 5, 7, 900), Zero::zero());
|
||||
check(hmsm(3, 5, 7, 900), hmsm(3, 5, 7, 900), Duration::zero());
|
||||
check(hmsm(3, 5, 7, 900), hmsm(3, 5, 7, 600), Duration::milliseconds(300));
|
||||
check(hmsm(3, 5, 7, 200), hmsm(2, 4, 6, 200), Duration::seconds(3600 + 60 + 1));
|
||||
check(hmsm(3, 5, 7, 200), hmsm(2, 4, 6, 300),
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
use std::fmt;
|
||||
use std::str::MaybeOwned;
|
||||
use std::num::Zero;
|
||||
use stdtime;
|
||||
use num::Integer;
|
||||
|
||||
|
@ -25,7 +24,7 @@ use datetime::DateTime;
|
|||
pub enum LocalResult<T> {
|
||||
/// Given local time representation is invalid.
|
||||
/// This can occur when, for example, the positive timezone transition.
|
||||
NoResult,
|
||||
None,
|
||||
/// Given local time representation has a single unique result.
|
||||
Single(T),
|
||||
/// Given local time representation has multiple results and thus ambiguous.
|
||||
|
@ -36,17 +35,17 @@ pub enum LocalResult<T> {
|
|||
impl<T> LocalResult<T> {
|
||||
/// Returns `Some` only when the conversion result is unique, or `None` otherwise.
|
||||
pub fn single(self) -> Option<T> {
|
||||
match self { Single(t) => Some(t), _ => None }
|
||||
match self { LocalResult::Single(t) => Some(t), _ => None }
|
||||
}
|
||||
|
||||
/// Returns `Some` for the earliest possible conversion result, or `None` if none.
|
||||
pub fn earliest(self) -> Option<T> {
|
||||
match self { Single(t) | Ambiguous(t,_) => Some(t), _ => None }
|
||||
match self { LocalResult::Single(t) | LocalResult::Ambiguous(t,_) => Some(t), _ => None }
|
||||
}
|
||||
|
||||
/// Returns `Some` for the latest possible conversion result, or `None` if none.
|
||||
pub fn latest(self) -> Option<T> {
|
||||
match self { Single(t) | Ambiguous(_,t) => Some(t), _ => None }
|
||||
match self { LocalResult::Single(t) | LocalResult::Ambiguous(_,t) => Some(t), _ => None }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,9 +53,11 @@ impl<T:fmt::Show> LocalResult<T> {
|
|||
/// Returns the single unique conversion result, or fails accordingly.
|
||||
pub fn unwrap(self) -> T {
|
||||
match self {
|
||||
NoResult => panic!("No such local time"),
|
||||
Single(t) => t,
|
||||
Ambiguous(t1,t2) => panic!("Ambiguous local time, ranging from {} to {}", t1, t2),
|
||||
LocalResult::None => panic!("No such local time"),
|
||||
LocalResult::Single(t) => t,
|
||||
LocalResult::Ambiguous(t1,t2) => {
|
||||
panic!("Ambiguous local time, ranging from {} to {}", t1, t2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +85,7 @@ pub trait Offset: Clone + fmt::Show {
|
|||
fn ymd_opt(&self, year: i32, month: u32, day: u32) -> LocalResult<Date<Self>> {
|
||||
match NaiveDate::from_ymd_opt(year, month, day) {
|
||||
Some(d) => self.from_local_date(&d),
|
||||
None => NoResult,
|
||||
None => LocalResult::None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,7 +110,7 @@ pub trait Offset: Clone + fmt::Show {
|
|||
fn yo_opt(&self, year: i32, ordinal: u32) -> LocalResult<Date<Self>> {
|
||||
match NaiveDate::from_yo_opt(year, ordinal) {
|
||||
Some(d) => self.from_local_date(&d),
|
||||
None => NoResult,
|
||||
None => LocalResult::None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,7 +139,7 @@ pub trait Offset: Clone + fmt::Show {
|
|||
fn isoywd_opt(&self, year: i32, week: u32, weekday: Weekday) -> LocalResult<Date<Self>> {
|
||||
match NaiveDate::from_isoywd_opt(year, week, weekday) {
|
||||
Some(d) => self.from_local_date(&d),
|
||||
None => NoResult,
|
||||
None => LocalResult::None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,7 +156,7 @@ pub trait Offset: Clone + fmt::Show {
|
|||
fn hms_opt(&self, hour: u32, min: u32, sec: u32) -> LocalResult<Time<Self>> {
|
||||
match NaiveTime::from_hms_opt(hour, min, sec) {
|
||||
Some(t) => self.from_local_time(&t),
|
||||
None => NoResult,
|
||||
None => LocalResult::None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,7 +175,7 @@ pub trait Offset: Clone + fmt::Show {
|
|||
fn hms_milli_opt(&self, hour: u32, min: u32, sec: u32, milli: u32) -> LocalResult<Time<Self>> {
|
||||
match NaiveTime::from_hms_milli_opt(hour, min, sec, milli) {
|
||||
Some(t) => self.from_local_time(&t),
|
||||
None => NoResult,
|
||||
None => LocalResult::None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -193,7 +194,7 @@ pub trait Offset: Clone + fmt::Show {
|
|||
fn hms_micro_opt(&self, hour: u32, min: u32, sec: u32, micro: u32) -> LocalResult<Time<Self>> {
|
||||
match NaiveTime::from_hms_micro_opt(hour, min, sec, micro) {
|
||||
Some(t) => self.from_local_time(&t),
|
||||
None => NoResult,
|
||||
None => LocalResult::None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,7 +213,7 @@ pub trait Offset: Clone + fmt::Show {
|
|||
fn hms_nano_opt(&self, hour: u32, min: u32, sec: u32, nano: u32) -> LocalResult<Time<Self>> {
|
||||
match NaiveTime::from_hms_nano_opt(hour, min, sec, nano) {
|
||||
Some(t) => self.from_local_time(&t),
|
||||
None => NoResult,
|
||||
None => LocalResult::None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,16 +263,16 @@ impl UTC {
|
|||
|
||||
impl Offset for UTC {
|
||||
fn name(&self) -> MaybeOwned<'static> { "UTC".into_maybe_owned() }
|
||||
fn local_minus_utc(&self) -> Duration { Zero::zero() }
|
||||
fn local_minus_utc(&self) -> Duration { Duration::zero() }
|
||||
|
||||
fn from_local_date(&self, local: &NaiveDate) -> LocalResult<Date<UTC>> {
|
||||
Single(Date::from_utc(local.clone(), UTC))
|
||||
LocalResult::Single(Date::from_utc(local.clone(), UTC))
|
||||
}
|
||||
fn from_local_time(&self, local: &NaiveTime) -> LocalResult<Time<UTC>> {
|
||||
Single(Time::from_utc(local.clone(), UTC))
|
||||
LocalResult::Single(Time::from_utc(local.clone(), UTC))
|
||||
}
|
||||
fn from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<DateTime<UTC>> {
|
||||
Single(DateTime::from_utc(local.clone(), UTC))
|
||||
LocalResult::Single(DateTime::from_utc(local.clone(), UTC))
|
||||
}
|
||||
|
||||
fn to_local_date(&self, utc: &NaiveDate) -> NaiveDate { utc.clone() }
|
||||
|
@ -336,15 +337,17 @@ impl Offset for FixedOffset {
|
|||
fn local_minus_utc(&self) -> Duration { Duration::seconds(self.local_minus_utc as i64) }
|
||||
|
||||
fn from_local_date(&self, local: &NaiveDate) -> LocalResult<Date<FixedOffset>> {
|
||||
Single(Date::from_utc(local.clone(), self.clone()))
|
||||
LocalResult::Single(Date::from_utc(local.clone(), self.clone()))
|
||||
}
|
||||
fn from_local_time(&self, local: &NaiveTime) -> LocalResult<Time<FixedOffset>> {
|
||||
Single(Time::from_utc(*local + Duration::seconds(-self.local_minus_utc as i64),
|
||||
self.clone()))
|
||||
let t = Time::from_utc(*local + Duration::seconds(-self.local_minus_utc as i64),
|
||||
self.clone());
|
||||
LocalResult::Single(t)
|
||||
}
|
||||
fn from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<DateTime<FixedOffset>> {
|
||||
Single(DateTime::from_utc(*local + Duration::seconds(-self.local_minus_utc as i64),
|
||||
self.clone()))
|
||||
let dt = DateTime::from_utc(*local + Duration::seconds(-self.local_minus_utc as i64),
|
||||
self.clone());
|
||||
LocalResult::Single(dt)
|
||||
}
|
||||
|
||||
fn to_local_date(&self, utc: &NaiveDate) -> NaiveDate {
|
||||
|
@ -391,8 +394,8 @@ impl Local {
|
|||
let date = NaiveDate::from_yo(tm.tm_year + 1900, tm.tm_yday as u32 + 1);
|
||||
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);
|
||||
let offset = Local { cached: FixedOffset::east(tm.tm_gmtoff) };
|
||||
DateTime::from_utc(date.and_time(time) + Duration::seconds(-tm.tm_gmtoff as i64), offset)
|
||||
let offset = Local { cached: FixedOffset::east(tm.tm_utcoff) };
|
||||
DateTime::from_utc(date.and_time(time) + Duration::seconds(-tm.tm_utcoff as i64), offset)
|
||||
}
|
||||
|
||||
/// Converts a local `NaiveDateTime` to the `time::Timespec`.
|
||||
|
@ -407,7 +410,7 @@ impl Local {
|
|||
tm_wday: 0, // to_local ignores this
|
||||
tm_yday: 0, // and this
|
||||
tm_isdst: -1,
|
||||
tm_gmtoff: 1, // this is arbitrary but should be nonzero
|
||||
tm_utcoff: 1, // this is arbitrary but should be nonzero
|
||||
// in order to make `to_timespec` use `rust_mktime` internally.
|
||||
tm_nsec: d.nanosecond() as i32,
|
||||
};
|
||||
|
@ -431,24 +434,24 @@ impl Offset for Local {
|
|||
|
||||
fn from_local_date(&self, local: &NaiveDate) -> LocalResult<Date<Local>> {
|
||||
match self.from_local_datetime(&local.and_hms(0, 0, 0)) {
|
||||
NoResult => NoResult,
|
||||
Single(dt) => Single(dt.date()),
|
||||
Ambiguous(min, max) => {
|
||||
LocalResult::None => LocalResult::None,
|
||||
LocalResult::Single(dt) => LocalResult::Single(dt.date()),
|
||||
LocalResult::Ambiguous(min, max) => {
|
||||
let min = min.date();
|
||||
let max = max.date();
|
||||
if min == max {Single(min)} else {Ambiguous(min, max)}
|
||||
if min == max {LocalResult::Single(min)} else {LocalResult::Ambiguous(min, max)}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn from_local_time(&self, local: &NaiveTime) -> LocalResult<Time<Local>> {
|
||||
// XXX we don't have enough information here, so we assume that the timezone remains same
|
||||
Single(Time::from_utc(local.clone(), self.clone()))
|
||||
LocalResult::Single(Time::from_utc(local.clone(), self.clone()))
|
||||
}
|
||||
|
||||
fn from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<DateTime<Local>> {
|
||||
let timespec = Local::datetime_to_timespec(local);
|
||||
Single(Local::tm_to_datetime(stdtime::at(timespec)))
|
||||
LocalResult::Single(Local::tm_to_datetime(stdtime::at(timespec)))
|
||||
}
|
||||
|
||||
fn to_local_date(&self, utc: &NaiveDate) -> NaiveDate { self.cached.to_local_date(utc) }
|
||||
|
|
Loading…
Reference in New Issue