Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.5: Let TimeDelta::{weeks, days, hours, minutes, seconds} take i32 #1515

Merged
merged 6 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bench/benches/chrono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ fn bench_format_manual(c: &mut Criterion) {

fn bench_naivedate_add_signed(c: &mut Criterion) {
let date = NaiveDate::from_ymd(2023, 7, 29).unwrap();
let extra = TimeDelta::days(25).unwrap();
let extra = TimeDelta::days(25);
c.bench_function("bench_naivedate_add_signed", |b| {
b.iter(|| black_box(date).checked_add_signed(extra).unwrap())
});
Expand Down
42 changes: 18 additions & 24 deletions src/datetime/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl TimeZone for DstTester {
DstTester::TO_WINTER_MONTH_DAY.1,
)
.unwrap()
.and_time(DstTester::transition_start_local() - TimeDelta::hours(1).unwrap());
.and_time(DstTester::transition_start_local() - TimeDelta::hours(1));

let local_to_summer_transition_start = NaiveDate::from_ymd(
local.year(),
Expand All @@ -67,7 +67,7 @@ impl TimeZone for DstTester {
DstTester::TO_SUMMER_MONTH_DAY.1,
)
.unwrap()
.and_time(DstTester::transition_start_local() + TimeDelta::hours(1).unwrap());
.and_time(DstTester::transition_start_local() + TimeDelta::hours(1));

if *local < local_to_winter_transition_end || *local >= local_to_summer_transition_end {
LocalResult::Single(DstTester::summer_offset())
Expand Down Expand Up @@ -569,12 +569,12 @@ fn test_datetime_offset() {
let dt = Utc.with_ymd_and_hms(2014, 5, 6, 7, 8, 9).unwrap();
assert_eq!(dt, edt.with_ymd_and_hms(2014, 5, 6, 3, 8, 9).unwrap());
assert_eq!(
dt + TimeDelta::seconds(3600 + 60 + 1).unwrap(),
dt + TimeDelta::seconds(3600 + 60 + 1),
Utc.with_ymd_and_hms(2014, 5, 6, 8, 9, 10).unwrap()
);
assert_eq!(
dt.signed_duration_since(edt.with_ymd_and_hms(2014, 5, 6, 10, 11, 12).unwrap()),
TimeDelta::seconds(-7 * 3600 - 3 * 60 - 3).unwrap()
TimeDelta::seconds(-7 * 3600 - 3 * 60 - 3)
);

assert_eq!(*Utc.with_ymd_and_hms(2014, 5, 6, 7, 8, 9).unwrap().offset(), Utc);
Expand Down Expand Up @@ -1389,20 +1389,20 @@ fn test_datetime_add_assign() {
let datetime = naivedatetime.and_utc();
let mut datetime_add = datetime;

datetime_add += TimeDelta::seconds(60).unwrap();
assert_eq!(datetime_add, datetime + TimeDelta::seconds(60).unwrap());
datetime_add += TimeDelta::seconds(60);
assert_eq!(datetime_add, datetime + TimeDelta::seconds(60));

let timezone = FixedOffset::east(60 * 60).unwrap();
let datetime = datetime.with_timezone(&timezone);
let datetime_add = datetime_add.with_timezone(&timezone);

assert_eq!(datetime_add, datetime + TimeDelta::seconds(60).unwrap());
assert_eq!(datetime_add, datetime + TimeDelta::seconds(60));

let timezone = FixedOffset::west(2 * 60 * 60).unwrap();
let datetime = datetime.with_timezone(&timezone);
let datetime_add = datetime_add.with_timezone(&timezone);

assert_eq!(datetime_add, datetime + TimeDelta::seconds(60).unwrap());
assert_eq!(datetime_add, datetime + TimeDelta::seconds(60));
}

#[test]
Expand All @@ -1415,8 +1415,8 @@ fn test_datetime_add_assign_local() {

// ensure we cross a DST transition
for i in 1..=365 {
datetime_add += TimeDelta::days(1).unwrap();
assert_eq!(datetime_add, datetime + TimeDelta::days(i).unwrap())
datetime_add += TimeDelta::days(1);
assert_eq!(datetime_add, datetime + TimeDelta::days(i))
}
}

Expand All @@ -1426,20 +1426,20 @@ fn test_datetime_sub_assign() {
let datetime = naivedatetime.and_utc();
let mut datetime_sub = datetime;

datetime_sub -= TimeDelta::minutes(90).unwrap();
assert_eq!(datetime_sub, datetime - TimeDelta::minutes(90).unwrap());
datetime_sub -= TimeDelta::minutes(90);
assert_eq!(datetime_sub, datetime - TimeDelta::minutes(90));

let timezone = FixedOffset::east(60 * 60).unwrap();
let datetime = datetime.with_timezone(&timezone);
let datetime_sub = datetime_sub.with_timezone(&timezone);

assert_eq!(datetime_sub, datetime - TimeDelta::minutes(90).unwrap());
assert_eq!(datetime_sub, datetime - TimeDelta::minutes(90));

let timezone = FixedOffset::west(2 * 60 * 60).unwrap();
let datetime = datetime.with_timezone(&timezone);
let datetime_sub = datetime_sub.with_timezone(&timezone);

assert_eq!(datetime_sub, datetime - TimeDelta::minutes(90).unwrap());
assert_eq!(datetime_sub, datetime - TimeDelta::minutes(90));
}

#[test]
Expand Down Expand Up @@ -1522,10 +1522,7 @@ fn test_min_max_setters() {
assert_eq!(beyond_min.with_ordinal0(beyond_min.ordinal0()), Some(beyond_min));
assert_eq!(beyond_min.with_ordinal0(200), None);
assert_eq!(beyond_min.with_hour(beyond_min.hour()), Some(beyond_min));
assert_eq!(
beyond_min.with_hour(23),
beyond_min.checked_add_signed(TimeDelta::hours(1).unwrap())
);
assert_eq!(beyond_min.with_hour(23), beyond_min.checked_add_signed(TimeDelta::hours(1)));
assert_eq!(beyond_min.with_hour(5), None);
assert_eq!(beyond_min.with_minute(0), Some(beyond_min));
assert_eq!(beyond_min.with_second(0), Some(beyond_min));
Expand All @@ -1546,10 +1543,7 @@ fn test_min_max_setters() {
assert_eq!(beyond_max.with_ordinal0(beyond_max.ordinal0()), Some(beyond_max));
assert_eq!(beyond_max.with_ordinal0(200), None);
assert_eq!(beyond_max.with_hour(beyond_max.hour()), Some(beyond_max));
assert_eq!(
beyond_max.with_hour(0),
beyond_max.checked_sub_signed(TimeDelta::hours(1).unwrap())
);
assert_eq!(beyond_max.with_hour(0), beyond_max.checked_sub_signed(TimeDelta::hours(1)));
assert_eq!(beyond_max.with_hour(5), None);
assert_eq!(beyond_max.with_minute(beyond_max.minute()), Some(beyond_max));
assert_eq!(beyond_max.with_second(beyond_max.second()), Some(beyond_max));
Expand Down Expand Up @@ -1630,8 +1624,8 @@ fn test_datetime_sub_assign_local() {

// ensure we cross a DST transition
for i in 1..=365 {
datetime_sub -= TimeDelta::days(1).unwrap();
assert_eq!(datetime_sub, datetime - TimeDelta::days(i).unwrap())
datetime_sub -= TimeDelta::days(1);
assert_eq!(datetime_sub, datetime - TimeDelta::days(i))
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/format/parsed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,7 @@ impl Parsed {
59 => {}
// `datetime` is known to be off by one second.
0 => {
datetime -= TimeDelta::seconds(1).unwrap();
datetime -= TimeDelta::seconds(1);
}
// otherwise it is impossible.
_ => return Err(IMPOSSIBLE),
Expand Down
8 changes: 4 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,11 +199,11 @@
//! // arithmetic operations
//! let dt1 = Utc.with_ymd_and_hms(2014, 11, 14, 8, 9, 10).unwrap();
//! let dt2 = Utc.with_ymd_and_hms(2014, 11, 14, 10, 9, 8).unwrap();
//! assert_eq!(dt1.signed_duration_since(dt2), TimeDelta::seconds(-2 * 3600 + 2).unwrap());
//! assert_eq!(dt2.signed_duration_since(dt1), TimeDelta::seconds(2 * 3600 - 2).unwrap());
//! assert_eq!(Utc.with_ymd_and_hms(1970, 1, 1, 0, 0, 0).unwrap() + TimeDelta::seconds(1_000_000_000).unwrap(),
//! assert_eq!(dt1.signed_duration_since(dt2), TimeDelta::seconds(-2 * 3600 + 2));
//! assert_eq!(dt2.signed_duration_since(dt1), TimeDelta::seconds(2 * 3600 - 2));
//! assert_eq!(Utc.with_ymd_and_hms(1970, 1, 1, 0, 0, 0).unwrap() + TimeDelta::seconds(1_000_000_000),
//! Utc.with_ymd_and_hms(2001, 9, 9, 1, 46, 40).unwrap());
//! assert_eq!(Utc.with_ymd_and_hms(1970, 1, 1, 0, 0, 0).unwrap() - TimeDelta::seconds(1_000_000_000).unwrap(),
//! assert_eq!(Utc.with_ymd_and_hms(1970, 1, 1, 0, 0, 0).unwrap() - TimeDelta::seconds(1_000_000_000),
//! Utc.with_ymd_and_hms(1938, 4, 24, 22, 13, 20).unwrap());
//! ```
//!
Expand Down
99 changes: 41 additions & 58 deletions src/naive/date/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use crate::format::{
};
use crate::month::Months;
use crate::naive::{Days, IsoWeek, NaiveDateTime, NaiveTime, NaiveWeek};
use crate::{expect, ok, try_err, try_ok_or, try_opt};
use crate::{ok, try_err, try_ok_or, try_opt};
use crate::{Datelike, Error, TimeDelta, Weekday};

use super::internals::{Mdf, YearFlags};
Expand Down Expand Up @@ -872,16 +872,16 @@ impl NaiveDate {
///
/// let d = NaiveDate::from_ymd(2015, 9, 5).unwrap();
/// assert_eq!(
/// d.checked_add_signed(TimeDelta::days(40).unwrap()),
/// d.checked_add_signed(TimeDelta::days(40)),
/// Some(NaiveDate::from_ymd(2015, 10, 15).unwrap())
/// );
/// assert_eq!(
/// d.checked_add_signed(TimeDelta::days(-40).unwrap()),
/// d.checked_add_signed(TimeDelta::days(-40)),
/// Some(NaiveDate::from_ymd(2015, 7, 27).unwrap())
/// );
/// assert_eq!(d.checked_add_signed(TimeDelta::days(1_000_000_000).unwrap()), None);
/// assert_eq!(d.checked_add_signed(TimeDelta::days(-1_000_000_000).unwrap()), None);
/// assert_eq!(NaiveDate::MAX.checked_add_signed(TimeDelta::days(1).unwrap()), None);
/// assert_eq!(d.checked_add_signed(TimeDelta::days(1_000_000_000)), None);
/// assert_eq!(d.checked_add_signed(TimeDelta::days(-1_000_000_000)), None);
/// assert_eq!(NaiveDate::MAX.checked_add_signed(TimeDelta::days(1)), None);
/// ```
#[must_use]
pub const fn checked_add_signed(self, rhs: TimeDelta) -> Option<NaiveDate> {
Expand All @@ -905,16 +905,16 @@ impl NaiveDate {
///
/// let d = NaiveDate::from_ymd(2015, 9, 5).unwrap();
/// assert_eq!(
/// d.checked_sub_signed(TimeDelta::days(40).unwrap()),
/// d.checked_sub_signed(TimeDelta::days(40)),
/// Some(NaiveDate::from_ymd(2015, 7, 27).unwrap())
/// );
/// assert_eq!(
/// d.checked_sub_signed(TimeDelta::days(-40).unwrap()),
/// d.checked_sub_signed(TimeDelta::days(-40)),
/// Some(NaiveDate::from_ymd(2015, 10, 15).unwrap())
/// );
/// assert_eq!(d.checked_sub_signed(TimeDelta::days(1_000_000_000).unwrap()), None);
/// assert_eq!(d.checked_sub_signed(TimeDelta::days(-1_000_000_000).unwrap()), None);
/// assert_eq!(NaiveDate::MIN.checked_sub_signed(TimeDelta::days(1).unwrap()), None);
/// assert_eq!(d.checked_sub_signed(TimeDelta::days(1_000_000_000)), None);
/// assert_eq!(d.checked_sub_signed(TimeDelta::days(-1_000_000_000)), None);
/// assert_eq!(NaiveDate::MIN.checked_sub_signed(TimeDelta::days(1)), None);
/// ```
#[must_use]
pub const fn checked_sub_signed(self, rhs: TimeDelta) -> Option<NaiveDate> {
Expand All @@ -940,31 +940,23 @@ impl NaiveDate {
/// let since = NaiveDate::signed_duration_since;
///
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2014, 1, 1)), TimeDelta::zero());
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2013, 12, 31)), TimeDelta::days(1).unwrap());
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2014, 1, 2)), TimeDelta::days(-1).unwrap());
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2013, 9, 23)), TimeDelta::days(100).unwrap());
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2013, 1, 1)), TimeDelta::days(365).unwrap());
/// assert_eq!(
/// since(from_ymd(2014, 1, 1), from_ymd(2010, 1, 1)),
/// TimeDelta::days(365 * 4 + 1).unwrap()
/// );
/// assert_eq!(
/// since(from_ymd(2014, 1, 1), from_ymd(1614, 1, 1)),
/// TimeDelta::days(365 * 400 + 97).unwrap()
/// );
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2013, 12, 31)), TimeDelta::days(1));
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2014, 1, 2)), TimeDelta::days(-1));
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2013, 9, 23)), TimeDelta::days(100));
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2013, 1, 1)), TimeDelta::days(365));
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2010, 1, 1)), TimeDelta::days(365 * 4 + 1));
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(1614, 1, 1)), TimeDelta::days(365 * 400 + 97));
/// ```
#[must_use]
pub const fn signed_duration_since(self, rhs: NaiveDate) -> TimeDelta {
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 = yo_to_cycle(year1_mod_400 as u32, self.ordinal()) as i64;
let cycle2 = yo_to_cycle(year2_mod_400 as u32, rhs.ordinal()) as i64;
let days = (year1_div_400 as i64 - year2_div_400 as i64) * 146_097 + (cycle1 - cycle2);
// The range of `TimeDelta` is ca. 585 million years, the range of `NaiveDate` ca. 525.000
// years.
expect!(TimeDelta::days(days), "always in range")
let cycle1 = yo_to_cycle(year1_mod_400 as u32, self.ordinal()) as i32;
let cycle2 = yo_to_cycle(year2_mod_400 as u32, rhs.ordinal()) as i32;
let days = (year1_div_400 - year2_div_400) * 146_097 + (cycle1 - cycle2);
TimeDelta::days(days)
}

