Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document panics in Add/Sub impls and use expect #1316

Merged
merged 7 commits into from
Sep 26, 2023
154 changes: 148 additions & 6 deletions src/datetime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1208,6 +1208,16 @@ impl<Tz: TimeZone> hash::Hash for DateTime<Tz> {
}
}

/// Add `chrono::Duration` to `DateTime`.
///
/// As a part of Chrono's [leap second handling], the addition assumes that **there is no leap
/// second ever**, except when the `NaiveDateTime` itself represents a leap second in which case
/// the assumption becomes that **there is exactly a single leap second ever**.
///
/// # Panics
///
/// Panics if the resulting date would be out of range.
/// Consider using [`DateTime<Tz>::checked_add_signed`] to get an `Option` instead.
impl<Tz: TimeZone> Add<OldDuration> for DateTime<Tz> {
type Output = DateTime<Tz>;

Expand All @@ -1217,6 +1227,16 @@ impl<Tz: TimeZone> Add<OldDuration> for DateTime<Tz> {
}
}

/// Add `std::time::Duration` to `DateTime`.
///
/// As a part of Chrono's [leap second handling], the addition assumes that **there is no leap
/// second ever**, except when the `NaiveDateTime` itself represents a leap second in which case
/// the assumption becomes that **there is exactly a single leap second ever**.
///
/// # Panics
///
/// Panics if the resulting date would be out of range.
/// Consider using [`DateTime<Tz>::checked_add_signed`] to get an `Option` instead.
impl<Tz: TimeZone> Add<Duration> for DateTime<Tz> {
type Output = DateTime<Tz>;

Expand All @@ -1228,6 +1248,16 @@ impl<Tz: TimeZone> Add<Duration> for DateTime<Tz> {
}
}

