mirror of
https://github.com/chronotope/chrono.git
synced 2025-10-02 07:21:41 +00:00
Don't use timestamp methods from NaiveDateTime
This commit is contained in:
parent
39f9a97b9b
commit
392e0dd460
@ -1103,7 +1103,7 @@ fn test_parse_from_str() {
|
|||||||
.is_err());
|
.is_err());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
DateTime::parse_from_str("0", "%s").unwrap(),
|
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!(
|
assert_eq!(
|
||||||
|
@ -231,10 +231,10 @@ fn format_inner(
|
|||||||
Timestamp => (
|
Timestamp => (
|
||||||
1,
|
1,
|
||||||
match (date, time, off) {
|
match (date, time, off) {
|
||||||
(Some(d), Some(t), None) => Some(d.and_time(*t).timestamp()),
|
(Some(d), Some(t), None) => Some(d.and_time(*t).and_utc().timestamp()),
|
||||||
(Some(d), Some(t), Some(&(_, off))) => {
|
(Some(d), Some(t), Some(&(_, off))) => Some(
|
||||||
Some(d.and_time(*t).timestamp() - i64::from(off.local_minus_utc()))
|
d.and_time(*t).and_utc().timestamp() - i64::from(off.local_minus_utc()),
|
||||||
}
|
),
|
||||||
(_, _, _) => None,
|
(_, _, _) => None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -858,7 +858,7 @@ impl Parsed {
|
|||||||
|
|
||||||
// verify the timestamp field if any
|
// verify the timestamp field if any
|
||||||
// the following is safe, `timestamp` is very limited in range
|
// 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 let Some(given_timestamp) = self.timestamp {
|
||||||
// if `datetime` represents a leap second, it might be off by one second.
|
// if `datetime` represents a leap second, it might be off by one second.
|
||||||
if given_timestamp != timestamp
|
if given_timestamp != timestamp
|
||||||
@ -883,8 +883,7 @@ impl Parsed {
|
|||||||
|
|
||||||
// reconstruct date and time fields from timestamp
|
// reconstruct date and time fields from timestamp
|
||||||
let ts = timestamp.checked_add(i64::from(offset)).ok_or(OUT_OF_RANGE)?;
|
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::from_timestamp(ts, 0).ok_or(OUT_OF_RANGE)?.naive_utc();
|
||||||
let mut datetime = datetime.ok_or(OUT_OF_RANGE)?;
|
|
||||||
|
|
||||||
// fill year, ordinal, hour, minute and second fields from timestamp.
|
// fill year, ordinal, hour, minute and second fields from timestamp.
|
||||||
// if existing fields are consistent, this will allow the full date/time reconstruction.
|
// 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.
|
// make a naive `DateTime` from given timestamp and (if any) nanosecond.
|
||||||
// an empty `nanosecond` is always equal to zero, so missing nanosecond is fine.
|
// an empty `nanosecond` is always equal to zero, so missing nanosecond is fine.
|
||||||
let nanosecond = self.nanosecond.unwrap_or(0);
|
let nanosecond = self.nanosecond.unwrap_or(0);
|
||||||
let dt = NaiveDateTime::from_timestamp_opt(timestamp, nanosecond);
|
let dt =
|
||||||
let dt = dt.ok_or(OUT_OF_RANGE)?;
|
DateTime::from_timestamp(timestamp, nanosecond).ok_or(OUT_OF_RANGE)?.naive_utc();
|
||||||
guessed_offset = tz.offset_from_utc_datetime(&dt).fix().local_minus_utc();
|
guessed_offset = tz.offset_from_utc_datetime(&dt).fix().local_minus_utc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ impl Cache {
|
|||||||
if !local {
|
if !local {
|
||||||
let offset = self
|
let offset = self
|
||||||
.zone
|
.zone
|
||||||
.find_local_time_type(d.timestamp())
|
.find_local_time_type(d.and_utc().timestamp())
|
||||||
.expect("unable to select local time type")
|
.expect("unable to select local time type")
|
||||||
.offset();
|
.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
|
// 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.
|
// the entire time was skipped in which case we will return LocalResult::None anyway.
|
||||||
self.zone
|
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")
|
.expect("unable to select local time type")
|
||||||
.map(|o| FixedOffset::east_opt(o.offset()).unwrap())
|
.map(|o| FixedOffset::east_opt(o.offset()).unwrap())
|
||||||
}
|
}
|
||||||
|
@ -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");
|
/// 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<DateTime<Self>> {
|
fn timestamp_opt(&self, secs: i64, nsecs: u32) -> LocalResult<DateTime<Self>> {
|
||||||
match NaiveDateTime::from_timestamp_opt(secs, nsecs) {
|
match DateTime::from_timestamp(secs, nsecs) {
|
||||||
Some(dt) => LocalResult::Single(self.from_utc_datetime(&dt)),
|
Some(dt) => LocalResult::Single(self.from_utc_datetime(&dt.naive_utc())),
|
||||||
None => LocalResult::None,
|
None => LocalResult::None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -414,8 +414,8 @@ pub trait TimeZone: Sized + Clone {
|
|||||||
/// };
|
/// };
|
||||||
/// ```
|
/// ```
|
||||||
fn timestamp_millis_opt(&self, millis: i64) -> LocalResult<DateTime<Self>> {
|
fn timestamp_millis_opt(&self, millis: i64) -> LocalResult<DateTime<Self>> {
|
||||||
match NaiveDateTime::from_timestamp_millis(millis) {
|
match DateTime::from_timestamp_millis(millis) {
|
||||||
Some(dt) => LocalResult::Single(self.from_utc_datetime(&dt)),
|
Some(dt) => LocalResult::Single(self.from_utc_datetime(&dt.naive_utc())),
|
||||||
None => LocalResult::None,
|
None => LocalResult::None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -433,12 +433,7 @@ pub trait TimeZone: Sized + Clone {
|
|||||||
/// assert_eq!(Utc.timestamp_nanos(1431648000000000).timestamp(), 1431648);
|
/// assert_eq!(Utc.timestamp_nanos(1431648000000000).timestamp(), 1431648);
|
||||||
/// ```
|
/// ```
|
||||||
fn timestamp_nanos(&self, nanos: i64) -> DateTime<Self> {
|
fn timestamp_nanos(&self, nanos: i64) -> DateTime<Self> {
|
||||||
let (mut secs, mut nanos) = (nanos / 1_000_000_000, nanos % 1_000_000_000);
|
self.from_utc_datetime(&DateTime::from_timestamp_nanos(nanos).naive_utc())
|
||||||
if nanos < 0 {
|
|
||||||
secs -= 1;
|
|
||||||
nanos += 1_000_000_000;
|
|
||||||
}
|
|
||||||
self.timestamp_opt(secs, nanos as u32).unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Makes a new `DateTime` from the number of non-leap microseconds
|
/// 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);
|
/// assert_eq!(Utc.timestamp_micros(1431648000000).unwrap().timestamp(), 1431648);
|
||||||
/// ```
|
/// ```
|
||||||
fn timestamp_micros(&self, micros: i64) -> LocalResult<DateTime<Self>> {
|
fn timestamp_micros(&self, micros: i64) -> LocalResult<DateTime<Self>> {
|
||||||
match NaiveDateTime::from_timestamp_micros(micros) {
|
match DateTime::from_timestamp_micros(micros) {
|
||||||
Some(dt) => LocalResult::Single(self.from_utc_datetime(&dt)),
|
Some(dt) => LocalResult::Single(self.from_utc_datetime(&dt.naive_utc())),
|
||||||
None => LocalResult::None,
|
None => LocalResult::None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,9 +33,9 @@ use crate::{Date, DateTime};
|
|||||||
/// # Example
|
/// # 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.timestamp_opt(61, 0).unwrap(), dt);
|
||||||
/// assert_eq!(Utc.with_ymd_and_hms(1970, 1, 1, 0, 1, 1).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<Utc> {
|
pub fn now() -> DateTime<Utc> {
|
||||||
let now =
|
let now =
|
||||||
SystemTime::now().duration_since(UNIX_EPOCH).expect("system time before Unix epoch");
|
SystemTime::now().duration_since(UNIX_EPOCH).expect("system time before Unix epoch");
|
||||||
let naive =
|
DateTime::from_timestamp(now.as_secs() as i64, now.subsec_nanos()).unwrap()
|
||||||
NaiveDateTime::from_timestamp_opt(now.as_secs() as i64, now.subsec_nanos()).unwrap();
|
|
||||||
Utc.from_utc_datetime(&naive)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a `DateTime` which corresponds to the current date and time.
|
/// Returns a `DateTime` which corresponds to the current date and time.
|
||||||
|
36
src/round.rs
36
src/round.rs
@ -196,7 +196,8 @@ where
|
|||||||
if span < 0 {
|
if span < 0 {
|
||||||
return Err(RoundingError::DurationExceedsLimit);
|
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 {
|
if span == 0 {
|
||||||
return Ok(original);
|
return Ok(original);
|
||||||
}
|
}
|
||||||
@ -232,7 +233,8 @@ where
|
|||||||
if span < 0 {
|
if span < 0 {
|
||||||
return Err(RoundingError::DurationExceedsLimit);
|
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;
|
let delta_down = stamp % span;
|
||||||
match delta_down.cmp(&0) {
|
match delta_down.cmp(&0) {
|
||||||
Ordering::Equal => Ok(original),
|
Ordering::Equal => Ok(original),
|
||||||
@ -312,7 +314,7 @@ mod tests {
|
|||||||
use super::{DurationRound, RoundingError, SubsecRound, TimeDelta};
|
use super::{DurationRound, RoundingError, SubsecRound, TimeDelta};
|
||||||
use crate::offset::{FixedOffset, TimeZone, Utc};
|
use crate::offset::{FixedOffset, TimeZone, Utc};
|
||||||
use crate::Timelike;
|
use crate::Timelike;
|
||||||
use crate::{NaiveDate, NaiveDateTime};
|
use crate::{DateTime, NaiveDate};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_round_subsecs() {
|
fn test_round_subsecs() {
|
||||||
@ -768,15 +770,15 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn issue1010() {
|
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);
|
let span = TimeDelta::microseconds(-7_019_067_213_869_040);
|
||||||
assert_eq!(dt.duration_trunc(span), Err(RoundingError::DurationExceedsLimit));
|
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);
|
let span = TimeDelta::nanoseconds(-8_923_838_508_697_114_584);
|
||||||
assert_eq!(dt.duration_round(span), Err(RoundingError::DurationExceedsLimit));
|
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);
|
let span = TimeDelta::nanoseconds(-9_223_372_036_854_771_421);
|
||||||
assert_eq!(dt.duration_round(span), Err(RoundingError::DurationExceedsLimit));
|
assert_eq!(dt.duration_round(span), Err(RoundingError::DurationExceedsLimit));
|
||||||
}
|
}
|
||||||
@ -807,16 +809,22 @@ mod tests {
|
|||||||
fn test_duration_round_close_to_min_max() {
|
fn test_duration_round_close_to_min_max() {
|
||||||
let span = TimeDelta::nanoseconds(i64::MAX);
|
let span = TimeDelta::nanoseconds(i64::MAX);
|
||||||
|
|
||||||
let dt = NaiveDateTime::from_timestamp_nanos(i64::MIN / 2 - 1).unwrap();
|
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");
|
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();
|
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");
|
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();
|
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");
|
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();
|
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");
|
assert_eq!(dt.duration_round(span).unwrap().to_string(), "1970-01-01 00:00:00 UTC");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user