summaryrefslogtreecommitdiffstats
path: root/vendor/chrono/src/round.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/chrono/src/round.rs')
-rw-r--r--vendor/chrono/src/round.rs41
1 files changed, 31 insertions, 10 deletions
diff --git a/vendor/chrono/src/round.rs b/vendor/chrono/src/round.rs
index b95f24570..f43ab595c 100644
--- a/vendor/chrono/src/round.rs
+++ b/vendor/chrono/src/round.rs
@@ -24,7 +24,7 @@ pub trait SubsecRound {
///
/// # Example
/// ``` rust
- /// # use chrono::{DateTime, SubsecRound, Timelike, TimeZone, Utc, NaiveDate};
+ /// # use chrono::{SubsecRound, Timelike, Utc, NaiveDate};
/// let dt = NaiveDate::from_ymd_opt(2018, 1, 11).unwrap().and_hms_milli_opt(12, 0, 0, 154).unwrap().and_local_timezone(Utc).unwrap();
/// assert_eq!(dt.round_subsecs(2).nanosecond(), 150_000_000);
/// assert_eq!(dt.round_subsecs(1).nanosecond(), 200_000_000);
@@ -36,7 +36,7 @@ pub trait SubsecRound {
///
/// # Example
/// ``` rust
- /// # use chrono::{DateTime, SubsecRound, Timelike, TimeZone, Utc, NaiveDate};
+ /// # use chrono::{SubsecRound, Timelike, Utc, NaiveDate};
/// let dt = NaiveDate::from_ymd_opt(2018, 1, 11).unwrap().and_hms_milli_opt(12, 0, 0, 154).unwrap().and_local_timezone(Utc).unwrap();
/// assert_eq!(dt.trunc_subsecs(2).nanosecond(), 150_000_000);
/// assert_eq!(dt.trunc_subsecs(1).nanosecond(), 100_000_000);
@@ -75,7 +75,7 @@ where
}
// Return the maximum span in nanoseconds for the target number of digits.
-fn span_for_digits(digits: u16) -> u32 {
+const fn span_for_digits(digits: u16) -> u32 {
// fast lookup form of: 10^(9-min(9,digits))
match digits {
0 => 1_000_000_000,
@@ -111,7 +111,7 @@ pub trait DurationRound: Sized {
///
/// # Example
/// ``` rust
- /// # use chrono::{DateTime, DurationRound, Duration, TimeZone, Utc, NaiveDate};
+ /// # use chrono::{DurationRound, Duration, Utc, NaiveDate};
/// let dt = NaiveDate::from_ymd_opt(2018, 1, 11).unwrap().and_hms_milli_opt(12, 0, 0, 154).unwrap().and_local_timezone(Utc).unwrap();
/// assert_eq!(
/// dt.duration_round(Duration::milliseconds(10)).unwrap().to_string(),
@@ -128,7 +128,7 @@ pub trait DurationRound: Sized {
///
/// # Example
/// ``` rust
- /// # use chrono::{DateTime, DurationRound, Duration, TimeZone, Utc, NaiveDate};
+ /// # use chrono::{DurationRound, Duration, Utc, NaiveDate};
/// let dt = NaiveDate::from_ymd_opt(2018, 1, 11).unwrap().and_hms_milli_opt(12, 0, 0, 154).unwrap().and_local_timezone(Utc).unwrap();
/// assert_eq!(
/// dt.duration_trunc(Duration::milliseconds(10)).unwrap().to_string(),
@@ -178,6 +178,9 @@ where
T: Timelike + Add<Duration, Output = T> + Sub<Duration, Output = T>,
{
if let Some(span) = duration.num_nanoseconds() {
+ if span < 0 {
+ return Err(RoundingError::DurationExceedsLimit);
+ }
if naive.timestamp().abs() > MAX_SECONDS_TIMESTAMP_FOR_NANOS {
return Err(RoundingError::TimestampExceedsLimit);
}
@@ -217,6 +220,9 @@ where
T: Timelike + Add<Duration, Output = T> + Sub<Duration, Output = T>,
{
if let Some(span) = duration.num_nanoseconds() {
+ if span < 0 {
+ return Err(RoundingError::DurationExceedsLimit);
+ }
if naive.timestamp().abs() > MAX_SECONDS_TIMESTAMP_FOR_NANOS {
return Err(RoundingError::TimestampExceedsLimit);
}
@@ -243,7 +249,7 @@ pub enum RoundingError {
/// Error when the Duration exceeds the Duration from or until the Unix epoch.
///
/// ``` rust
- /// # use chrono::{DateTime, DurationRound, Duration, RoundingError, TimeZone, Utc};
+ /// # use chrono::{DurationRound, Duration, RoundingError, TimeZone, Utc};
/// let dt = Utc.with_ymd_and_hms(1970, 12, 12, 0, 0, 0).unwrap();
///
/// assert_eq!(
@@ -256,7 +262,7 @@ pub enum RoundingError {
/// Error when `Duration.num_nanoseconds` exceeds the limit.
///
/// ``` rust
- /// # use chrono::{DateTime, DurationRound, Duration, RoundingError, TimeZone, Utc, NaiveDate};
+ /// # use chrono::{DurationRound, Duration, RoundingError, Utc, NaiveDate};
/// let dt = NaiveDate::from_ymd_opt(2260, 12, 31).unwrap().and_hms_nano_opt(23, 59, 59, 1_75_500_000).unwrap().and_local_timezone(Utc).unwrap();
///
/// assert_eq!(
@@ -269,7 +275,7 @@ pub enum RoundingError {
/// Error when `DateTime.timestamp_nanos` exceeds the limit.
///
/// ``` rust
- /// # use chrono::{DateTime, DurationRound, Duration, RoundingError, TimeZone, Utc};
+ /// # use chrono::{DurationRound, Duration, RoundingError, TimeZone, Utc};
/// let dt = Utc.with_ymd_and_hms(2300, 12, 12, 0, 0, 0).unwrap();
///
/// assert_eq!(dt.duration_round(Duration::days(1)), Err(RoundingError::TimestampExceedsLimit),);
@@ -304,10 +310,10 @@ impl std::error::Error for RoundingError {
#[cfg(test)]
mod tests {
- use super::{Duration, DurationRound, SubsecRound};
+ use super::{Duration, DurationRound, RoundingError, SubsecRound};
use crate::offset::{FixedOffset, TimeZone, Utc};
- use crate::NaiveDate;
use crate::Timelike;
+ use crate::{NaiveDate, NaiveDateTime};
#[test]
fn test_round_subsecs() {
@@ -760,4 +766,19 @@ mod tests {
"1969-12-12 12:10:00 UTC"
);
}
+
+ #[test]
+ fn issue1010() {
+ let dt = NaiveDateTime::from_timestamp_opt(-4227854320, 1678774288).unwrap();
+ let span = Duration::microseconds(-7019067213869040);
+ assert_eq!(dt.duration_trunc(span), Err(RoundingError::DurationExceedsLimit));
+
+ let dt = NaiveDateTime::from_timestamp_opt(320041586, 1920103021).unwrap();
+ let span = Duration::nanoseconds(-8923838508697114584);
+ assert_eq!(dt.duration_round(span), Err(RoundingError::DurationExceedsLimit));
+
+ let dt = NaiveDateTime::from_timestamp_opt(-2621440, 0).unwrap();
+ let span = Duration::nanoseconds(-9223372036854771421);
+ assert_eq!(dt.duration_round(span), Err(RoundingError::DurationExceedsLimit));
+ }
}