diff --git a/src/datetime.rs b/src/datetime.rs index 80bbb786..a8ce59bb 100644 --- a/src/datetime.rs +++ b/src/datetime.rs @@ -389,6 +389,22 @@ impl crate::DateTime { })?; Ok(Self::from_time_0_3(odt)) } + + /// Returns the time elapsed since `earlier`, or `None` if the given `DateTime` is later than + /// this one. + pub fn checked_duration_since(self, earlier: Self) -> Option { + if earlier.0 > self.0 { + return None; + } + Some(Duration::from_millis((self.0 - earlier.0) as u64)) + } + + /// Returns the time elapsed since `earlier`, or a [`Duration`] of zero if the given `DateTime` + /// is later than this one. + pub fn saturating_duration_since(self, earlier: Self) -> Duration { + self.checked_duration_since(earlier) + .unwrap_or(Duration::ZERO) + } } impl fmt::Debug for crate::DateTime { diff --git a/src/tests/datetime.rs b/src/tests/datetime.rs index 8f4719c3..56bba311 100644 --- a/src/tests/datetime.rs +++ b/src/tests/datetime.rs @@ -1,3 +1,5 @@ +use std::time::Duration; + use crate::tests::LOCK; #[test] @@ -38,3 +40,22 @@ fn datetime_to_rfc3339() { fn invalid_datetime_to_rfc3339() { assert!(crate::DateTime::MAX.try_to_rfc3339_string().is_err()); } + +#[test] +fn duration_since() { + let _guard = LOCK.run_concurrently(); + + let date1 = crate::DateTime::from_millis(100); + let date2 = crate::DateTime::from_millis(1000); + + assert_eq!( + date2.checked_duration_since(date1), + Some(Duration::from_millis(900)) + ); + assert_eq!( + date2.saturating_duration_since(date1), + Duration::from_millis(900) + ); + assert!(date1.checked_duration_since(date2).is_none()); + assert_eq!(date1.saturating_duration_since(date2), Duration::ZERO); +}