/// Add-assign `chrono::Duration` to `DateTime`.
///
/// As a part of Chrono's [leap second handling], the addition assumes that **there is no leap
/// second ever**, except when the `NaiveDateTime` itself represents a leap second in which case
/// the assumption becomes that **there is exactly a single leap second ever**.
///
/// # Panics
///
/// Panics if the resulting date would be out of range.
/// Consider using [`DateTime<Tz>::checked_add_signed`] to get an `Option` instead.
impl<Tz: TimeZone> AddAssign<OldDuration> for DateTime<Tz> {
#[inline]
fn add_assign(&mut self, rhs: OldDuration) {
Expand All @@ -1238,6 +1268,16 @@ impl<Tz: TimeZone> AddAssign<OldDuration> for DateTime<Tz> {
}
}

/// Add-assign `std::time::Duration` to `DateTime`.
///
/// As a part of Chrono's [leap second handling], the addition assumes that **there is no leap
/// second ever**, except when the `NaiveDateTime` itself represents a leap second in which case
/// the assumption becomes that **there is exactly a single leap second ever**.
///
/// # Panics
///
/// Panics if the resulting date would be out of range.
/// Consider using [`DateTime<Tz>::checked_add_signed`] to get an `Option` instead.
impl<Tz: TimeZone> AddAssign<Duration> for DateTime<Tz> {
#[inline]
fn add_assign(&mut self, rhs: Duration) {
Expand All @@ -1247,24 +1287,55 @@ impl<Tz: TimeZone> AddAssign<Duration> for DateTime<Tz> {
}
}

/// Add `FixedOffset` to the datetime value of `DateTime` (offset remains unchanged).
///
/// # Panics
///
/// Panics if the resulting date would be out of range.
impl<Tz: TimeZone> Add<FixedOffset> for DateTime<Tz> {
type Output = DateTime<Tz>;

#[inline]
fn add(mut self, rhs: FixedOffset) -> DateTime<Tz> {
self.datetime = self.naive_utc().checked_add_offset(rhs).unwrap();
self.datetime =
self.naive_utc().checked_add_offset(rhs).expect("`DateTime + FixedOffset` overflowed");
self
}
}

/// Add `Months` to `DateTime`.
///
/// The result will be clamped to valid days in the resulting month, see `checked_add_months` for
/// details.
///
/// # Panics
///
/// Panics if:
/// - The resulting date would be out of range.
/// - The local time at the resulting date does not exist or is ambiguous, for example during a
/// daylight saving time transition.
///
/// Strongly consider using [`DateTime<Tz>::checked_add_months`] to get an `Option` instead.
impl<Tz: TimeZone> Add<Months> for DateTime<Tz> {
type Output = DateTime<Tz>;

fn add(self, rhs: Months) -> Self::Output {
self.checked_add_months(rhs).unwrap()
self.checked_add_months(rhs).expect("`DateTime + Months` out of range")
}
}

/// Subtract `chrono::Duration` from `DateTime`.
///
/// This is the same as the addition with a negated `Duration`.
///
/// As a part of Chrono's [leap second handling] the subtraction assumes that **there is no leap
/// second ever**, except when the `DateTime` itself represents a leap second in which case
/// the assumption becomes that **there is exactly a single leap second ever**.
///
/// # Panics
///
/// Panics if the resulting date would be out of range.
/// Consider using [`DateTime<Tz>::checked_sub_signed`] to get an `Option` instead.
impl<Tz: TimeZone> Sub<OldDuration> for DateTime<Tz> {
type Output = DateTime<Tz>;

Expand All @@ -1274,6 +1345,16 @@ impl<Tz: TimeZone> Sub<OldDuration> for DateTime<Tz> {
}
}

/// Subtract `std::time::Duration` from `DateTime`.
///
/// As a part of Chrono's [leap second handling] the subtraction assumes that **there is no leap
/// second ever**, except when the `DateTime` itself represents a leap second in which case
/// the assumption becomes that **there is exactly a single leap second ever**.
///
/// # Panics
///
/// Panics if the resulting date would be out of range.
/// Consider using [`DateTime<Tz>::checked_sub_signed`] to get an `Option` instead.
impl<Tz: TimeZone> Sub<Duration> for DateTime<Tz> {
type Output = DateTime<Tz>;

Expand All @@ -1285,6 +1366,18 @@ impl<Tz: TimeZone> Sub<Duration> for DateTime<Tz> {
}
}

/// Subtract-assign `chrono::Duration` from `DateTime`.
///
/// This is the same as the addition with a negated `Duration`.
///
/// As a part of Chrono's [leap second handling], the addition assumes that **there is no leap
/// second ever**, except when the `DateTime` itself represents a leap second in which case
/// the assumption becomes that **there is exactly a single leap second ever**.
///
/// # Panics
///
/// Panics if the resulting date would be out of range.
/// Consider using [`DateTime<Tz>::checked_sub_signed`] to get an `Option` instead.
impl<Tz: TimeZone> SubAssign<OldDuration> for DateTime<Tz> {
#[inline]
fn sub_assign(&mut self, rhs: OldDuration) {
Expand All @@ -1295,6 +1388,16 @@ impl<Tz: TimeZone> SubAssign<OldDuration> for DateTime<Tz> {
}
}

/// Subtract-assign `std::time::Duration` from `DateTime`.
///
/// As a part of Chrono's [leap second handling], the addition assumes that **there is no leap
/// second ever**, except when the `DateTime` itself represents a leap second in which case
/// the assumption becomes that **there is exactly a single leap second ever**.
///
/// # Panics
///
/// Panics if the resulting date would be out of range.
/// Consider using [`DateTime<Tz>::checked_sub_signed`] to get an `Option` instead.
impl<Tz: TimeZone> SubAssign<Duration> for DateTime<Tz> {
#[inline]
fn sub_assign(&mut self, rhs: Duration) {
Expand All @@ -1304,21 +1407,40 @@ impl<Tz: TimeZone> SubAssign<Duration> for DateTime<Tz> {
}
}

/// Subtract `FixedOffset` from the datetime value of `DateTime` (offset remains unchanged).
///
/// # Panics
///
/// Panics if the resulting date would be out of range.
impl<Tz: TimeZone> Sub<FixedOffset> for DateTime<Tz> {
type Output = DateTime<Tz>;

#[inline]
fn sub(mut self, rhs: FixedOffset) -> DateTime<Tz> {
self.datetime = self.naive_utc().checked_sub_offset(rhs).unwrap();
self.datetime =
self.naive_utc().checked_sub_offset(rhs).expect("`DateTime - FixedOffset` overflowed");
self
}
}

/// Subtract `Months` from `DateTime`.
///
/// The result will be clamped to valid days in the resulting month, see
/// [`DateTime<Tz>::checked_sub_months`] for details.
///
/// # Panics
///
/// Panics if:
/// - The resulting date would be out of range.
/// - The local time at the resulting date does not exist or is ambiguous, for example during a
/// daylight saving time transition.
///
/// Strongly consider using [`DateTime<Tz>::checked_sub_months`] to get an `Option` instead.
impl<Tz: TimeZone> Sub<Months> for DateTime<Tz> {
type Output = DateTime<Tz>;

fn sub(self, rhs: Months) -> Self::Output {
self.checked_sub_months(rhs).unwrap()
self.checked_sub_months(rhs).expect("`DateTime - Months` out of range")
}
}

Expand All @@ -1340,19 +1462,39 @@ impl<Tz: TimeZone> Sub<&DateTime<Tz>> for DateTime<Tz> {
}
}

/// Add `Days` to `NaiveDateTime`.
///
/// # Panics
///
/// Panics if:
/// - The resulting date would be out of range.
/// - The local time at the resulting date does not exist or is ambiguous, for example during a
/// daylight saving time transition.
///
/// Strongly consider using `DateTime<Tz>::checked_sub_days` to get an `Option` instead.
impl<Tz: TimeZone> Add<Days> for DateTime<Tz> {
type Output = DateTime<Tz>;

fn add(self, days: Days) -> Self::Output {
self.checked_add_days(days).unwrap()
self.checked_add_days(days).expect("`DateTime + Days` out of range")
}
}

/// Subtract `Days` from `DateTime`.
///
/// # Panics
///
/// Panics if:
/// - The resulting date would be out of range.
/// - The local time at the resulting date does not exist or is ambiguous, for example during a
/// daylight saving time transition.
///
/// Strongly consider using `DateTime<Tz>::checked_sub_days` to get an `Option` instead.
impl<Tz: TimeZone> Sub<Days> for DateTime<Tz> {
type Output = DateTime<Tz>;

fn sub(self, days: Days) -> Self::Output {
self.checked_sub_days(days).unwrap()
self.checked_sub_days(days).expect("`DateTime - Days` out of range")
}
}

Expand Down
Loading