From fce3fd9e868bbd7939d62cfd87e23b9eac713f7c Mon Sep 17 00:00:00 2001 From: xmakro Date: Tue, 9 Jan 2024 21:55:24 +0800 Subject: [PATCH 1/2] Add from_timestamp_micros/millis to DateTime --- src/datetime/mod.rs | 56 +++++++++++++++++++++++++++++++++++++++++++ src/datetime/tests.rs | 24 +++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/src/datetime/mod.rs b/src/datetime/mod.rs index ac9ef511d0..f99f957476 100644 --- a/src/datetime/mod.rs +++ b/src/datetime/mod.rs @@ -624,6 +624,62 @@ impl DateTime { NaiveDateTime::from_timestamp_opt(secs, nsecs).as_ref().map(NaiveDateTime::and_utc) } + /// Makes a new [`DateTime`] from the number of non-leap microseconds + /// since January 1, 1970 0:00:00.000000 UTC (aka "UNIX timestamp"). + /// + /// This is guaranteed to round-trip with regard to [`timestamp_micros`](DateTime::timestamp_micros). + /// + /// If you need to create a `DateTime` with a [`TimeZone`] different from [`Utc`], use + /// [`TimeZone::timestamp_micros`] or [`DateTime::with_timezone`]. + /// + /// # Errors + /// + /// Returns `None` on out-of-range number of microseconds, otherwise returns `Some(DateTime {...})`. + /// + /// # Example + /// + /// ``` + /// use chrono::{DateTime, Utc}; + /// + /// let dt: DateTime = DateTime::::from_timestamp_micros(947638923000004).expect("invalid timestamp"); + /// + /// assert_eq!(dt.to_string(), "2000-01-12 01:02:03.000004 UTC"); + /// assert_eq!(DateTime::from_timestamp_micros(dt.timestamp_micros()).unwrap(), dt); + /// ``` + #[inline] + #[must_use] + pub fn from_timestamp_micros(micros: i64) -> Option { + NaiveDateTime::from_timestamp_micros(micros).as_ref().map(NaiveDateTime::and_utc) + } + + /// Makes a new [`DateTime`] from the number of non-leap milliseconds + /// since January 1, 1970 0:00:00.000 UTC (aka "UNIX timestamp"). + /// + /// This is guaranteed to round-trip with regard to [`timestamp_millis`](DateTime::timestamp_millis). + /// + /// If you need to create a `DateTime` with a [`TimeZone`] different from [`Utc`], use + /// [`TimeZone::timestamp_millis_opt`] or [`DateTime::with_timezone`]. + /// + /// # Errors + /// + /// Returns `None` on out-of-range number of milliseconds, otherwise returns `Some(DateTime {...})`. + /// + /// # Example + /// + /// ``` + /// use chrono::{DateTime, Utc}; + /// + /// let dt: DateTime = DateTime::::from_timestamp_millis(947638923004).expect("invalid timestamp"); + /// + /// assert_eq!(dt.to_string(), "2000-01-12 01:02:03.004 UTC"); + /// assert_eq!(DateTime::from_timestamp_millis(dt.timestamp_millis()).unwrap(), dt); + /// ``` + #[inline] + #[must_use] + pub fn from_timestamp_millis(millis: i64) -> Option { + NaiveDateTime::from_timestamp_millis(millis).as_ref().map(NaiveDateTime::and_utc) + } + // FIXME: remove when our MSRV is 1.61+ // This method is used by `NaiveDateTime::and_utc` because `DateTime::from_naive_utc_and_offset` // can't be made const yet. diff --git a/src/datetime/tests.rs b/src/datetime/tests.rs index 3df11e78d4..4b1a8a9035 100644 --- a/src/datetime/tests.rs +++ b/src/datetime/tests.rs @@ -1253,6 +1253,30 @@ fn test_datetime_from_local() { assert_eq!(datetime_west, datetime_utc.with_timezone(&timezone_west)); } +#[test] +fn test_datetime_from_timestamp_micros() { + // 2000-01-12 01:02:03.000004Z + let naive_dt = + NaiveDate::from_ymd_opt(2000, 1, 12).unwrap().and_hms_micro_opt(1, 2, 3, 4).unwrap(); + let datetime_utc = DateTime::::from_naive_utc_and_offset(naive_dt, Utc); + assert_eq!( + datetime_utc, + DateTime::::from_timestamp_micros(datetime_utc.timestamp_micros()).unwrap() + ); +} + +#[test] +fn test_datetime_from_timestamp_millis() { + // 2000-01-12T01:02:03:004Z + let naive_dt = + NaiveDate::from_ymd_opt(2000, 1, 12).unwrap().and_hms_milli_opt(1, 2, 3, 4).unwrap(); + let datetime_utc = DateTime::::from_naive_utc_and_offset(naive_dt, Utc); + assert_eq!( + datetime_utc, + DateTime::::from_timestamp_millis(datetime_utc.timestamp_millis()).unwrap() + ); +} + #[test] #[cfg(feature = "clock")] fn test_years_elapsed() { From d840420e997a4deb256526a3c24071032e41c52c Mon Sep 17 00:00:00 2001 From: xmakro Date: Tue, 9 Jan 2024 23:10:15 +0800 Subject: [PATCH 2/2] Revert timestamp_from_micros --- src/datetime/mod.rs | 28 ---------------------------- src/datetime/tests.rs | 12 ------------ 2 files changed, 40 deletions(-) diff --git a/src/datetime/mod.rs b/src/datetime/mod.rs index f99f957476..9d4e1c3861 100644 --- a/src/datetime/mod.rs +++ b/src/datetime/mod.rs @@ -624,34 +624,6 @@ impl DateTime { NaiveDateTime::from_timestamp_opt(secs, nsecs).as_ref().map(NaiveDateTime::and_utc) } - /// Makes a new [`DateTime`] from the number of non-leap microseconds - /// since January 1, 1970 0:00:00.000000 UTC (aka "UNIX timestamp"). - /// - /// This is guaranteed to round-trip with regard to [`timestamp_micros`](DateTime::timestamp_micros). - /// - /// If you need to create a `DateTime` with a [`TimeZone`] different from [`Utc`], use - /// [`TimeZone::timestamp_micros`] or [`DateTime::with_timezone`]. - /// - /// # Errors - /// - /// Returns `None` on out-of-range number of microseconds, otherwise returns `Some(DateTime {...})`. - /// - /// # Example - /// - /// ``` - /// use chrono::{DateTime, Utc}; - /// - /// let dt: DateTime = DateTime::::from_timestamp_micros(947638923000004).expect("invalid timestamp"); - /// - /// assert_eq!(dt.to_string(), "2000-01-12 01:02:03.000004 UTC"); - /// assert_eq!(DateTime::from_timestamp_micros(dt.timestamp_micros()).unwrap(), dt); - /// ``` - #[inline] - #[must_use] - pub fn from_timestamp_micros(micros: i64) -> Option { - NaiveDateTime::from_timestamp_micros(micros).as_ref().map(NaiveDateTime::and_utc) - } - /// Makes a new [`DateTime`] from the number of non-leap milliseconds /// since January 1, 1970 0:00:00.000 UTC (aka "UNIX timestamp"). /// diff --git a/src/datetime/tests.rs b/src/datetime/tests.rs index 4b1a8a9035..3e96e227fa 100644 --- a/src/datetime/tests.rs +++ b/src/datetime/tests.rs @@ -1253,18 +1253,6 @@ fn test_datetime_from_local() { assert_eq!(datetime_west, datetime_utc.with_timezone(&timezone_west)); } -#[test] -fn test_datetime_from_timestamp_micros() { - // 2000-01-12 01:02:03.000004Z - let naive_dt = - NaiveDate::from_ymd_opt(2000, 1, 12).unwrap().and_hms_micro_opt(1, 2, 3, 4).unwrap(); - let datetime_utc = DateTime::::from_naive_utc_and_offset(naive_dt, Utc); - assert_eq!( - datetime_utc, - DateTime::::from_timestamp_micros(datetime_utc.timestamp_micros()).unwrap() - ); -} - #[test] fn test_datetime_from_timestamp_millis() { // 2000-01-12T01:02:03:004Z