Rename Duration to TimeDelta in round module

This commit is contained in:
Paul Dicker 2024-02-02 19:55:18 +01:00 committed by Paul Dicker
parent 20e9a73aa3
commit 3bd9a90e91

View File

@ -1,13 +1,9 @@
// 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.
//! Functionality for rounding or truncating a `DateTime` by a `Duration`. //! Functionality for rounding or truncating a `DateTime` by a `TimeDelta`.
use crate::datetime::DateTime; use crate::{DateTime, NaiveDateTime, TimeDelta, TimeZone, Timelike};
use crate::duration::Duration;
use crate::NaiveDateTime;
use crate::TimeZone;
use crate::Timelike;
use core::cmp::Ordering; use core::cmp::Ordering;
use core::fmt; use core::fmt;
use core::marker::Sized; use core::marker::Sized;
@ -48,7 +44,7 @@ pub trait SubsecRound {
impl<T> SubsecRound for T impl<T> SubsecRound for T
where where
T: Timelike + Add<Duration, Output = T> + Sub<Duration, Output = T>, T: Timelike + Add<TimeDelta, Output = T> + Sub<TimeDelta, Output = T>,
{ {
fn round_subsecs(self, digits: u16) -> T { fn round_subsecs(self, digits: u16) -> T {
let span = span_for_digits(digits); let span = span_for_digits(digits);
@ -56,9 +52,9 @@ where
if delta_down > 0 { if delta_down > 0 {
let delta_up = span - delta_down; let delta_up = span - delta_down;
if delta_up <= delta_down { if delta_up <= delta_down {
self + Duration::nanoseconds(delta_up.into()) self + TimeDelta::nanoseconds(delta_up.into())
} else { } else {
self - Duration::nanoseconds(delta_down.into()) self - TimeDelta::nanoseconds(delta_down.into())
} }
} else { } else {
self // unchanged self // unchanged
@ -69,7 +65,7 @@ where
let span = span_for_digits(digits); let span = span_for_digits(digits);
let delta_down = self.nanosecond() % span; let delta_down = self.nanosecond() % span;
if delta_down > 0 { if delta_down > 0 {
self - Duration::nanoseconds(delta_down.into()) self - TimeDelta::nanoseconds(delta_down.into())
} else { } else {
self // unchanged self // unchanged
} }
@ -93,13 +89,13 @@ const fn span_for_digits(digits: u16) -> u32 {
} }
} }
/// Extension trait for rounding or truncating a DateTime by a Duration. /// Extension trait for rounding or truncating a DateTime by a TimeDelta.
/// ///
/// # Limitations /// # Limitations
/// Both rounding and truncating are done via [`Duration::num_nanoseconds`] and /// Both rounding and truncating are done via [`TimeDelta::num_nanoseconds`] and
/// [`DateTime::timestamp_nanos_opt`]. This means that they will fail if either the /// [`DateTime::timestamp_nanos_opt`]. This means that they will fail if either the
/// `Duration` or the `DateTime` are too big to represented as nanoseconds. They /// `TimeDelta` or the `DateTime` are too big to represented as nanoseconds. They
/// will also fail if the `Duration` is bigger than the timestamp. /// will also fail if the `TimeDelta` is bigger than the timestamp.
pub trait DurationRound: Sized { pub trait DurationRound: Sized {
/// Error that can occur in rounding or truncating /// Error that can occur in rounding or truncating
#[cfg(feature = "std")] #[cfg(feature = "std")]
@ -109,49 +105,49 @@ pub trait DurationRound: Sized {
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
type Err: fmt::Debug + fmt::Display; type Err: fmt::Debug + fmt::Display;
/// Return a copy rounded by Duration. /// Return a copy rounded by TimeDelta.
/// ///
/// # Example /// # Example
/// ``` rust /// ``` rust
/// # use chrono::{DurationRound, Duration, Utc, NaiveDate}; /// # use chrono::{DurationRound, TimeDelta, Utc, NaiveDate};
/// let dt = NaiveDate::from_ymd_opt(2018, 1, 11).unwrap().and_hms_milli_opt(12, 0, 0, 154).unwrap().and_local_timezone(Utc).unwrap(); /// let dt = NaiveDate::from_ymd_opt(2018, 1, 11).unwrap().and_hms_milli_opt(12, 0, 0, 154).unwrap().and_local_timezone(Utc).unwrap();
/// assert_eq!( /// assert_eq!(
/// dt.duration_round(Duration::milliseconds(10)).unwrap().to_string(), /// dt.duration_round(TimeDelta::milliseconds(10)).unwrap().to_string(),
/// "2018-01-11 12:00:00.150 UTC" /// "2018-01-11 12:00:00.150 UTC"
/// ); /// );
/// assert_eq!( /// assert_eq!(
/// dt.duration_round(Duration::days(1)).unwrap().to_string(), /// dt.duration_round(TimeDelta::days(1)).unwrap().to_string(),
/// "2018-01-12 00:00:00 UTC" /// "2018-01-12 00:00:00 UTC"
/// ); /// );
/// ``` /// ```
fn duration_round(self, duration: Duration) -> Result<Self, Self::Err>; fn duration_round(self, duration: TimeDelta) -> Result<Self, Self::Err>;
/// Return a copy truncated by Duration. /// Return a copy truncated by TimeDelta.
/// ///
/// # Example /// # Example
/// ``` rust /// ``` rust
/// # use chrono::{DurationRound, Duration, Utc, NaiveDate}; /// # use chrono::{DurationRound, TimeDelta, Utc, NaiveDate};
/// let dt = NaiveDate::from_ymd_opt(2018, 1, 11).unwrap().and_hms_milli_opt(12, 0, 0, 154).unwrap().and_local_timezone(Utc).unwrap(); /// let dt = NaiveDate::from_ymd_opt(2018, 1, 11).unwrap().and_hms_milli_opt(12, 0, 0, 154).unwrap().and_local_timezone(Utc).unwrap();
/// assert_eq!( /// assert_eq!(
/// dt.duration_trunc(Duration::milliseconds(10)).unwrap().to_string(), /// dt.duration_trunc(TimeDelta::milliseconds(10)).unwrap().to_string(),
/// "2018-01-11 12:00:00.150 UTC" /// "2018-01-11 12:00:00.150 UTC"
/// ); /// );
/// assert_eq!( /// assert_eq!(
/// dt.duration_trunc(Duration::days(1)).unwrap().to_string(), /// dt.duration_trunc(TimeDelta::days(1)).unwrap().to_string(),
/// "2018-01-11 00:00:00 UTC" /// "2018-01-11 00:00:00 UTC"
/// ); /// );
/// ``` /// ```
fn duration_trunc(self, duration: Duration) -> Result<Self, Self::Err>; fn duration_trunc(self, duration: TimeDelta) -> Result<Self, Self::Err>;
} }
impl<Tz: TimeZone> DurationRound for DateTime<Tz> { impl<Tz: TimeZone> DurationRound for DateTime<Tz> {
type Err = RoundingError; type Err = RoundingError;
fn duration_round(self, duration: Duration) -> Result<Self, Self::Err> { fn duration_round(self, duration: TimeDelta) -> Result<Self, Self::Err> {
duration_round(self.naive_local(), self, duration) duration_round(self.naive_local(), self, duration)
} }
fn duration_trunc(self, duration: Duration) -> Result<Self, Self::Err> { fn duration_trunc(self, duration: TimeDelta) -> Result<Self, Self::Err> {
duration_trunc(self.naive_local(), self, duration) duration_trunc(self.naive_local(), self, duration)
} }
} }
@ -159,11 +155,11 @@ impl<Tz: TimeZone> DurationRound for DateTime<Tz> {
impl DurationRound for NaiveDateTime { impl DurationRound for NaiveDateTime {
type Err = RoundingError; type Err = RoundingError;
fn duration_round(self, duration: Duration) -> Result<Self, Self::Err> { fn duration_round(self, duration: TimeDelta) -> Result<Self, Self::Err> {
duration_round(self, self, duration) duration_round(self, self, duration)
} }
fn duration_trunc(self, duration: Duration) -> Result<Self, Self::Err> { fn duration_trunc(self, duration: TimeDelta) -> Result<Self, Self::Err> {
duration_trunc(self, self, duration) duration_trunc(self, self, duration)
} }
} }
@ -171,10 +167,10 @@ impl DurationRound for NaiveDateTime {
fn duration_round<T>( fn duration_round<T>(
naive: NaiveDateTime, naive: NaiveDateTime,
original: T, original: T,
duration: Duration, duration: TimeDelta,
) -> Result<T, RoundingError> ) -> Result<T, RoundingError>
where where
T: Timelike + Add<Duration, Output = T> + Sub<Duration, Output = T>, T: Timelike + Add<TimeDelta, Output = T> + Sub<TimeDelta, Output = T>,
{ {
if let Some(span) = duration.num_nanoseconds() { if let Some(span) = duration.num_nanoseconds() {
if span < 0 { if span < 0 {
@ -197,9 +193,9 @@ where
(span - delta_down, delta_down) (span - delta_down, delta_down)
}; };
if delta_up <= delta_down { if delta_up <= delta_down {
Ok(original + Duration::nanoseconds(delta_up)) Ok(original + TimeDelta::nanoseconds(delta_up))
} else { } else {
Ok(original - Duration::nanoseconds(delta_down)) Ok(original - TimeDelta::nanoseconds(delta_down))
} }
} }
} else { } else {
@ -210,10 +206,10 @@ where
fn duration_trunc<T>( fn duration_trunc<T>(
naive: NaiveDateTime, naive: NaiveDateTime,
original: T, original: T,
duration: Duration, duration: TimeDelta,
) -> Result<T, RoundingError> ) -> Result<T, RoundingError>
where where
T: Timelike + Add<Duration, Output = T> + Sub<Duration, Output = T>, T: Timelike + Add<TimeDelta, Output = T> + Sub<TimeDelta, Output = T>,
{ {
if let Some(span) = duration.num_nanoseconds() { if let Some(span) = duration.num_nanoseconds() {
if span < 0 { if span < 0 {
@ -226,40 +222,40 @@ where
let delta_down = stamp % span; let delta_down = stamp % span;
match delta_down.cmp(&0) { match delta_down.cmp(&0) {
Ordering::Equal => Ok(original), Ordering::Equal => Ok(original),
Ordering::Greater => Ok(original - Duration::nanoseconds(delta_down)), Ordering::Greater => Ok(original - TimeDelta::nanoseconds(delta_down)),
Ordering::Less => Ok(original - Duration::nanoseconds(span - delta_down.abs())), Ordering::Less => Ok(original - TimeDelta::nanoseconds(span - delta_down.abs())),
} }
} else { } else {
Err(RoundingError::DurationExceedsLimit) Err(RoundingError::DurationExceedsLimit)
} }
} }
/// An error from rounding by `Duration` /// An error from rounding by `TimeDelta`
/// ///
/// See: [`DurationRound`] /// See: [`DurationRound`]
#[derive(Debug, Clone, PartialEq, Eq, Copy)] #[derive(Debug, Clone, PartialEq, Eq, Copy)]
pub enum RoundingError { pub enum RoundingError {
/// Error when the Duration exceeds the Duration from or until the Unix epoch. /// Error when the TimeDelta exceeds the TimeDelta from or until the Unix epoch.
/// ///
/// ``` rust /// ``` rust
/// # use chrono::{DurationRound, Duration, RoundingError, TimeZone, Utc}; /// # use chrono::{DurationRound, TimeDelta, RoundingError, TimeZone, Utc};
/// let dt = Utc.with_ymd_and_hms(1970, 12, 12, 0, 0, 0).unwrap(); /// let dt = Utc.with_ymd_and_hms(1970, 12, 12, 0, 0, 0).unwrap();
/// ///
/// assert_eq!( /// assert_eq!(
/// dt.duration_round(Duration::days(365)), /// dt.duration_round(TimeDelta::days(365)),
/// Err(RoundingError::DurationExceedsTimestamp), /// Err(RoundingError::DurationExceedsTimestamp),
/// ); /// );
/// ``` /// ```
DurationExceedsTimestamp, DurationExceedsTimestamp,
/// Error when `Duration.num_nanoseconds` exceeds the limit. /// Error when `TimeDelta.num_nanoseconds` exceeds the limit.
/// ///
/// ``` rust /// ``` rust
/// # use chrono::{DurationRound, Duration, RoundingError, Utc, NaiveDate}; /// # use chrono::{DurationRound, TimeDelta, RoundingError, Utc, NaiveDate};
/// let dt = NaiveDate::from_ymd_opt(2260, 12, 31).unwrap().and_hms_nano_opt(23, 59, 59, 1_75_500_000).unwrap().and_local_timezone(Utc).unwrap(); /// let dt = NaiveDate::from_ymd_opt(2260, 12, 31).unwrap().and_hms_nano_opt(23, 59, 59, 1_75_500_000).unwrap().and_local_timezone(Utc).unwrap();
/// ///
/// assert_eq!( /// assert_eq!(
/// dt.duration_round(Duration::days(300 * 365)), /// dt.duration_round(TimeDelta::days(300 * 365)),
/// Err(RoundingError::DurationExceedsLimit) /// Err(RoundingError::DurationExceedsLimit)
/// ); /// );
/// ``` /// ```
@ -268,10 +264,10 @@ pub enum RoundingError {
/// Error when `DateTime.timestamp_nanos` exceeds the limit. /// Error when `DateTime.timestamp_nanos` exceeds the limit.
/// ///
/// ``` rust /// ``` rust
/// # use chrono::{DurationRound, Duration, RoundingError, TimeZone, Utc}; /// # use chrono::{DurationRound, TimeDelta, RoundingError, TimeZone, Utc};
/// let dt = Utc.with_ymd_and_hms(2300, 12, 12, 0, 0, 0).unwrap(); /// let dt = Utc.with_ymd_and_hms(2300, 12, 12, 0, 0, 0).unwrap();
/// ///
/// assert_eq!(dt.duration_round(Duration::days(1)), Err(RoundingError::TimestampExceedsLimit),); /// assert_eq!(dt.duration_round(TimeDelta::days(1)), Err(RoundingError::TimestampExceedsLimit),);
/// ``` /// ```
TimestampExceedsLimit, TimestampExceedsLimit,
} }
@ -302,7 +298,7 @@ impl std::error::Error for RoundingError {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{Duration, DurationRound, RoundingError, SubsecRound}; use super::{DurationRound, RoundingError, SubsecRound, TimeDelta};
use crate::offset::{FixedOffset, TimeZone, Utc}; use crate::offset::{FixedOffset, TimeZone, Utc};
use crate::Timelike; use crate::Timelike;
use crate::{NaiveDate, NaiveDateTime}; use crate::{NaiveDate, NaiveDateTime};
@ -447,12 +443,12 @@ mod tests {
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
dt.duration_round(Duration::zero()).unwrap().to_string(), dt.duration_round(TimeDelta::zero()).unwrap().to_string(),
"2016-12-31 23:59:59.175500 UTC" "2016-12-31 23:59:59.175500 UTC"
); );
assert_eq!( assert_eq!(
dt.duration_round(Duration::milliseconds(10)).unwrap().to_string(), dt.duration_round(TimeDelta::milliseconds(10)).unwrap().to_string(),
"2016-12-31 23:59:59.180 UTC" "2016-12-31 23:59:59.180 UTC"
); );
@ -466,7 +462,7 @@ mod tests {
) )
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
dt.duration_round(Duration::minutes(5)).unwrap().to_string(), dt.duration_round(TimeDelta::minutes(5)).unwrap().to_string(),
"2012-12-12 18:25:00 UTC" "2012-12-12 18:25:00 UTC"
); );
// round down // round down
@ -479,24 +475,24 @@ mod tests {
) )
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
dt.duration_round(Duration::minutes(5)).unwrap().to_string(), dt.duration_round(TimeDelta::minutes(5)).unwrap().to_string(),
"2012-12-12 18:20:00 UTC" "2012-12-12 18:20:00 UTC"
); );
assert_eq!( assert_eq!(
dt.duration_round(Duration::minutes(10)).unwrap().to_string(), dt.duration_round(TimeDelta::minutes(10)).unwrap().to_string(),
"2012-12-12 18:20:00 UTC" "2012-12-12 18:20:00 UTC"
); );
assert_eq!( assert_eq!(
dt.duration_round(Duration::minutes(30)).unwrap().to_string(), dt.duration_round(TimeDelta::minutes(30)).unwrap().to_string(),
"2012-12-12 18:30:00 UTC" "2012-12-12 18:30:00 UTC"
); );
assert_eq!( assert_eq!(
dt.duration_round(Duration::hours(1)).unwrap().to_string(), dt.duration_round(TimeDelta::hours(1)).unwrap().to_string(),
"2012-12-12 18:00:00 UTC" "2012-12-12 18:00:00 UTC"
); );
assert_eq!( assert_eq!(
dt.duration_round(Duration::days(1)).unwrap().to_string(), dt.duration_round(TimeDelta::days(1)).unwrap().to_string(),
"2012-12-13 00:00:00 UTC" "2012-12-13 00:00:00 UTC"
); );
@ -504,11 +500,11 @@ mod tests {
let dt = let dt =
FixedOffset::east_opt(3600).unwrap().with_ymd_and_hms(2020, 10, 27, 15, 0, 0).unwrap(); FixedOffset::east_opt(3600).unwrap().with_ymd_and_hms(2020, 10, 27, 15, 0, 0).unwrap();
assert_eq!( assert_eq!(
dt.duration_round(Duration::days(1)).unwrap().to_string(), dt.duration_round(TimeDelta::days(1)).unwrap().to_string(),
"2020-10-28 00:00:00 +01:00" "2020-10-28 00:00:00 +01:00"
); );
assert_eq!( assert_eq!(
dt.duration_round(Duration::weeks(1)).unwrap().to_string(), dt.duration_round(TimeDelta::weeks(1)).unwrap().to_string(),
"2020-10-29 00:00:00 +01:00" "2020-10-29 00:00:00 +01:00"
); );
@ -516,11 +512,11 @@ mod tests {
let dt = let dt =
FixedOffset::west_opt(3600).unwrap().with_ymd_and_hms(2020, 10, 27, 15, 0, 0).unwrap(); FixedOffset::west_opt(3600).unwrap().with_ymd_and_hms(2020, 10, 27, 15, 0, 0).unwrap();
assert_eq!( assert_eq!(
dt.duration_round(Duration::days(1)).unwrap().to_string(), dt.duration_round(TimeDelta::days(1)).unwrap().to_string(),
"2020-10-28 00:00:00 -01:00" "2020-10-28 00:00:00 -01:00"
); );
assert_eq!( assert_eq!(
dt.duration_round(Duration::weeks(1)).unwrap().to_string(), dt.duration_round(TimeDelta::weeks(1)).unwrap().to_string(),
"2020-10-29 00:00:00 -01:00" "2020-10-29 00:00:00 -01:00"
); );
} }
@ -538,12 +534,12 @@ mod tests {
.naive_utc(); .naive_utc();
assert_eq!( assert_eq!(
dt.duration_round(Duration::zero()).unwrap().to_string(), dt.duration_round(TimeDelta::zero()).unwrap().to_string(),
"2016-12-31 23:59:59.175500" "2016-12-31 23:59:59.175500"
); );
assert_eq!( assert_eq!(
dt.duration_round(Duration::milliseconds(10)).unwrap().to_string(), dt.duration_round(TimeDelta::milliseconds(10)).unwrap().to_string(),
"2016-12-31 23:59:59.180" "2016-12-31 23:59:59.180"
); );
@ -558,7 +554,7 @@ mod tests {
.unwrap() .unwrap()
.naive_utc(); .naive_utc();
assert_eq!( assert_eq!(
dt.duration_round(Duration::minutes(5)).unwrap().to_string(), dt.duration_round(TimeDelta::minutes(5)).unwrap().to_string(),
"2012-12-12 18:25:00" "2012-12-12 18:25:00"
); );
// round down // round down
@ -572,24 +568,24 @@ mod tests {
.unwrap() .unwrap()
.naive_utc(); .naive_utc();
assert_eq!( assert_eq!(
dt.duration_round(Duration::minutes(5)).unwrap().to_string(), dt.duration_round(TimeDelta::minutes(5)).unwrap().to_string(),
"2012-12-12 18:20:00" "2012-12-12 18:20:00"
); );
assert_eq!( assert_eq!(
dt.duration_round(Duration::minutes(10)).unwrap().to_string(), dt.duration_round(TimeDelta::minutes(10)).unwrap().to_string(),
"2012-12-12 18:20:00" "2012-12-12 18:20:00"
); );
assert_eq!( assert_eq!(
dt.duration_round(Duration::minutes(30)).unwrap().to_string(), dt.duration_round(TimeDelta::minutes(30)).unwrap().to_string(),
"2012-12-12 18:30:00" "2012-12-12 18:30:00"
); );
assert_eq!( assert_eq!(
dt.duration_round(Duration::hours(1)).unwrap().to_string(), dt.duration_round(TimeDelta::hours(1)).unwrap().to_string(),
"2012-12-12 18:00:00" "2012-12-12 18:00:00"
); );
assert_eq!( assert_eq!(
dt.duration_round(Duration::days(1)).unwrap().to_string(), dt.duration_round(TimeDelta::days(1)).unwrap().to_string(),
"2012-12-13 00:00:00" "2012-12-13 00:00:00"
); );
} }
@ -598,7 +594,7 @@ mod tests {
fn test_duration_round_pre_epoch() { fn test_duration_round_pre_epoch() {
let dt = Utc.with_ymd_and_hms(1969, 12, 12, 12, 12, 12).unwrap(); let dt = Utc.with_ymd_and_hms(1969, 12, 12, 12, 12, 12).unwrap();
assert_eq!( assert_eq!(
dt.duration_round(Duration::minutes(10)).unwrap().to_string(), dt.duration_round(TimeDelta::minutes(10)).unwrap().to_string(),
"1969-12-12 12:10:00 UTC" "1969-12-12 12:10:00 UTC"
); );
} }
@ -615,7 +611,7 @@ mod tests {
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
dt.duration_trunc(Duration::milliseconds(10)).unwrap().to_string(), dt.duration_trunc(TimeDelta::milliseconds(10)).unwrap().to_string(),
"2016-12-31 23:59:59.170 UTC" "2016-12-31 23:59:59.170 UTC"
); );
@ -629,7 +625,7 @@ mod tests {
) )
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
dt.duration_trunc(Duration::minutes(5)).unwrap().to_string(), dt.duration_trunc(TimeDelta::minutes(5)).unwrap().to_string(),
"2012-12-12 18:20:00 UTC" "2012-12-12 18:20:00 UTC"
); );
// would round down // would round down
@ -642,23 +638,23 @@ mod tests {
) )
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
dt.duration_trunc(Duration::minutes(5)).unwrap().to_string(), dt.duration_trunc(TimeDelta::minutes(5)).unwrap().to_string(),
"2012-12-12 18:20:00 UTC" "2012-12-12 18:20:00 UTC"
); );
assert_eq!( assert_eq!(
dt.duration_trunc(Duration::minutes(10)).unwrap().to_string(), dt.duration_trunc(TimeDelta::minutes(10)).unwrap().to_string(),
"2012-12-12 18:20:00 UTC" "2012-12-12 18:20:00 UTC"
); );
assert_eq!( assert_eq!(
dt.duration_trunc(Duration::minutes(30)).unwrap().to_string(), dt.duration_trunc(TimeDelta::minutes(30)).unwrap().to_string(),
"2012-12-12 18:00:00 UTC" "2012-12-12 18:00:00 UTC"
); );
assert_eq!( assert_eq!(
dt.duration_trunc(Duration::hours(1)).unwrap().to_string(), dt.duration_trunc(TimeDelta::hours(1)).unwrap().to_string(),
"2012-12-12 18:00:00 UTC" "2012-12-12 18:00:00 UTC"
); );
assert_eq!( assert_eq!(
dt.duration_trunc(Duration::days(1)).unwrap().to_string(), dt.duration_trunc(TimeDelta::days(1)).unwrap().to_string(),
"2012-12-12 00:00:00 UTC" "2012-12-12 00:00:00 UTC"
); );
@ -666,11 +662,11 @@ mod tests {
let dt = let dt =
FixedOffset::east_opt(3600).unwrap().with_ymd_and_hms(2020, 10, 27, 15, 0, 0).unwrap(); FixedOffset::east_opt(3600).unwrap().with_ymd_and_hms(2020, 10, 27, 15, 0, 0).unwrap();
assert_eq!( assert_eq!(
dt.duration_trunc(Duration::days(1)).unwrap().to_string(), dt.duration_trunc(TimeDelta::days(1)).unwrap().to_string(),
"2020-10-27 00:00:00 +01:00" "2020-10-27 00:00:00 +01:00"
); );
assert_eq!( assert_eq!(
dt.duration_trunc(Duration::weeks(1)).unwrap().to_string(), dt.duration_trunc(TimeDelta::weeks(1)).unwrap().to_string(),
"2020-10-22 00:00:00 +01:00" "2020-10-22 00:00:00 +01:00"
); );
@ -678,11 +674,11 @@ mod tests {
let dt = let dt =
FixedOffset::west_opt(3600).unwrap().with_ymd_and_hms(2020, 10, 27, 15, 0, 0).unwrap(); FixedOffset::west_opt(3600).unwrap().with_ymd_and_hms(2020, 10, 27, 15, 0, 0).unwrap();
assert_eq!( assert_eq!(
dt.duration_trunc(Duration::days(1)).unwrap().to_string(), dt.duration_trunc(TimeDelta::days(1)).unwrap().to_string(),
"2020-10-27 00:00:00 -01:00" "2020-10-27 00:00:00 -01:00"
); );
assert_eq!( assert_eq!(
dt.duration_trunc(Duration::weeks(1)).unwrap().to_string(), dt.duration_trunc(TimeDelta::weeks(1)).unwrap().to_string(),
"2020-10-22 00:00:00 -01:00" "2020-10-22 00:00:00 -01:00"
); );
} }
@ -700,7 +696,7 @@ mod tests {
.naive_utc(); .naive_utc();
assert_eq!( assert_eq!(
dt.duration_trunc(Duration::milliseconds(10)).unwrap().to_string(), dt.duration_trunc(TimeDelta::milliseconds(10)).unwrap().to_string(),
"2016-12-31 23:59:59.170" "2016-12-31 23:59:59.170"
); );
@ -715,7 +711,7 @@ mod tests {
.unwrap() .unwrap()
.naive_utc(); .naive_utc();
assert_eq!( assert_eq!(
dt.duration_trunc(Duration::minutes(5)).unwrap().to_string(), dt.duration_trunc(TimeDelta::minutes(5)).unwrap().to_string(),
"2012-12-12 18:20:00" "2012-12-12 18:20:00"
); );
// would round down // would round down
@ -729,23 +725,23 @@ mod tests {
.unwrap() .unwrap()
.naive_utc(); .naive_utc();
assert_eq!( assert_eq!(
dt.duration_trunc(Duration::minutes(5)).unwrap().to_string(), dt.duration_trunc(TimeDelta::minutes(5)).unwrap().to_string(),
"2012-12-12 18:20:00" "2012-12-12 18:20:00"
); );
assert_eq!( assert_eq!(
dt.duration_trunc(Duration::minutes(10)).unwrap().to_string(), dt.duration_trunc(TimeDelta::minutes(10)).unwrap().to_string(),
"2012-12-12 18:20:00" "2012-12-12 18:20:00"
); );
assert_eq!( assert_eq!(
dt.duration_trunc(Duration::minutes(30)).unwrap().to_string(), dt.duration_trunc(TimeDelta::minutes(30)).unwrap().to_string(),
"2012-12-12 18:00:00" "2012-12-12 18:00:00"
); );
assert_eq!( assert_eq!(
dt.duration_trunc(Duration::hours(1)).unwrap().to_string(), dt.duration_trunc(TimeDelta::hours(1)).unwrap().to_string(),
"2012-12-12 18:00:00" "2012-12-12 18:00:00"
); );
assert_eq!( assert_eq!(
dt.duration_trunc(Duration::days(1)).unwrap().to_string(), dt.duration_trunc(TimeDelta::days(1)).unwrap().to_string(),
"2012-12-12 00:00:00" "2012-12-12 00:00:00"
); );
} }
@ -754,7 +750,7 @@ mod tests {
fn test_duration_trunc_pre_epoch() { fn test_duration_trunc_pre_epoch() {
let dt = Utc.with_ymd_and_hms(1969, 12, 12, 12, 12, 12).unwrap(); let dt = Utc.with_ymd_and_hms(1969, 12, 12, 12, 12, 12).unwrap();
assert_eq!( assert_eq!(
dt.duration_trunc(Duration::minutes(10)).unwrap().to_string(), dt.duration_trunc(TimeDelta::minutes(10)).unwrap().to_string(),
"1969-12-12 12:10:00 UTC" "1969-12-12 12:10:00 UTC"
); );
} }
@ -762,15 +758,15 @@ mod tests {
#[test] #[test]
fn issue1010() { fn issue1010() {
let dt = NaiveDateTime::from_timestamp_opt(-4_227_854_320, 678_774_288).unwrap(); let dt = NaiveDateTime::from_timestamp_opt(-4_227_854_320, 678_774_288).unwrap();
let span = Duration::microseconds(-7_019_067_213_869_040); let span = TimeDelta::microseconds(-7_019_067_213_869_040);
assert_eq!(dt.duration_trunc(span), Err(RoundingError::DurationExceedsLimit)); assert_eq!(dt.duration_trunc(span), Err(RoundingError::DurationExceedsLimit));
let dt = NaiveDateTime::from_timestamp_opt(320_041_586, 920_103_021).unwrap(); let dt = NaiveDateTime::from_timestamp_opt(320_041_586, 920_103_021).unwrap();
let span = Duration::nanoseconds(-8_923_838_508_697_114_584); let span = TimeDelta::nanoseconds(-8_923_838_508_697_114_584);
assert_eq!(dt.duration_round(span), Err(RoundingError::DurationExceedsLimit)); assert_eq!(dt.duration_round(span), Err(RoundingError::DurationExceedsLimit));
let dt = NaiveDateTime::from_timestamp_opt(-2_621_440, 0).unwrap(); let dt = NaiveDateTime::from_timestamp_opt(-2_621_440, 0).unwrap();
let span = Duration::nanoseconds(-9_223_372_036_854_771_421); let span = TimeDelta::nanoseconds(-9_223_372_036_854_771_421);
assert_eq!(dt.duration_round(span), Err(RoundingError::DurationExceedsLimit)); assert_eq!(dt.duration_round(span), Err(RoundingError::DurationExceedsLimit));
} }
} }