Skip to content

Commit

Permalink
Convert DateTime::from_timestamp_micros to return Result
Browse files Browse the repository at this point in the history
  • Loading branch information
pitdicker committed Mar 8, 2024
1 parent 9da1b4c commit 6c68842
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 16 deletions.
22 changes: 10 additions & 12 deletions src/datetime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use crate::offset::Local;
use crate::offset::{FixedOffset, Offset, TimeZone, Utc};
#[cfg(any(feature = "clock", feature = "std"))]
use crate::OutOfRange;
use crate::{ok, try_err, try_ok_or};
use crate::{try_err, try_ok_or};
use crate::{Datelike, Error, Months, TimeDelta, Timelike, Weekday};

#[cfg(any(feature = "rkyv", feature = "rkyv-16", feature = "rkyv-32", feature = "rkyv-64"))]
Expand Down Expand Up @@ -823,31 +823,29 @@ impl DateTime<Utc> {
///
/// # Errors
///
/// Returns `None` if the number of microseconds would be out of range for a `NaiveDateTime`
/// (more than ca. 262,000 years away from common era)
/// Returns [`Error::OutOfRange`] if the timestamp in microseconds is outside the range of a
/// `DateTime` (more than ca. 262,000 years away from common era).
///
/// # Example
///
/// ```
/// use chrono::DateTime;
///
/// let timestamp_micros: i64 = 1662921288000000; // Sun, 11 Sep 2022 18:34:48 UTC
/// let dt = DateTime::from_timestamp_micros(timestamp_micros);
/// assert!(dt.is_some());
/// assert_eq!(timestamp_micros, dt.expect("invalid timestamp").timestamp_micros());
/// let dt = DateTime::from_timestamp_micros(timestamp_micros)?;
/// assert_eq!(timestamp_micros, dt.timestamp_micros());
///
/// // Negative timestamps (before the UNIX epoch) are supported as well.
/// let timestamp_micros: i64 = -2208936075000000; // Mon, 1 Jan 1900 14:38:45 UTC
/// let dt = DateTime::from_timestamp_micros(timestamp_micros);
/// assert!(dt.is_some());
/// assert_eq!(timestamp_micros, dt.expect("invalid timestamp").timestamp_micros());
/// let dt = DateTime::from_timestamp_micros(timestamp_micros)?;
/// assert_eq!(timestamp_micros, dt.timestamp_micros());
/// # Ok::<(), chrono::Error>(())
/// ```
#[inline]
#[must_use]
pub const fn from_timestamp_micros(micros: i64) -> Option<Self> {
pub const fn from_timestamp_micros(micros: i64) -> Result<Self, Error> {
let secs = micros.div_euclid(1_000_000);
let nsecs = micros.rem_euclid(1_000_000) as u32 * 1000;
ok!(Self::from_timestamp(secs, nsecs))
Self::from_timestamp(secs, nsecs)
}

/// Creates a new [`DateTime<Utc>`] from the number of non-leap microseconds
Expand Down
4 changes: 2 additions & 2 deletions src/datetime/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ fn test_datetime_from_timestamp_micros() {

for timestamp_micros in invalid.iter().copied() {
let datetime = DateTime::from_timestamp_micros(timestamp_micros);
assert!(datetime.is_none());
assert_eq!(datetime, Err(Error::OutOfRange));
}

// Test that the result of `TimeZone::timestamp_micros` compares equal to
Expand All @@ -185,7 +185,7 @@ fn test_datetime_from_timestamp_micros() {
for secs in secs_test.iter().copied() {
assert_eq!(
DateTime::from_timestamp_micros(secs * 1_000_000),
DateTime::from_timestamp(secs, 0).ok()
DateTime::from_timestamp(secs, 0)
);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/offset/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ pub trait TimeZone: Sized + Clone {
/// ```
fn timestamp_micros(&self, micros: i64) -> LocalResult<DateTime<Self>> {
match DateTime::from_timestamp_micros(micros) {
Some(dt) => LocalResult::Single(self.from_utc_datetime(&dt.naive_utc())),
None => LocalResult::None,
Ok(dt) => LocalResult::Single(self.from_utc_datetime(&dt.naive_utc())),
Err(_) => LocalResult::None,
}
}

Expand Down

0 comments on commit 6c68842

Please sign in to comment.