/// Returns the number of whole years from the given `base` until `self`.
Expand Down Expand Up @@ -1707,16 +1699,13 @@ impl Datelike for NaiveDate {
/// let from_ymd = |y, m, d| NaiveDate::from_ymd(y, m, d).unwrap();
///
/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::zero(), from_ymd(2014, 1, 1));
/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::seconds(86399).unwrap(), from_ymd(2014, 1, 1));
/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::seconds(-86399).unwrap(), from_ymd(2014, 1, 1));
/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::days(1).unwrap(), from_ymd(2014, 1, 2));
/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::days(-1).unwrap(), from_ymd(2013, 12, 31));
/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::days(364).unwrap(), from_ymd(2014, 12, 31));
/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::days(365 * 4 + 1).unwrap(), from_ymd(2018, 1, 1));
/// assert_eq!(
/// from_ymd(2014, 1, 1) + TimeDelta::days(365 * 400 + 97).unwrap(),
/// from_ymd(2414, 1, 1)
/// );
/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::seconds(86399), from_ymd(2014, 1, 1));
/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::seconds(-86399), from_ymd(2014, 1, 1));
/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::days(1), from_ymd(2014, 1, 2));
/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::days(-1), from_ymd(2013, 12, 31));
/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::days(364), from_ymd(2014, 12, 31));
/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::days(365 * 4 + 1), from_ymd(2018, 1, 1));
/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::days(365 * 400 + 97), from_ymd(2414, 1, 1));
/// ```
///
/// [`NaiveDate::checked_add_signed`]: crate::NaiveDate::checked_add_signed
Expand Down Expand Up @@ -1853,16 +1842,13 @@ impl Sub<Days> for NaiveDate {
/// let from_ymd = |y, m, d| NaiveDate::from_ymd(y, m, d).unwrap();
///
/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::zero(), from_ymd(2014, 1, 1));
/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::seconds(86399).unwrap(), from_ymd(2014, 1, 1));
/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::seconds(-86399).unwrap(), from_ymd(2014, 1, 1));
/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::days(1).unwrap(), from_ymd(2013, 12, 31));
/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::days(-1).unwrap(), from_ymd(2014, 1, 2));
/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::days(364).unwrap(), from_ymd(2013, 1, 2));
/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::days(365 * 4 + 1).unwrap(), from_ymd(2010, 1, 1));
/// assert_eq!(
/// from_ymd(2014, 1, 1) - TimeDelta::days(365 * 400 + 97).unwrap(),
/// from_ymd(1614, 1, 1)
/// );
/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::seconds(86399), from_ymd(2014, 1, 1));
/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::seconds(-86399), from_ymd(2014, 1, 1));
/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::days(1), from_ymd(2013, 12, 31));
/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::days(-1), from_ymd(2014, 1, 2));
/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::days(364), from_ymd(2013, 1, 2));
/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::days(365 * 4 + 1), from_ymd(2010, 1, 1));
/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::days(365 * 400 + 97), from_ymd(1614, 1, 1));
/// ```
///
/// [`NaiveDate::checked_sub_signed`]: crate::NaiveDate::checked_sub_signed
Expand Down Expand Up @@ -1909,15 +1895,12 @@ impl SubAssign<TimeDelta> for NaiveDate {
/// let from_ymd = |y, m, d| NaiveDate::from_ymd(y, m, d).unwrap();
///
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2014, 1, 1), TimeDelta::zero());
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 12, 31), TimeDelta::days(1).unwrap());
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2014, 1, 2), TimeDelta::days(-1).unwrap());
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 9, 23), TimeDelta::days(100).unwrap());
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 1, 1), TimeDelta::days(365).unwrap());
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2010, 1, 1), TimeDelta::days(365 * 4 + 1).unwrap());
/// assert_eq!(
/// from_ymd(2014, 1, 1) - from_ymd(1614, 1, 1),
/// TimeDelta::days(365 * 400 + 97).unwrap()
/// );
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 12, 31), TimeDelta::days(1));
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2014, 1, 2), TimeDelta::days(-1));
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 9, 23), TimeDelta::days(100));
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 1, 1), TimeDelta::days(365));
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2010, 1, 1), TimeDelta::days(365 * 4 + 1));
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(1614, 1, 1), TimeDelta::days(365 * 400 + 97));
/// ```
impl Sub<NaiveDate> for NaiveDate {
type Output = TimeDelta;
Expand Down
Loading
Loading