diff --git a/src/naive/datetime/mod.rs b/src/naive/datetime/mod.rs index d13ff99889..659d4dd87d 100644 --- a/src/naive/datetime/mod.rs +++ b/src/naive/datetime/mod.rs @@ -5,7 +5,6 @@ #[cfg(any(feature = "alloc", feature = "std", test))] use core::borrow::Borrow; -use core::convert::TryFrom; use core::fmt::Write; use core::ops::{Add, AddAssign, Sub, SubAssign}; use core::{fmt, str}; @@ -22,7 +21,6 @@ use crate::format::{Fixed, Item, Numeric, Pad}; use crate::naive::{Days, IsoWeek, NaiveDate, NaiveTime}; use crate::oldtime::Duration as OldDuration; use crate::{DateTime, Datelike, LocalResult, Months, TimeZone, Timelike, Weekday}; -use core::cmp::Ordering; #[cfg(feature = "rustc-serialize")] pub(super) mod rustc_serialize; @@ -42,11 +40,6 @@ mod tests; /// touching that call when we are already sure that it WILL overflow... const MAX_SECS_BITS: usize = 44; -/// Number of nanoseconds in a millisecond -const NANOS_IN_MILLISECOND: u32 = 1_000_000; -/// Number of nanoseconds in a second -const NANOS_IN_SECOND: u32 = 1000 * NANOS_IN_MILLISECOND; - /// The minimum possible `NaiveDateTime`. #[deprecated(since = "0.4.20", note = "Use NaiveDateTime::MIN instead")] pub const MIN_DATETIME: NaiveDateTime = NaiveDateTime::MIN; @@ -87,32 +80,6 @@ pub struct NaiveDateTime { time: NaiveTime, } -/// The unit of a timestamp expressed in fractions of a second. -/// Currently either milliseconds or microseconds. -/// -/// This is a private type, used in the implementation of -/// [NaiveDateTime::from_timestamp_millis] and [NaiveDateTime::from_timestamp_micros]. -#[derive(Clone, Copy, Debug)] -enum TimestampUnit { - Millis, - Micros, -} - -impl TimestampUnit { - fn per_second(self) -> u32 { - match self { - TimestampUnit::Millis => 1_000, - TimestampUnit::Micros => 1_000_000, - } - } - fn nanos_per(self) -> u32 { - match self { - TimestampUnit::Millis => 1_000_000, - TimestampUnit::Micros => 1_000, - } - } -} - impl NaiveDateTime { /// Makes a new `NaiveDateTime` from date and time components. /// Equivalent to [`date.and_time(time)`](./struct.NaiveDate.html#method.and_time) @@ -180,7 +147,9 @@ impl NaiveDateTime { #[inline] #[must_use] pub fn from_timestamp_millis(millis: i64) -> Option { - Self::from_timestamp_unit(millis, TimestampUnit::Millis) + let secs = millis.div_euclid(1000); + let nsecs = millis.rem_euclid(1000) as u32 * 1_000_000; + NaiveDateTime::from_timestamp_opt(secs, nsecs) } /// Creates a new [NaiveDateTime] from microseconds since the UNIX epoch. @@ -207,7 +176,9 @@ impl NaiveDateTime { #[inline] #[must_use] pub fn from_timestamp_micros(micros: i64) -> Option { - Self::from_timestamp_unit(micros, TimestampUnit::Micros) + let secs = micros.div_euclid(1_000_000); + let nsecs = micros.rem_euclid(1_000_000) as u32 * 1000; + NaiveDateTime::from_timestamp_opt(secs, nsecs) } /// Makes a new `NaiveDateTime` corresponding to a UTC date and time, @@ -950,36 +921,6 @@ impl NaiveDateTime { pub const MIN: Self = Self { date: NaiveDate::MIN, time: NaiveTime::MIN }; /// The maximum possible `NaiveDateTime`. pub const MAX: Self = Self { date: NaiveDate::MAX, time: NaiveTime::MAX }; - - /// Creates a new [NaiveDateTime] from milliseconds or microseconds since the UNIX epoch. - /// - /// This is a private function used by [from_timestamp_millis] and [from_timestamp_micros]. - #[inline] - fn from_timestamp_unit(value: i64, unit: TimestampUnit) -> Option { - let (secs, subsecs) = - (value / i64::from(unit.per_second()), value % i64::from(unit.per_second())); - - match subsecs.cmp(&0) { - Ordering::Less => { - // in the case where our subsec part is negative, then we are actually in the earlier second - // hence we subtract one from the seconds part, and we then add a whole second worth of nanos - // to our nanos part. Due to the use of u32 datatype, it is more convenient to subtract - // the absolute value of the subsec nanos from a whole second worth of nanos - let nsecs = u32::try_from(subsecs.abs()).ok()? * unit.nanos_per(); - NaiveDateTime::from_timestamp_opt( - secs.checked_sub(1)?, - NANOS_IN_SECOND.checked_sub(nsecs)?, - ) - } - Ordering::Equal => NaiveDateTime::from_timestamp_opt(secs, 0), - Ordering::Greater => { - // convert the subsec millis into nanosecond scale so they can be supplied - // as the nanoseconds parameter - let nsecs = u32::try_from(subsecs).ok()? * unit.nanos_per(); - NaiveDateTime::from_timestamp_opt(secs, nsecs) - } - } - } } impl Datelike for NaiveDateTime {