0.1.2: no more `num` dependency, multidispatched addition.
- `num` dependency is gone. It was only used for floored division and it is not hard to copy only that portion from num. - `Duration + Date` (or so) was blocked by rust-lang/rust#7590, which has been subsequently fixed. - Removed unused `unsafe` checks.
This commit is contained in:
parent
0a04ae1aa9
commit
86665d0a7f
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "chrono"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
authors = ["Kang Seonghoon <public+rust@mearie.org>"]
|
||||
|
||||
description = "Date and time library for Rust"
|
||||
|
@ -13,9 +13,6 @@ 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"
|
||||
|
||||
|
|
|
@ -263,13 +263,10 @@ impl<Off:Offset> Add<Duration,Date<Off>> for Date<Off> {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// Rust issue #7590, the current coherence checker can't handle multiple Add impls
|
||||
impl<Off:Offset> Add<Date<Off>,Date<Off>> for Duration {
|
||||
#[inline]
|
||||
fn add(&self, rhs: &Date<Off>) -> Date<Off> { rhs.add(self) }
|
||||
}
|
||||
*/
|
||||
|
||||
impl<Off:Offset, Off2:Offset> Sub<Date<Off2>,Duration> for Date<Off> {
|
||||
fn sub(&self, rhs: &Date<Off2>) -> Duration {
|
||||
|
|
|
@ -185,13 +185,10 @@ impl<Off:Offset> Add<Duration,DateTime<Off>> for DateTime<Off> {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// Rust issue #7590, the current coherence checker can't handle multiple Add impls
|
||||
impl<Off:Offset> Add<DateTime<Off>,DateTime<Off>> for Duration {
|
||||
#[inline]
|
||||
fn add(&self, rhs: &DateTime<Off>) -> DateTime<Off> { rhs.add(self) }
|
||||
}
|
||||
*/
|
||||
|
||||
impl<Off:Offset, Off2:Offset> Sub<DateTime<Off2>,Duration> for DateTime<Off> {
|
||||
fn sub(&self, rhs: &DateTime<Off2>) -> Duration {
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
// This is a part of rust-chrono.
|
||||
// Copyright (c) 2014, Kang Seonghoon.
|
||||
// Copyright 2013-2014 The Rust Project Developers.
|
||||
// See README.md and LICENSE.txt for details.
|
||||
|
||||
//! Integer division utilities. (Shamelessly copied from [num](https://github.com/rust-lang/num/))
|
||||
|
||||
// Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
|
||||
// December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
|
||||
|
||||
use std::num::Int;
|
||||
|
||||
/// Same as `(a / b, a % b)`.
|
||||
#[inline]
|
||||
pub fn div_rem<T: Int>(a: T, b: T) -> (T, T) {
|
||||
(a / b, a % b)
|
||||
}
|
||||
|
||||
/// Same as `let (q, r) = div_mod_floor(a, b); r`.
|
||||
#[inline]
|
||||
pub fn mod_floor<T: Int>(a: T, b: T) -> T {
|
||||
let zero = Int::zero();
|
||||
match a % b {
|
||||
r if (r > zero && b < zero) || (r < zero && b > zero) => r + b,
|
||||
r => r,
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculates a floored integer quotient and modulo.
|
||||
#[inline]
|
||||
pub fn div_mod_floor<T: Int>(a: T, b: T) -> (T, T) {
|
||||
let zero = Int::zero();
|
||||
let one = Int::one();
|
||||
match (a / b, a % b) {
|
||||
(d, r) if (r > zero && b < zero) || (r < zero && b > zero) => (d - one, r + b),
|
||||
(d, r) => (d, r),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{mod_floor, div_mod_floor};
|
||||
|
||||
#[test]
|
||||
fn test_mod_floor() {
|
||||
assert_eq!(mod_floor( 8i, 3), 2);
|
||||
assert_eq!(mod_floor( 8i, -3), -1);
|
||||
assert_eq!(mod_floor(-8i, 3), 1);
|
||||
assert_eq!(mod_floor(-8i, -3), -2);
|
||||
|
||||
assert_eq!(mod_floor( 1i, 2), 1);
|
||||
assert_eq!(mod_floor( 1i, -2), -1);
|
||||
assert_eq!(mod_floor(-1i, 2), 1);
|
||||
assert_eq!(mod_floor(-1i, -2), -1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_div_mod_floor() {
|
||||
assert_eq!(div_mod_floor( 8i, 3), ( 2, 2));
|
||||
assert_eq!(div_mod_floor( 8i, -3), (-3, -1));
|
||||
assert_eq!(div_mod_floor(-8i, 3), (-3, 1));
|
||||
assert_eq!(div_mod_floor(-8i, -3), ( 2, -2));
|
||||
|
||||
assert_eq!(div_mod_floor( 1i, 2), ( 0, 1));
|
||||
assert_eq!(div_mod_floor( 1i, -2), (-1, -1));
|
||||
assert_eq!(div_mod_floor(-1i, 2), (-1, 1));
|
||||
assert_eq!(div_mod_floor(-1i, -2), ( 0, -1));
|
||||
}
|
||||
}
|
||||
|
|
@ -13,7 +13,6 @@ Experimental date and time handling for Rust.
|
|||
#![feature(macro_rules)]
|
||||
#![deny(missing_docs)]
|
||||
|
||||
extern crate num;
|
||||
extern crate "time" as stdtime;
|
||||
|
||||
pub use duration::Duration;
|
||||
|
@ -26,6 +25,7 @@ pub use date::Date;
|
|||
pub use time::Time;
|
||||
pub use datetime::DateTime;
|
||||
|
||||
mod div;
|
||||
pub mod duration {
|
||||
//! ISO 8601 duration.
|
||||
//!
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
use std::fmt;
|
||||
use std::num::Int;
|
||||
use num::Integer;
|
||||
|
||||
use {Weekday, Datelike};
|
||||
use div::div_mod_floor;
|
||||
use duration::Duration;
|
||||
use naive::time::NaiveTime;
|
||||
use naive::datetime::NaiveDateTime;
|
||||
|
@ -148,9 +148,9 @@ impl NaiveDate {
|
|||
/// Returns `None` on the out-of-range date.
|
||||
pub fn from_num_days_from_ce_opt(days: i32) -> Option<NaiveDate> {
|
||||
let days = days + 365; // make January 1, 1 BCE equal to day 0
|
||||
let (year_div_400, cycle) = days.div_mod_floor(&146097);
|
||||
let (year_div_400, cycle) = div_mod_floor(days, 146097);
|
||||
let (year_mod_400, ordinal) = internals::cycle_to_yo(cycle as u32);
|
||||
let flags = unsafe { YearFlags::from_year_mod_400(year_mod_400 as i32) };
|
||||
let flags = YearFlags::from_year_mod_400(year_mod_400 as i32);
|
||||
NaiveDate::from_of(year_div_400 * 400 + year_mod_400 as i32,
|
||||
Of::new(ordinal, flags))
|
||||
}
|
||||
|
@ -382,33 +382,30 @@ impl Add<Duration,NaiveDate> for NaiveDate {
|
|||
// TODO overflow currently fails
|
||||
|
||||
let year = self.year();
|
||||
let (mut year_div_400, year_mod_400) = year.div_mod_floor(&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 = (cycle as i32).checked_add(rhs.num_days().to_i32().unwrap()).unwrap();
|
||||
let (cycle_div_400y, cycle) = cycle.div_mod_floor(&146097);
|
||||
let (cycle_div_400y, cycle) = div_mod_floor(cycle, 146097);
|
||||
year_div_400 += cycle_div_400y;
|
||||
|
||||
let (year_mod_400, ordinal) = internals::cycle_to_yo(cycle as u32);
|
||||
let flags = unsafe { YearFlags::from_year_mod_400(year_mod_400 as i32) };
|
||||
let flags = YearFlags::from_year_mod_400(year_mod_400 as i32);
|
||||
NaiveDate::from_of(year_div_400 * 400 + year_mod_400 as i32,
|
||||
Of::new(ordinal, flags)).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// Rust issue #7590, the current coherence checker can't handle multiple Add impls
|
||||
impl Add<NaiveDate,NaiveDate> for Duration {
|
||||
#[inline]
|
||||
fn add(&self, rhs: &NaiveDate) -> NaiveDate { rhs.add(self) }
|
||||
}
|
||||
*/
|
||||
|
||||
impl Sub<NaiveDate,Duration> for NaiveDate {
|
||||
fn sub(&self, rhs: &NaiveDate) -> Duration {
|
||||
let year1 = self.year();
|
||||
let year2 = rhs.year();
|
||||
let (year1_div_400, year1_mod_400) = year1.div_mod_floor(&400);
|
||||
let (year2_div_400, year2_mod_400) = year2.div_mod_floor(&400);
|
||||
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))
|
||||
|
@ -698,7 +695,7 @@ mod tests {
|
|||
let lhs = NaiveDate::from_ymd(y1, m1, d1);
|
||||
let sum = NaiveDate::from_ymd(y, m, d);
|
||||
assert_eq!(lhs + rhs, sum);
|
||||
//assert_eq!(rhs + lhs, sum);
|
||||
assert_eq!(rhs + lhs, sum);
|
||||
}
|
||||
|
||||
check((2014, 1, 1), Duration::zero(), (2014, 1, 1));
|
||||
|
@ -780,8 +777,8 @@ mod tests {
|
|||
#[allow(dead_code)] // some internal methods have been left for consistency
|
||||
mod internals {
|
||||
use std::{i32, num, fmt};
|
||||
use num::Integer;
|
||||
use Weekday;
|
||||
use div::{div_rem, mod_floor};
|
||||
|
||||
/// The internal date representation. This also includes the packed `Mdf` value.
|
||||
pub type DateImpl = i32;
|
||||
|
@ -855,7 +852,7 @@ mod internals {
|
|||
];
|
||||
|
||||
pub fn cycle_to_yo(cycle: u32) -> (u32, u32) {
|
||||
let (mut year_mod_400, mut ordinal0) = cycle.div_rem(&365);
|
||||
let (mut year_mod_400, mut ordinal0) = div_rem(cycle, 365);
|
||||
let delta = YEAR_DELTAS[year_mod_400 as uint] as u32;
|
||||
if ordinal0 < delta {
|
||||
year_mod_400 -= 1;
|
||||
|
@ -873,12 +870,12 @@ mod internals {
|
|||
impl YearFlags {
|
||||
#[inline]
|
||||
pub fn from_year(year: i32) -> YearFlags {
|
||||
let year = year.mod_floor(&400);
|
||||
unsafe { YearFlags::from_year_mod_400(year) }
|
||||
let year = mod_floor(year, 400);
|
||||
YearFlags::from_year_mod_400(year)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn from_year_mod_400(year: i32) -> YearFlags {
|
||||
pub fn from_year_mod_400(year: i32) -> YearFlags {
|
||||
YEAR_TO_FLAGS[year as uint]
|
||||
}
|
||||
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
use std::fmt;
|
||||
use std::num::Int;
|
||||
use num::Integer;
|
||||
|
||||
use {Weekday, Timelike, Datelike};
|
||||
use div::div_mod_floor;
|
||||
use duration::Duration;
|
||||
use naive::time::NaiveTime;
|
||||
use naive::date::NaiveDate;
|
||||
|
@ -49,7 +49,7 @@ impl NaiveDateTime {
|
|||
/// Returns `None` on the out-of-range number of seconds and/or invalid nanosecond.
|
||||
#[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 (days, secs) = div_mod_floor(secs, 86400);
|
||||
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);
|
||||
|
@ -183,13 +183,10 @@ impl Add<Duration,NaiveDateTime> for NaiveDateTime {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// Rust issue #7590, the current coherence checker can't handle multiple Add impls
|
||||
impl Add<NaiveDateTime,NaiveDateTime> for Duration {
|
||||
#[inline]
|
||||
fn add(&self, rhs: &NaiveDateTime) -> NaiveDateTime { rhs.add(self) }
|
||||
}
|
||||
*/
|
||||
|
||||
impl Sub<NaiveDateTime,Duration> for NaiveDateTime {
|
||||
fn sub(&self, rhs: &NaiveDateTime) -> Duration {
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
use std::fmt;
|
||||
use std::num::Int;
|
||||
use num::Integer;
|
||||
|
||||
use Timelike;
|
||||
use div::div_mod_floor;
|
||||
use offset::Offset;
|
||||
use duration::Duration;
|
||||
use format::DelayedFormat;
|
||||
|
@ -126,8 +126,8 @@ impl NaiveTime {
|
|||
|
||||
/// Returns a triple of the hour, minute and second numbers.
|
||||
fn hms(&self) -> (u32, u32, u32) {
|
||||
let (mins, sec) = self.secs.div_mod_floor(&60);
|
||||
let (hour, min) = mins.div_mod_floor(&60);
|
||||
let (mins, sec) = div_mod_floor(self.secs, 60);
|
||||
let (hour, min) = div_mod_floor(mins, 60);
|
||||
(hour, min, sec)
|
||||
}
|
||||
}
|
||||
|
@ -190,13 +190,10 @@ impl Add<Duration,NaiveTime> for NaiveTime {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// Rust issue #7590, the current coherence checker can't handle multiple Add impls
|
||||
impl Add<NaiveTime,NaiveTime> for Duration {
|
||||
#[inline]
|
||||
fn add(&self, rhs: &NaiveTime) -> NaiveTime { rhs.add(self) }
|
||||
}
|
||||
*/
|
||||
|
||||
impl Sub<NaiveTime,Duration> for NaiveTime {
|
||||
fn sub(&self, rhs: &NaiveTime) -> Duration {
|
||||
|
@ -303,7 +300,7 @@ mod tests {
|
|||
fn test_time_add() {
|
||||
fn check(lhs: NaiveTime, rhs: Duration, sum: NaiveTime) {
|
||||
assert_eq!(lhs + rhs, sum);
|
||||
//assert_eq!(rhs + lhs, sum);
|
||||
assert_eq!(rhs + lhs, sum);
|
||||
}
|
||||
|
||||
let hmsm = |h,m,s,mi| NaiveTime::from_hms_milli(h, m, s, mi);
|
||||
|
|
|
@ -9,9 +9,9 @@
|
|||
use std::fmt;
|
||||
use std::str::MaybeOwned;
|
||||
use stdtime;
|
||||
use num::Integer;
|
||||
|
||||
use {Weekday, Datelike, Timelike};
|
||||
use div::div_mod_floor;
|
||||
use duration::Duration;
|
||||
use naive::date::NaiveDate;
|
||||
use naive::time::NaiveTime;
|
||||
|
@ -365,8 +365,8 @@ impl fmt::Show for FixedOffset {
|
|||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let offset = self.local_minus_utc;
|
||||
let (sign, offset) = if offset < 0 {('-', -offset)} else {('+', offset)};
|
||||
let (mins, sec) = offset.div_mod_floor(&60);
|
||||
let (hour, min) = mins.div_mod_floor(&60);
|
||||
let (mins, sec) = div_mod_floor(offset, 60);
|
||||
let (hour, min) = div_mod_floor(mins, 60);
|
||||
if sec == 0 {
|
||||
write!(f, "{}{:02}:{:02}", sign, hour, min)
|
||||
} else {
|
||||
|
|
|
@ -113,13 +113,10 @@ impl<Off:Offset> Add<Duration,Time<Off>> for Time<Off> {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// Rust issue #7590, the current coherence checker can't handle multiple Add impls
|
||||
impl<Off:Offset> Add<Time<Off>,Time<Off>> for Duration {
|
||||
#[inline]
|
||||
fn add(&self, rhs: &Time<Off>) -> Time<Off> { rhs.add(self) }
|
||||
}
|
||||
*/
|
||||
|
||||
impl<Off:Offset, Off2:Offset> Sub<Time<Off2>,Duration> for Time<Off> {
|
||||
fn sub(&self, rhs: &Time<Off2>) -> Duration {
|
||||
|
|
Loading…
Reference in New Issue