diff --git a/src/datetime/tests.rs b/src/datetime/tests.rs index 4adee3d2..f53b3c95 100644 --- a/src/datetime/tests.rs +++ b/src/datetime/tests.rs @@ -1103,7 +1103,7 @@ fn test_parse_from_str() { .is_err()); assert_eq!( DateTime::parse_from_str("0", "%s").unwrap(), - NaiveDateTime::from_timestamp_opt(0, 0).unwrap().and_utc().fixed_offset() + DateTime::from_timestamp(0, 0).unwrap().fixed_offset() ); assert_eq!( diff --git a/src/format/formatting.rs b/src/format/formatting.rs index 9b055289..f3448f94 100644 --- a/src/format/formatting.rs +++ b/src/format/formatting.rs @@ -231,10 +231,10 @@ fn format_inner( Timestamp => ( 1, match (date, time, off) { - (Some(d), Some(t), None) => Some(d.and_time(*t).timestamp()), - (Some(d), Some(t), Some(&(_, off))) => { - Some(d.and_time(*t).timestamp() - i64::from(off.local_minus_utc())) - } + (Some(d), Some(t), None) => Some(d.and_time(*t).and_utc().timestamp()), + (Some(d), Some(t), Some(&(_, off))) => Some( + d.and_time(*t).and_utc().timestamp() - i64::from(off.local_minus_utc()), + ), (_, _, _) => None, }, ), diff --git a/src/format/parsed.rs b/src/format/parsed.rs index 0f500512..be8db517 100644 --- a/src/format/parsed.rs +++ b/src/format/parsed.rs @@ -858,7 +858,7 @@ impl Parsed { // verify the timestamp field if any // the following is safe, `timestamp` is very limited in range - let timestamp = datetime.timestamp() - i64::from(offset); + let timestamp = datetime.and_utc().timestamp() - i64::from(offset); if let Some(given_timestamp) = self.timestamp { // if `datetime` represents a leap second, it might be off by one second. if given_timestamp != timestamp @@ -883,8 +883,7 @@ impl Parsed { // reconstruct date and time fields from timestamp let ts = timestamp.checked_add(i64::from(offset)).ok_or(OUT_OF_RANGE)?; - let datetime = NaiveDateTime::from_timestamp_opt(ts, 0); - let mut datetime = datetime.ok_or(OUT_OF_RANGE)?; + let mut datetime = DateTime::from_timestamp(ts, 0).ok_or(OUT_OF_RANGE)?.naive_utc(); // fill year, ordinal, hour, minute and second fields from timestamp. // if existing fields are consistent, this will allow the full date/time reconstruction. @@ -1000,8 +999,8 @@ impl Parsed { // make a naive `DateTime` from given timestamp and (if any) nanosecond. // an empty `nanosecond` is always equal to zero, so missing nanosecond is fine. let nanosecond = self.nanosecond.unwrap_or(0); - let dt = NaiveDateTime::from_timestamp_opt(timestamp, nanosecond); - let dt = dt.ok_or(OUT_OF_RANGE)?; + let dt = + DateTime::from_timestamp(timestamp, nanosecond).ok_or(OUT_OF_RANGE)?.naive_utc(); guessed_offset = tz.offset_from_utc_datetime(&dt).fix().local_minus_utc(); } diff --git a/src/offset/local/unix.rs b/src/offset/local/unix.rs index ce96a6e3..0b5bfefe 100644 --- a/src/offset/local/unix.rs +++ b/src/offset/local/unix.rs @@ -151,7 +151,7 @@ impl Cache { if !local { let offset = self .zone - .find_local_time_type(d.timestamp()) + .find_local_time_type(d.and_utc().timestamp()) .expect("unable to select local time type") .offset(); @@ -164,7 +164,7 @@ impl Cache { // we pass through the year as the year of a local point in time must either be valid in that locale, or // the entire time was skipped in which case we will return LocalResult::None anyway. self.zone - .find_local_time_type_from_local(d.timestamp(), d.year()) + .find_local_time_type_from_local(d.and_utc().timestamp(), d.year()) .expect("unable to select local time type") .map(|o| FixedOffset::east_opt(o.offset()).unwrap()) } diff --git a/src/offset/mod.rs b/src/offset/mod.rs index 26566ad0..005c6bdd 100644 --- a/src/offset/mod.rs +++ b/src/offset/mod.rs @@ -380,8 +380,8 @@ pub trait TimeZone: Sized + Clone { /// assert_eq!(Utc.timestamp_opt(1431648000, 0).unwrap().to_string(), "2015-05-15 00:00:00 UTC"); /// ``` fn timestamp_opt(&self, secs: i64, nsecs: u32) -> LocalResult> { - match NaiveDateTime::from_timestamp_opt(secs, nsecs) { - Some(dt) => LocalResult::Single(self.from_utc_datetime(&dt)), + match DateTime::from_timestamp(secs, nsecs) { + Some(dt) => LocalResult::Single(self.from_utc_datetime(&dt.naive_utc())), None => LocalResult::None, } } @@ -414,8 +414,8 @@ pub trait TimeZone: Sized + Clone { /// }; /// ``` fn timestamp_millis_opt(&self, millis: i64) -> LocalResult> { - match NaiveDateTime::from_timestamp_millis(millis) { - Some(dt) => LocalResult::Single(self.from_utc_datetime(&dt)), + match DateTime::from_timestamp_millis(millis) { + Some(dt) => LocalResult::Single(self.from_utc_datetime(&dt.naive_utc())), None => LocalResult::None, } } @@ -433,12 +433,7 @@ pub trait TimeZone: Sized + Clone { /// assert_eq!(Utc.timestamp_nanos(1431648000000000).timestamp(), 1431648); /// ``` fn timestamp_nanos(&self, nanos: i64) -> DateTime { - let (mut secs, mut nanos) = (nanos / 1_000_000_000, nanos % 1_000_000_000); - if nanos < 0 { - secs -= 1; - nanos += 1_000_000_000; - } - self.timestamp_opt(secs, nanos as u32).unwrap() + self.from_utc_datetime(&DateTime::from_timestamp_nanos(nanos).naive_utc()) } /// Makes a new `DateTime` from the number of non-leap microseconds @@ -452,8 +447,8 @@ pub trait TimeZone: Sized + Clone { /// assert_eq!(Utc.timestamp_micros(1431648000000).unwrap().timestamp(), 1431648); /// ``` fn timestamp_micros(&self, micros: i64) -> LocalResult> { - match NaiveDateTime::from_timestamp_micros(micros) { - Some(dt) => LocalResult::Single(self.from_utc_datetime(&dt)), + match DateTime::from_timestamp_micros(micros) { + Some(dt) => LocalResult::Single(self.from_utc_datetime(&dt.naive_utc())), None => LocalResult::None, } } diff --git a/src/offset/utc.rs b/src/offset/utc.rs index be88e37e..5bfbe69e 100644 --- a/src/offset/utc.rs +++ b/src/offset/utc.rs @@ -33,9 +33,9 @@ use crate::{Date, DateTime}; /// # Example /// /// ``` -/// use chrono::{NaiveDateTime, TimeZone, Utc}; +/// use chrono::{DateTime, TimeZone, Utc}; /// -/// let dt = Utc.from_utc_datetime(&NaiveDateTime::from_timestamp_opt(61, 0).unwrap()); +/// let dt = DateTime::from_timestamp(61, 0).unwrap(); /// /// assert_eq!(Utc.timestamp_opt(61, 0).unwrap(), dt); /// assert_eq!(Utc.with_ymd_and_hms(1970, 1, 1, 0, 1, 1).unwrap(), dt); @@ -95,9 +95,7 @@ impl Utc { pub fn now() -> DateTime { let now = SystemTime::now().duration_since(UNIX_EPOCH).expect("system time before Unix epoch"); - let naive = - NaiveDateTime::from_timestamp_opt(now.as_secs() as i64, now.subsec_nanos()).unwrap(); - Utc.from_utc_datetime(&naive) + DateTime::from_timestamp(now.as_secs() as i64, now.subsec_nanos()).unwrap() } /// Returns a `DateTime` which corresponds to the current date and time. diff --git a/src/round.rs b/src/round.rs index c70eea6a..ef3e39d2 100644 --- a/src/round.rs +++ b/src/round.rs @@ -196,7 +196,8 @@ where if span < 0 { return Err(RoundingError::DurationExceedsLimit); } - let stamp = naive.timestamp_nanos_opt().ok_or(RoundingError::TimestampExceedsLimit)?; + let stamp = + naive.and_utc().timestamp_nanos_opt().ok_or(RoundingError::TimestampExceedsLimit)?; if span == 0 { return Ok(original); } @@ -232,7 +233,8 @@ where if span < 0 { return Err(RoundingError::DurationExceedsLimit); } - let stamp = naive.timestamp_nanos_opt().ok_or(RoundingError::TimestampExceedsLimit)?; + let stamp = + naive.and_utc().timestamp_nanos_opt().ok_or(RoundingError::TimestampExceedsLimit)?; let delta_down = stamp % span; match delta_down.cmp(&0) { Ordering::Equal => Ok(original), @@ -312,7 +314,7 @@ mod tests { use super::{DurationRound, RoundingError, SubsecRound, TimeDelta}; use crate::offset::{FixedOffset, TimeZone, Utc}; use crate::Timelike; - use crate::{NaiveDate, NaiveDateTime}; + use crate::{DateTime, NaiveDate}; #[test] fn test_round_subsecs() { @@ -768,15 +770,15 @@ mod tests { #[test] fn issue1010() { - let dt = NaiveDateTime::from_timestamp_opt(-4_227_854_320, 678_774_288).unwrap(); + let dt = DateTime::from_timestamp(-4_227_854_320, 678_774_288).unwrap(); let span = TimeDelta::microseconds(-7_019_067_213_869_040); assert_eq!(dt.duration_trunc(span), Err(RoundingError::DurationExceedsLimit)); - let dt = NaiveDateTime::from_timestamp_opt(320_041_586, 920_103_021).unwrap(); + let dt = DateTime::from_timestamp(320_041_586, 920_103_021).unwrap(); let span = TimeDelta::nanoseconds(-8_923_838_508_697_114_584); assert_eq!(dt.duration_round(span), Err(RoundingError::DurationExceedsLimit)); - let dt = NaiveDateTime::from_timestamp_opt(-2_621_440, 0).unwrap(); + let dt = DateTime::from_timestamp(-2_621_440, 0).unwrap(); let span = TimeDelta::nanoseconds(-9_223_372_036_854_771_421); assert_eq!(dt.duration_round(span), Err(RoundingError::DurationExceedsLimit)); } @@ -807,16 +809,22 @@ mod tests { fn test_duration_round_close_to_min_max() { let span = TimeDelta::nanoseconds(i64::MAX); - let dt = NaiveDateTime::from_timestamp_nanos(i64::MIN / 2 - 1).unwrap(); - assert_eq!(dt.duration_round(span).unwrap().to_string(), "1677-09-21 00:12:43.145224193"); + let dt = DateTime::from_timestamp_nanos(i64::MIN / 2 - 1); + assert_eq!( + dt.duration_round(span).unwrap().to_string(), + "1677-09-21 00:12:43.145224193 UTC" + ); - let dt = NaiveDateTime::from_timestamp_nanos(i64::MIN / 2 + 1).unwrap(); - assert_eq!(dt.duration_round(span).unwrap().to_string(), "1970-01-01 00:00:00"); + let dt = DateTime::from_timestamp_nanos(i64::MIN / 2 + 1); + assert_eq!(dt.duration_round(span).unwrap().to_string(), "1970-01-01 00:00:00 UTC"); - let dt = NaiveDateTime::from_timestamp_nanos(i64::MAX / 2 + 1).unwrap(); - assert_eq!(dt.duration_round(span).unwrap().to_string(), "2262-04-11 23:47:16.854775807"); + let dt = DateTime::from_timestamp_nanos(i64::MAX / 2 + 1); + assert_eq!( + dt.duration_round(span).unwrap().to_string(), + "2262-04-11 23:47:16.854775807 UTC" + ); - let dt = NaiveDateTime::from_timestamp_nanos(i64::MAX / 2 - 1).unwrap(); - assert_eq!(dt.duration_round(span).unwrap().to_string(), "1970-01-01 00:00:00"); + let dt = DateTime::from_timestamp_nanos(i64::MAX / 2 - 1); + assert_eq!(dt.duration_round(span).unwrap().to_string(), "1970-01-01 00:00:00 UTC"); } }