Repository: chronotope/chrono (language: rust)

Issue:
Deprecate panicking `TimeDelta` initializers
The following methods can panic and have a `try_` variant:
```rust
impl Duration {
    pub const fn weeks(weeks: i64) -> Duration;
    pub const fn days(days: i64) -> Duration;
    pub const fn hours(hours: i64) -> Duration;
    pub const fn minutes(minutes: i64) -> Duration;
    pub const fn seconds(seconds: i64) -> Duration;
    pub const fn milliseconds(milliseconds: i64) -> Duration;
}
```

The replacement methods have been introduced only recently in 0.4.32, and `Duration::try_milliseconds` has not seen a release yet.

In all other places in chrono we have deprecated such panicking methods, and I suppose we should do the same here.
I wonder when would be the right time?

cc @danwilliams


Discussion / hints:
Once replacements are in the field, I think the next release after about 1-2 months should be okay to deprecate.

Might be interesting to pick apart the crates.io downloads to figure out what old releases are still getting picked up (and maybe, why)?
From https://github.com/chronotope/chrono/issues/1408#issuecomment-1931651503:
> Might be interesting to pick apart the crates.io downloads to figure out what old releases are still getting picked up (and maybe, why)?

https://lib.rs/crates/chrono/versions has a nice breakdown. With just a superficial look there is a big correlation between use and for how long a version was the latest release.

Top 5:

| version   | date       | downloads/mo | probable reason
|-----------|------------|--------------|------------------
| total     |            | 6.7M         |
| 0.4.33    | 2024-01-25 | 2.4M (±35%)  | Most-used is the current release.
| 0.4.31    | 2023-09-15 | 2.1M (±31%)  | This was the last release for four months before current
| 0.4.26    | 2023-05-30 | 738K (±11%)  | This was the last release for three months before 5 quick releases
| 0.4.23    | 2022-11-12 | 473K  (±7%)  | Again the last release for four months before before 3 quick releases
| 0.4.19    | 2020-09-30 | 172K  (±2.6) | The last release for close to two years.

It seems to me there are no obvious blockers for users to upgrade. At least the 150 most popular crates that use chrono don't specify a max version, only a minimum version of chrono.

Also interesting that (2.4 + 0.145 + 2.1 + 0.77) / 6.678 = 71% of our users are now on a version of chrono without the time 0.1 dependency.

I have no idea how to figure out which older version of other crates causes the downloads of for example 0.4.19.

Fix patch:
diff --git a/src/format/parsed.rs b/src/format/parsed.rs
index be8db51788..ea5933c84f 100644
--- a/src/format/parsed.rs
+++ b/src/format/parsed.rs
@@ -694,71 +694,15 @@ impl Parsed {
                 (verify_ymd(date) && verify_isoweekdate(date) && verify_ordinal(date), date)
             }
 
-            (
-                Some(year),
-                _,
-                &Parsed { week_from_sun: Some(week_from_sun), weekday: Some(weekday), .. },
-            ) => {
+            (Some(year), _, &Parsed { week_from_sun: Some(week), weekday: Some(weekday), .. }) => {
                 // year, week (starting at 1st Sunday), day of the week
-                let newyear = NaiveDate::from_yo_opt(year, 1).ok_or(OUT_OF_RANGE)?;
-                let firstweek = match newyear.weekday() {
-                    Weekday::Sun => 0,
-                    Weekday::Mon => 6,
-                    Weekday::Tue => 5,
-                    Weekday::Wed => 4,
-                    Weekday::Thu => 3,
-                    Weekday::Fri => 2,
-                    Weekday::Sat => 1,
-                };
-
-                // `firstweek+1`-th day of January is the beginning of the week 1.
-                if week_from_sun > 53 {
-                    return Err(OUT_OF_RANGE);
-                } // can it overflow?
-                let ndays = firstweek
-                    + (week_from_sun as i32 - 1) * 7
-                    + weekday.num_days_from_sunday() as i32;
-                let date = newyear
-                    .checked_add_signed(TimeDelta::days(i64::from(ndays)))
-                    .ok_or(OUT_OF_RANGE)?;
-                if date.year() != year {
-                    return Err(OUT_OF_RANGE);
-                } // early exit for correct error
-
+                let date = resolve_week_date(year, week, weekday, Weekday::Sun)?;
                 (verify_ymd(date) && verify_isoweekdate(date) && verify_ordinal(date), date)
             }
 
-            (
-                Some(year),
-                _,
-                &Parsed { week_from_mon: Some(week_from_mon), weekday: Some(weekday), .. },
-            ) => {
+            (Some(year), _, &Parsed { week_from_mon: Some(week), weekday: Some(weekday), .. }) => {
                 // year, week (starting at 1st Monday), day of the week
-                let newyear = NaiveDate::from_yo_opt(year, 1).ok_or(OUT_OF_RANGE)?;
-                let firstweek = match newyear.weekday() {
-                    Weekday::Sun => 1,
-                    Weekday::Mon => 0,
-                    Weekday::Tue => 6,
-                    Weekday::Wed => 5,
-                    Weekday::Thu => 4,
-                    Weekday::Fri => 3,
-                    Weekday::Sat => 2,
-                };
-
-                // `firstweek+1`-th day of January is the beginning of the week 1.
-                if week_from_mon > 53 {
-                    return Err(OUT_OF_RANGE);
-                } // can it overflow?
-                let ndays = firstweek
-                    + (week_from_mon as i32 - 1) * 7
-                    + weekday.num_days_from_monday() as i32;
-                let date = newyear
-                    .checked_add_signed(TimeDelta::days(i64::from(ndays)))
-                    .ok_or(OUT_OF_RANGE)?;
-                if date.year() != year {
-                    return Err(OUT_OF_RANGE);
-                } // early exit for correct error
-
+                let date = resolve_week_date(year, week, weekday, Weekday::Mon)?;
                 (verify_ymd(date) && verify_isoweekdate(date) && verify_ordinal(date), date)
             }
 
@@ -895,7 +839,7 @@ impl Parsed {
                     59 => {}
                     // `datetime` is known to be off by one second.
                     0 => {
-                        datetime -= TimeDelta::seconds(1);
+                        datetime -= TimeDelta::try_seconds(1).unwrap();
                     }
                     // otherwise it is impossible.
                     _ => return Err(IMPOSSIBLE),
@@ -1038,6 +982,32 @@ impl Parsed {
     }
 }
 
+/// Create a `NaiveDate` when given a year, week, weekday, and the definition at which day of the
+/// week a week starts.
+///
+/// Returns `IMPOSSIBLE` if `week` is `0` or `53` and the `weekday` falls outside the year.
+fn resolve_week_date(
+    year: i32,
+    week: u32,
+    weekday: Weekday,
+    week_start_day: Weekday,
+) -> ParseResult<NaiveDate> {
+    if week > 53 {
+        return Err(OUT_OF_RANGE);
+    }
+
+    let first_day_of_year = NaiveDate::from_yo_opt(year, 1).ok_or(OUT_OF_RANGE)?;
+    // Ordinal of the day at which week 1 starts.
+    let first_week_start = 1 + week_start_day.num_days_from(first_day_of_year.weekday()) as i32;
+    // Number of the `weekday`, which is 0 for the first day of the week.
+    let weekday = weekday.num_days_from(week_start_day) as i32;
+    let ordinal = first_week_start + (week as i32 - 1) * 7 + weekday;
+    if ordinal <= 0 {
+        return Err(IMPOSSIBLE);
+    }
+    first_day_of_year.with_ordinal(ordinal as u32).ok_or(IMPOSSIBLE)
+}
+
 #[cfg(test)]
 mod tests {
     use super::super::{IMPOSSIBLE, NOT_ENOUGH, OUT_OF_RANGE};
@@ -1216,8 +1186,8 @@ mod tests {
         assert_eq!(parse!(year: 2000, week_from_mon: 0), Err(NOT_ENOUGH));
         assert_eq!(parse!(year: 2000, week_from_sun: 0), Err(NOT_ENOUGH));
         assert_eq!(parse!(year: 2000, weekday: Sun), Err(NOT_ENOUGH));
-        assert_eq!(parse!(year: 2000, week_from_mon: 0, weekday: Fri), Err(OUT_OF_RANGE));
-        assert_eq!(parse!(year: 2000, week_from_sun: 0, weekday: Fri), Err(OUT_OF_RANGE));
+        assert_eq!(parse!(year: 2000, week_from_mon: 0, weekday: Fri), Err(IMPOSSIBLE));
+        assert_eq!(parse!(year: 2000, week_from_sun: 0, weekday: Fri), Err(IMPOSSIBLE));
         assert_eq!(parse!(year: 2000, week_from_mon: 0, weekday: Sat), ymd(2000, 1, 1));
         assert_eq!(parse!(year: 2000, week_from_sun: 0, weekday: Sat), ymd(2000, 1, 1));
         assert_eq!(parse!(year: 2000, week_from_mon: 0, weekday: Sun), ymd(2000, 1, 2));
@@ -1231,9 +1201,9 @@ mod tests {
         assert_eq!(parse!(year: 2000, week_from_mon: 2, weekday: Mon), ymd(2000, 1, 10));
         assert_eq!(parse!(year: 2000, week_from_sun: 52, weekday: Sat), ymd(2000, 12, 30));
         assert_eq!(parse!(year: 2000, week_from_sun: 53, weekday: Sun), ymd(2000, 12, 31));
-        assert_eq!(parse!(year: 2000, week_from_sun: 53, weekday: Mon), Err(OUT_OF_RANGE));
+        assert_eq!(parse!(year: 2000, week_from_sun: 53, weekday: Mon), Err(IMPOSSIBLE));
         assert_eq!(parse!(year: 2000, week_from_sun: 0xffffffff, weekday: Mon), Err(OUT_OF_RANGE));
-        assert_eq!(parse!(year: 2006, week_from_sun: 0, weekday: Sat), Err(OUT_OF_RANGE));
+        assert_eq!(parse!(year: 2006, week_from_sun: 0, weekday: Sat), Err(IMPOSSIBLE));
         assert_eq!(parse!(year: 2006, week_from_sun: 1, weekday: Sun), ymd(2006, 1, 1));
 
         // weekdates: conflicting inputs
diff --git a/src/lib.rs b/src/lib.rs
index ad2312b877..917b39691b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -257,16 +257,12 @@
 //! // arithmetic operations
 //! let dt1 = Utc.with_ymd_and_hms(2014, 11, 14, 8, 9, 10).unwrap();
 //! let dt2 = Utc.with_ymd_and_hms(2014, 11, 14, 10, 9, 8).unwrap();
-//! assert_eq!(dt1.signed_duration_since(dt2), TimeDelta::seconds(-2 * 3600 + 2));
-//! assert_eq!(dt2.signed_duration_since(dt1), TimeDelta::seconds(2 * 3600 - 2));
-//! assert_eq!(
-//!     Utc.with_ymd_and_hms(1970, 1, 1, 0, 0, 0).unwrap() + TimeDelta::seconds(1_000_000_000),
-//!     Utc.with_ymd_and_hms(2001, 9, 9, 1, 46, 40).unwrap()
-//! );
-//! assert_eq!(
-//!     Utc.with_ymd_and_hms(1970, 1, 1, 0, 0, 0).unwrap() - TimeDelta::seconds(1_000_000_000),
-//!     Utc.with_ymd_and_hms(1938, 4, 24, 22, 13, 20).unwrap()
-//! );
+//! assert_eq!(dt1.signed_duration_since(dt2), TimeDelta::try_seconds(-2 * 3600 + 2).unwrap());
+//! assert_eq!(dt2.signed_duration_since(dt1), TimeDelta::try_seconds(2 * 3600 - 2).unwrap());
+//! assert_eq!(Utc.with_ymd_and_hms(1970, 1, 1, 0, 0, 0).unwrap() + TimeDelta::try_seconds(1_000_000_000).unwrap(),
+//!            Utc.with_ymd_and_hms(2001, 9, 9, 1, 46, 40).unwrap());
+//! assert_eq!(Utc.with_ymd_and_hms(1970, 1, 1, 0, 0, 0).unwrap() - TimeDelta::try_seconds(1_000_000_000).unwrap(),
+//!            Utc.with_ymd_and_hms(1938, 4, 24, 22, 13, 20).unwrap());
 //! ```
 //!
 //! ### Formatting and Parsing
diff --git a/src/naive/date/mod.rs b/src/naive/date/mod.rs
index d0ac747a6b..9c6d04b480 100644
--- a/src/naive/date/mod.rs
+++ b/src/naive/date/mod.rs
@@ -1057,16 +1057,16 @@ impl NaiveDate {
     ///
     /// let d = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap();
     /// assert_eq!(
-    ///     d.checked_add_signed(TimeDelta::days(40)),
+    ///     d.checked_add_signed(TimeDelta::try_days(40).unwrap()),
     ///     Some(NaiveDate::from_ymd_opt(2015, 10, 15).unwrap())
     /// );
     /// assert_eq!(
-    ///     d.checked_add_signed(TimeDelta::days(-40)),
+    ///     d.checked_add_signed(TimeDelta::try_days(-40).unwrap()),
     ///     Some(NaiveDate::from_ymd_opt(2015, 7, 27).unwrap())
     /// );
-    /// assert_eq!(d.checked_add_signed(TimeDelta::days(1_000_000_000)), None);
-    /// assert_eq!(d.checked_add_signed(TimeDelta::days(-1_000_000_000)), None);
-    /// assert_eq!(NaiveDate::MAX.checked_add_signed(TimeDelta::days(1)), None);
+    /// assert_eq!(d.checked_add_signed(TimeDelta::try_days(1_000_000_000).unwrap()), None);
+    /// assert_eq!(d.checked_add_signed(TimeDelta::try_days(-1_000_000_000).unwrap()), None);
+    /// assert_eq!(NaiveDate::MAX.checked_add_signed(TimeDelta::try_days(1).unwrap()), None);
     /// ```
     #[must_use]
     pub const fn checked_add_signed(self, rhs: TimeDelta) -> Option<NaiveDate> {
@@ -1090,16 +1090,16 @@ impl NaiveDate {
     ///
     /// let d = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap();
     /// assert_eq!(
-    ///     d.checked_sub_signed(TimeDelta::days(40)),
+    ///     d.checked_sub_signed(TimeDelta::try_days(40).unwrap()),
     ///     Some(NaiveDate::from_ymd_opt(2015, 7, 27).unwrap())
     /// );
     /// assert_eq!(
-    ///     d.checked_sub_signed(TimeDelta::days(-40)),
+    ///     d.checked_sub_signed(TimeDelta::try_days(-40).unwrap()),
     ///     Some(NaiveDate::from_ymd_opt(2015, 10, 15).unwrap())
     /// );
-    /// assert_eq!(d.checked_sub_signed(TimeDelta::days(1_000_000_000)), None);
-    /// assert_eq!(d.checked_sub_signed(TimeDelta::days(-1_000_000_000)), None);
-    /// assert_eq!(NaiveDate::MIN.checked_sub_signed(TimeDelta::days(1)), None);
+    /// assert_eq!(d.checked_sub_signed(TimeDelta::try_days(1_000_000_000).unwrap()), None);
+    /// assert_eq!(d.checked_sub_signed(TimeDelta::try_days(-1_000_000_000).unwrap()), None);
+    /// assert_eq!(NaiveDate::MIN.checked_sub_signed(TimeDelta::try_days(1).unwrap()), None);
     /// ```
     #[must_use]
     pub const fn checked_sub_signed(self, rhs: TimeDelta) -> Option<NaiveDate> {
@@ -1125,12 +1125,27 @@ impl NaiveDate {
     /// let since = NaiveDate::signed_duration_since;
     ///
     /// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2014, 1, 1)), TimeDelta::zero());
-    /// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2013, 12, 31)), TimeDelta::days(1));
-    /// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2014, 1, 2)), TimeDelta::days(-1));
-    /// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2013, 9, 23)), TimeDelta::days(100));
-    /// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2013, 1, 1)), TimeDelta::days(365));
-    /// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2010, 1, 1)), TimeDelta::days(365 * 4 + 1));
-    /// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(1614, 1, 1)), TimeDelta::days(365 * 400 + 97));
+    /// assert_eq!(
+    ///     since(from_ymd(2014, 1, 1), from_ymd(2013, 12, 31)),
+    ///     TimeDelta::try_days(1).unwrap()
+    /// );
+    /// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2014, 1, 2)), TimeDelta::try_days(-1).unwrap());
+    /// assert_eq!(
+    ///     since(from_ymd(2014, 1, 1), from_ymd(2013, 9, 23)),
+    ///     TimeDelta::try_days(100).unwrap()
+    /// );
+    /// assert_eq!(
+    ///     since(from_ymd(2014, 1, 1), from_ymd(2013, 1, 1)),
+    ///     TimeDelta::try_days(365).unwrap()
+    /// );
+    /// assert_eq!(
+    ///     since(from_ymd(2014, 1, 1), from_ymd(2010, 1, 1)),
+    ///     TimeDelta::try_days(365 * 4 + 1).unwrap()
+    /// );
+    /// assert_eq!(
+    ///     since(from_ymd(2014, 1, 1), from_ymd(1614, 1, 1)),
+    ///     TimeDelta::try_days(365 * 400 + 97).unwrap()
+    /// );
     /// ```
     #[must_use]
     pub const fn signed_duration_since(self, rhs: NaiveDate) -> TimeDelta {
@@ -1140,7 +1155,10 @@ impl NaiveDate {
         let (year2_div_400, year2_mod_400) = div_mod_floor(year2, 400);
         let cycle1 = yo_to_cycle(year1_mod_400 as u32, self.ordinal()) as i64;
         let cycle2 = yo_to_cycle(year2_mod_400 as u32, rhs.ordinal()) as i64;
-        TimeDelta::days((year1_div_400 as i64 - year2_div_400 as i64) * 146_097 + (cycle1 - cycle2))
+        let days = (year1_div_400 as i64 - year2_div_400 as i64) * 146_097 + (cycle1 - cycle2);
+        // The range of `TimeDelta` is ca. 585 million years, the range of `NaiveDate` ca. 525.000
+        // years.
+        expect!(TimeDelta::try_days(days), "always in range")
     }
 
     /// Returns the number of whole years from the given `base` until `self`.
@@ -1889,13 +1907,22 @@ impl Datelike for NaiveDate {
 /// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
 ///
 /// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::zero(), from_ymd(2014, 1, 1));
-/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::seconds(86399), from_ymd(2014, 1, 1));
-/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::seconds(-86399), from_ymd(2014, 1, 1));
-/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::days(1), from_ymd(2014, 1, 2));
-/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::days(-1), from_ymd(2013, 12, 31));
-/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::days(364), from_ymd(2014, 12, 31));
-/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::days(365 * 4 + 1), from_ymd(2018, 1, 1));
-/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::days(365 * 400 + 97), from_ymd(2414, 1, 1));
+/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::try_seconds(86399).unwrap(), from_ymd(2014, 1, 1));
+/// assert_eq!(
+///     from_ymd(2014, 1, 1) + TimeDelta::try_seconds(-86399).unwrap(),
+///     from_ymd(2014, 1, 1)
+/// );
+/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::try_days(1).unwrap(), from_ymd(2014, 1, 2));
+/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::try_days(-1).unwrap(), from_ymd(2013, 12, 31));
+/// assert_eq!(from_ymd(2014, 1, 1) + TimeDelta::try_days(364).unwrap(), from_ymd(2014, 12, 31));
+/// assert_eq!(
+///     from_ymd(2014, 1, 1) + TimeDelta::try_days(365 * 4 + 1).unwrap(),
+///     from_ymd(2018, 1, 1)
+/// );
+/// assert_eq!(
+///     from_ymd(2014, 1, 1) + TimeDelta::try_days(365 * 400 + 97).unwrap(),
+///     from_ymd(2414, 1, 1)
+/// );
 /// ```
 ///
 /// [`NaiveDate::checked_add_signed`]: crate::NaiveDate::checked_add_signed
@@ -2032,13 +2059,22 @@ impl Sub<Days> for NaiveDate {
 /// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
 ///
 /// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::zero(), from_ymd(2014, 1, 1));
-/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::seconds(86399), from_ymd(2014, 1, 1));
-/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::seconds(-86399), from_ymd(2014, 1, 1));
-/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::days(1), from_ymd(2013, 12, 31));
-/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::days(-1), from_ymd(2014, 1, 2));
-/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::days(364), from_ymd(2013, 1, 2));
-/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::days(365 * 4 + 1), from_ymd(2010, 1, 1));
-/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::days(365 * 400 + 97), from_ymd(1614, 1, 1));
+/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::try_seconds(86399).unwrap(), from_ymd(2014, 1, 1));
+/// assert_eq!(
+///     from_ymd(2014, 1, 1) - TimeDelta::try_seconds(-86399).unwrap(),
+///     from_ymd(2014, 1, 1)
+/// );
+/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::try_days(1).unwrap(), from_ymd(2013, 12, 31));
+/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::try_days(-1).unwrap(), from_ymd(2014, 1, 2));
+/// assert_eq!(from_ymd(2014, 1, 1) - TimeDelta::try_days(364).unwrap(), from_ymd(2013, 1, 2));
+/// assert_eq!(
+///     from_ymd(2014, 1, 1) - TimeDelta::try_days(365 * 4 + 1).unwrap(),
+///     from_ymd(2010, 1, 1)
+/// );
+/// assert_eq!(
+///     from_ymd(2014, 1, 1) - TimeDelta::try_days(365 * 400 + 97).unwrap(),
+///     from_ymd(1614, 1, 1)
+/// );
 /// ```
 ///
 /// [`NaiveDate::checked_sub_signed`]: crate::NaiveDate::checked_sub_signed
@@ -2085,12 +2121,18 @@ impl SubAssign<TimeDelta> for NaiveDate {
 /// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
 ///
 /// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2014, 1, 1), TimeDelta::zero());
-/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 12, 31), TimeDelta::days(1));
-/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2014, 1, 2), TimeDelta::days(-1));
-/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 9, 23), TimeDelta::days(100));
-/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 1, 1), TimeDelta::days(365));
-/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2010, 1, 1), TimeDelta::days(365 * 4 + 1));
-/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(1614, 1, 1), TimeDelta::days(365 * 400 + 97));
+/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 12, 31), TimeDelta::try_days(1).unwrap());
+/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2014, 1, 2), TimeDelta::try_days(-1).unwrap());
+/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 9, 23), TimeDelta::try_days(100).unwrap());
+/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 1, 1), TimeDelta::try_days(365).unwrap());
+/// assert_eq!(
+///     from_ymd(2014, 1, 1) - from_ymd(2010, 1, 1),
+///     TimeDelta::try_days(365 * 4 + 1).unwrap()
+/// );
+/// assert_eq!(
+///     from_ymd(2014, 1, 1) - from_ymd(1614, 1, 1),
+///     TimeDelta::try_days(365 * 400 + 97).unwrap()
+/// );
 /// ```
 impl Sub<NaiveDate> for NaiveDate {
     type Output = TimeDelta;
@@ -2154,7 +2196,7 @@ impl Iterator for NaiveDateWeeksIterator {
 
     fn next(&mut self) -> Option<Self::Item> {
         let current = self.value;
-        self.value = current.checked_add_signed(TimeDelta::weeks(1))?;
+        self.value = current.checked_add_days(Days::new(7))?;
         Some(current)
     }
 
@@ -2169,7 +2211,7 @@ impl ExactSizeIterator for NaiveDateWeeksIterator {}
 impl DoubleEndedIterator for NaiveDateWeeksIterator {
     fn next_back(&mut self) -> Option<Self::Item> {
         let current = self.value;
-        self.value = current.checked_sub_signed(TimeDelta::weeks(1))?;
+        self.value = current.checked_sub_days(Days::new(7))?;
         Some(current)
     }
 }
diff --git a/src/naive/datetime/mod.rs b/src/naive/datetime/mod.rs
index 181576d76c..2336bd8a25 100644
--- a/src/naive/datetime/mod.rs
+++ b/src/naive/datetime/mod.rs
@@ -34,14 +34,6 @@ pub(crate) mod serde;
 #[cfg(test)]
 mod tests;
 
-/// The tight upper bound guarantees that a time delta with `|TimeDelta| >= 2^MAX_SECS_BITS`
-/// will always overflow the addition with any date and time type.
-///
-/// So why is this needed? `TimeDelta::seconds(rhs)` may overflow, and we don't have
-/// an alternative returning `Option` or `Result`. Thus we need some early bound to avoid
-/// touching that call when we are already sure that it WILL overflow...
-const MAX_SECS_BITS: usize = 44;
-
 /// The minimum possible `NaiveDateTime`.
 #[deprecated(since = "0.4.20", note = "Use NaiveDateTime::MIN instead")]
 pub const MIN_DATETIME: NaiveDateTime = NaiveDateTime::MIN;
@@ -479,17 +471,26 @@ impl NaiveDateTime {
     /// let d = from_ymd(2016, 7, 8);
     /// let hms = |h, m, s| d.and_hms_opt(h, m, s).unwrap();
     /// assert_eq!(hms(3, 5, 7).checked_add_signed(TimeDelta::zero()), Some(hms(3, 5, 7)));
-    /// assert_eq!(hms(3, 5, 7).checked_add_signed(TimeDelta::seconds(1)), Some(hms(3, 5, 8)));
-    /// assert_eq!(hms(3, 5, 7).checked_add_signed(TimeDelta::seconds(-1)), Some(hms(3, 5, 6)));
-    /// assert_eq!(hms(3, 5, 7).checked_add_signed(TimeDelta::seconds(3600 + 60)), Some(hms(4, 6, 7)));
     /// assert_eq!(
-    ///     hms(3, 5, 7).checked_add_signed(TimeDelta::seconds(86_400)),
+    ///     hms(3, 5, 7).checked_add_signed(TimeDelta::try_seconds(1).unwrap()),
+    ///     Some(hms(3, 5, 8))
+    /// );
+    /// assert_eq!(
+    ///     hms(3, 5, 7).checked_add_signed(TimeDelta::try_seconds(-1).unwrap()),
+    ///     Some(hms(3, 5, 6))
+    /// );
+    /// assert_eq!(
+    ///     hms(3, 5, 7).checked_add_signed(TimeDelta::try_seconds(3600 + 60).unwrap()),
+    ///     Some(hms(4, 6, 7))
+    /// );
+    /// assert_eq!(
+    ///     hms(3, 5, 7).checked_add_signed(TimeDelta::try_seconds(86_400).unwrap()),
     ///     Some(from_ymd(2016, 7, 9).and_hms_opt(3, 5, 7).unwrap())
     /// );
     ///
     /// let hmsm = |h, m, s, milli| d.and_hms_milli_opt(h, m, s, milli).unwrap();
     /// assert_eq!(
-    ///     hmsm(3, 5, 7, 980).checked_add_signed(TimeDelta::milliseconds(450)),
+    ///     hmsm(3, 5, 7, 980).checked_add_signed(TimeDelta::try_milliseconds(450).unwrap()),
     ///     Some(hmsm(3, 5, 8, 430))
     /// );
     /// ```
@@ -499,7 +500,7 @@ impl NaiveDateTime {
     /// ```
     /// # use chrono::{TimeDelta, NaiveDate};
     /// # let hms = |h, m, s| NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_opt(h, m, s).unwrap();
-    /// assert_eq!(hms(3, 5, 7).checked_add_signed(TimeDelta::days(1_000_000_000)), None);
+    /// assert_eq!(hms(3, 5, 7).checked_add_signed(TimeDelta::try_days(1_000_000_000).unwrap()), None);
     /// ```
     ///
     /// Leap seconds are handled,
@@ -512,29 +513,24 @@ impl NaiveDateTime {
     /// let leap = hmsm(3, 5, 59, 1_300);
     /// assert_eq!(leap.checked_add_signed(TimeDelta::zero()),
     ///            Some(hmsm(3, 5, 59, 1_300)));
-    /// assert_eq!(leap.checked_add_signed(TimeDelta::milliseconds(-500)),
+    /// assert_eq!(leap.checked_add_signed(TimeDelta::try_milliseconds(-500).unwrap()),
     ///            Some(hmsm(3, 5, 59, 800)));
-    /// assert_eq!(leap.checked_add_signed(TimeDelta::milliseconds(500)),
+    /// assert_eq!(leap.checked_add_signed(TimeDelta::try_milliseconds(500).unwrap()),
     ///            Some(hmsm(3, 5, 59, 1_800)));
-    /// assert_eq!(leap.checked_add_signed(TimeDelta::milliseconds(800)),
+    /// assert_eq!(leap.checked_add_signed(TimeDelta::try_milliseconds(800).unwrap()),
     ///            Some(hmsm(3, 6, 0, 100)));
-    /// assert_eq!(leap.checked_add_signed(TimeDelta::seconds(10)),
+    /// assert_eq!(leap.checked_add_signed(TimeDelta::try_seconds(10).unwrap()),
     ///            Some(hmsm(3, 6, 9, 300)));
-    /// assert_eq!(leap.checked_add_signed(TimeDelta::seconds(-10)),
+    /// assert_eq!(leap.checked_add_signed(TimeDelta::try_seconds(-10).unwrap()),
     ///            Some(hmsm(3, 5, 50, 300)));
-    /// assert_eq!(leap.checked_add_signed(TimeDelta::days(1)),
+    /// assert_eq!(leap.checked_add_signed(TimeDelta::try_days(1).unwrap()),
     ///            Some(from_ymd(2016, 7, 9).and_hms_milli_opt(3, 5, 59, 300).unwrap()));
     /// ```
     #[must_use]
     pub const fn checked_add_signed(self, rhs: TimeDelta) -> Option<NaiveDateTime> {
-        let (time, rhs) = self.time.overflowing_add_signed(rhs);
-
-        // early checking to avoid overflow in TimeDelta::seconds
-        if rhs <= (-1 << MAX_SECS_BITS) || rhs >= (1 << MAX_SECS_BITS) {
-            return None;
-        }
-
-        let date = try_opt!(self.date.checked_add_signed(TimeDelta::seconds(rhs)));
+        let (time, remainder) = self.time.overflowing_add_signed(rhs);
+        let remainder = try_opt!(TimeDelta::try_seconds(remainder));
+        let date = try_opt!(self.date.checked_add_signed(remainder));
         Some(NaiveDateTime { date, time })
     }
 
@@ -659,17 +655,26 @@ impl NaiveDateTime {
     /// let d = from_ymd(2016, 7, 8);
     /// let hms = |h, m, s| d.and_hms_opt(h, m, s).unwrap();
     /// assert_eq!(hms(3, 5, 7).checked_sub_signed(TimeDelta::zero()), Some(hms(3, 5, 7)));
-    /// assert_eq!(hms(3, 5, 7).checked_sub_signed(TimeDelta::seconds(1)), Some(hms(3, 5, 6)));
-    /// assert_eq!(hms(3, 5, 7).checked_sub_signed(TimeDelta::seconds(-1)), Some(hms(3, 5, 8)));
-    /// assert_eq!(hms(3, 5, 7).checked_sub_signed(TimeDelta::seconds(3600 + 60)), Some(hms(2, 4, 7)));
     /// assert_eq!(
-    ///     hms(3, 5, 7).checked_sub_signed(TimeDelta::seconds(86_400)),
+    ///     hms(3, 5, 7).checked_sub_signed(TimeDelta::try_seconds(1).unwrap()),
+    ///     Some(hms(3, 5, 6))
+    /// );
+    /// assert_eq!(
+    ///     hms(3, 5, 7).checked_sub_signed(TimeDelta::try_seconds(-1).unwrap()),
+    ///     Some(hms(3, 5, 8))
+    /// );
+    /// assert_eq!(
+    ///     hms(3, 5, 7).checked_sub_signed(TimeDelta::try_seconds(3600 + 60).unwrap()),
+    ///     Some(hms(2, 4, 7))
+    /// );
+    /// assert_eq!(
+    ///     hms(3, 5, 7).checked_sub_signed(TimeDelta::try_seconds(86_400).unwrap()),
     ///     Some(from_ymd(2016, 7, 7).and_hms_opt(3, 5, 7).unwrap())
     /// );
     ///
     /// let hmsm = |h, m, s, milli| d.and_hms_milli_opt(h, m, s, milli).unwrap();
     /// assert_eq!(
-    ///     hmsm(3, 5, 7, 450).checked_sub_signed(TimeDelta::milliseconds(670)),
+    ///     hmsm(3, 5, 7, 450).checked_sub_signed(TimeDelta::try_milliseconds(670).unwrap()),
     ///     Some(hmsm(3, 5, 6, 780))
     /// );
     /// ```
@@ -679,7 +684,7 @@ impl NaiveDateTime {
     /// ```
     /// # use chrono::{TimeDelta, NaiveDate};
     /// # let hms = |h, m, s| NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_opt(h, m, s).unwrap();
-    /// assert_eq!(hms(3, 5, 7).checked_sub_signed(TimeDelta::days(1_000_000_000)), None);
+    /// assert_eq!(hms(3, 5, 7).checked_sub_signed(TimeDelta::try_days(1_000_000_000).unwrap()), None);
     /// ```
     ///
     /// Leap seconds are handled,
@@ -692,25 +697,20 @@ impl NaiveDateTime {
     /// let leap = hmsm(3, 5, 59, 1_300);
     /// assert_eq!(leap.checked_sub_signed(TimeDelta::zero()),
     ///            Some(hmsm(3, 5, 59, 1_300)));
-    /// assert_eq!(leap.checked_sub_signed(TimeDelta::milliseconds(200)),
+    /// assert_eq!(leap.checked_sub_signed(TimeDelta::try_milliseconds(200).unwrap()),
     ///            Some(hmsm(3, 5, 59, 1_100)));
-    /// assert_eq!(leap.checked_sub_signed(TimeDelta::milliseconds(500)),
+    /// assert_eq!(leap.checked_sub_signed(TimeDelta::try_milliseconds(500).unwrap()),
     ///            Some(hmsm(3, 5, 59, 800)));
-    /// assert_eq!(leap.checked_sub_signed(TimeDelta::seconds(60)),
+    /// assert_eq!(leap.checked_sub_signed(TimeDelta::try_seconds(60).unwrap()),
     ///            Some(hmsm(3, 5, 0, 300)));
-    /// assert_eq!(leap.checked_sub_signed(TimeDelta::days(1)),
+    /// assert_eq!(leap.checked_sub_signed(TimeDelta::try_days(1).unwrap()),
     ///            Some(from_ymd(2016, 7, 7).and_hms_milli_opt(3, 6, 0, 300).unwrap()));
     /// ```
     #[must_use]
     pub const fn checked_sub_signed(self, rhs: TimeDelta) -> Option<NaiveDateTime> {
-        let (time, rhs) = self.time.overflowing_sub_signed(rhs);
-
-        // early checking to avoid overflow in TimeDelta::seconds
-        if rhs <= (-1 << MAX_SECS_BITS) || rhs >= (1 << MAX_SECS_BITS) {
-            return None;
-        }
-
-        let date = try_opt!(self.date.checked_sub_signed(TimeDelta::seconds(rhs)));
+        let (time, remainder) = self.time.overflowing_sub_signed(rhs);
+        let remainder = try_opt!(TimeDelta::try_seconds(remainder));
+        let date = try_opt!(self.date.checked_sub_signed(remainder));
         Some(NaiveDateTime { date, time })
     }
 
@@ -785,7 +785,7 @@ impl NaiveDateTime {
     /// let d = from_ymd(2016, 7, 8);
     /// assert_eq!(
     ///     d.and_hms_opt(3, 5, 7).unwrap().signed_duration_since(d.and_hms_opt(2, 4, 6).unwrap()),
-    ///     TimeDelta::seconds(3600 + 60 + 1)
+    ///     TimeDelta::try_seconds(3600 + 60 + 1).unwrap()
     /// );
     ///
     /// // July 8 is 190th day in the year 2016
@@ -794,7 +794,8 @@ impl NaiveDateTime {
     ///     d.and_hms_milli_opt(0, 7, 6, 500)
     ///         .unwrap()
     ///         .signed_duration_since(d0.and_hms_opt(0, 0, 0).unwrap()),
-    ///     TimeDelta::seconds(189 * 86_400 + 7 * 60 + 6) + TimeDelta::milliseconds(500)
+    ///     TimeDelta::try_seconds(189 * 86_400 + 7 * 60 + 6).unwrap()
+    ///         + TimeDelta::try_milliseconds(500).unwrap()
     /// );
     /// ```
     ///
@@ -807,11 +808,11 @@ impl NaiveDateTime {
     /// let leap = from_ymd(2015, 6, 30).and_hms_milli_opt(23, 59, 59, 1_500).unwrap();
     /// assert_eq!(
     ///     leap.signed_duration_since(from_ymd(2015, 6, 30).and_hms_opt(23, 0, 0).unwrap()),
-    ///     TimeDelta::seconds(3600) + TimeDelta::milliseconds(500)
+    ///     TimeDelta::try_seconds(3600).unwrap() + TimeDelta::try_milliseconds(500).unwrap()
     /// );
     /// assert_eq!(
     ///     from_ymd(2015, 7, 1).and_hms_opt(1, 0, 0).unwrap().signed_duration_since(leap),
-    ///     TimeDelta::seconds(3600) - TimeDelta::milliseconds(500)
+    ///     TimeDelta::try_seconds(3600).unwrap() - TimeDelta::try_milliseconds(500).unwrap()
     /// );
     /// ```
     #[must_use]
@@ -1596,20 +1597,20 @@ impl Timelike for NaiveDateTime {
 /// let d = from_ymd(2016, 7, 8);
 /// let hms = |h, m, s| d.and_hms_opt(h, m, s).unwrap();
 /// assert_eq!(hms(3, 5, 7) + TimeDelta::zero(), hms(3, 5, 7));
-/// assert_eq!(hms(3, 5, 7) + TimeDelta::seconds(1), hms(3, 5, 8));
-/// assert_eq!(hms(3, 5, 7) + TimeDelta::seconds(-1), hms(3, 5, 6));
-/// assert_eq!(hms(3, 5, 7) + TimeDelta::seconds(3600 + 60), hms(4, 6, 7));
+/// assert_eq!(hms(3, 5, 7) + TimeDelta::try_seconds(1).unwrap(), hms(3, 5, 8));
+/// assert_eq!(hms(3, 5, 7) + TimeDelta::try_seconds(-1).unwrap(), hms(3, 5, 6));
+/// assert_eq!(hms(3, 5, 7) + TimeDelta::try_seconds(3600 + 60).unwrap(), hms(4, 6, 7));
 /// assert_eq!(
-///     hms(3, 5, 7) + TimeDelta::seconds(86_400),
+///     hms(3, 5, 7) + TimeDelta::try_seconds(86_400).unwrap(),
 ///     from_ymd(2016, 7, 9).and_hms_opt(3, 5, 7).unwrap()
 /// );
 /// assert_eq!(
-///     hms(3, 5, 7) + TimeDelta::days(365),
+///     hms(3, 5, 7) + TimeDelta::try_days(365).unwrap(),
 ///     from_ymd(2017, 7, 8).and_hms_opt(3, 5, 7).unwrap()
 /// );
 ///
 /// let hmsm = |h, m, s, milli| d.and_hms_milli_opt(h, m, s, milli).unwrap();
-/// assert_eq!(hmsm(3, 5, 7, 980) + TimeDelta::milliseconds(450), hmsm(3, 5, 8, 430));
+/// assert_eq!(hmsm(3, 5, 7, 980) + TimeDelta::try_milliseconds(450).unwrap(), hmsm(3, 5, 8, 430));
 /// ```
 ///
 /// Leap seconds are handled,
@@ -1620,13 +1621,13 @@ impl Timelike for NaiveDateTime {
 /// # let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
 /// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli_opt(h, m, s, milli).unwrap();
 /// let leap = hmsm(3, 5, 59, 1_300);
-/// assert_eq!(leap + TimeDelta::zero(),             hmsm(3, 5, 59, 1_300));
-/// assert_eq!(leap + TimeDelta::milliseconds(-500), hmsm(3, 5, 59, 800));
-/// assert_eq!(leap + TimeDelta::milliseconds(500),  hmsm(3, 5, 59, 1_800));
-/// assert_eq!(leap + TimeDelta::milliseconds(800),  hmsm(3, 6, 0, 100));
-/// assert_eq!(leap + TimeDelta::seconds(10),        hmsm(3, 6, 9, 300));
-/// assert_eq!(leap + TimeDelta::seconds(-10),       hmsm(3, 5, 50, 300));
-/// assert_eq!(leap + TimeDelta::days(1),
+/// assert_eq!(leap + TimeDelta::zero(), hmsm(3, 5, 59, 1_300));
+/// assert_eq!(leap + TimeDelta::try_milliseconds(-500).unwrap(), hmsm(3, 5, 59, 800));
+/// assert_eq!(leap + TimeDelta::try_milliseconds(500).unwrap(), hmsm(3, 5, 59, 1_800));
+/// assert_eq!(leap + TimeDelta::try_milliseconds(800).unwrap(), hmsm(3, 6, 0, 100));
+/// assert_eq!(leap + TimeDelta::try_seconds(10).unwrap(), hmsm(3, 6, 9, 300));
+/// assert_eq!(leap + TimeDelta::try_seconds(-10).unwrap(), hmsm(3, 5, 50, 300));
+/// assert_eq!(leap + TimeDelta::try_days(1).unwrap(),
 ///            from_ymd(2016, 7, 9).and_hms_milli_opt(3, 5, 59, 300).unwrap());
 /// ```
 ///
@@ -1786,20 +1787,20 @@ impl Add<Months> for NaiveDateTime {
 /// let d = from_ymd(2016, 7, 8);
 /// let hms = |h, m, s| d.and_hms_opt(h, m, s).unwrap();
 /// assert_eq!(hms(3, 5, 7) - TimeDelta::zero(), hms(3, 5, 7));
-/// assert_eq!(hms(3, 5, 7) - TimeDelta::seconds(1), hms(3, 5, 6));
-/// assert_eq!(hms(3, 5, 7) - TimeDelta::seconds(-1), hms(3, 5, 8));
-/// assert_eq!(hms(3, 5, 7) - TimeDelta::seconds(3600 + 60), hms(2, 4, 7));
+/// assert_eq!(hms(3, 5, 7) - TimeDelta::try_seconds(1).unwrap(), hms(3, 5, 6));
+/// assert_eq!(hms(3, 5, 7) - TimeDelta::try_seconds(-1).unwrap(), hms(3, 5, 8));
+/// assert_eq!(hms(3, 5, 7) - TimeDelta::try_seconds(3600 + 60).unwrap(), hms(2, 4, 7));
 /// assert_eq!(
-///     hms(3, 5, 7) - TimeDelta::seconds(86_400),
+///     hms(3, 5, 7) - TimeDelta::try_seconds(86_400).unwrap(),
 ///     from_ymd(2016, 7, 7).and_hms_opt(3, 5, 7).unwrap()
 /// );
 /// assert_eq!(
-///     hms(3, 5, 7) - TimeDelta::days(365),
+///     hms(3, 5, 7) - TimeDelta::try_days(365).unwrap(),
 ///     from_ymd(2015, 7, 9).and_hms_opt(3, 5, 7).unwrap()
 /// );
 ///
 /// let hmsm = |h, m, s, milli| d.and_hms_milli_opt(h, m, s, milli).unwrap();
-/// assert_eq!(hmsm(3, 5, 7, 450) - TimeDelta::milliseconds(670), hmsm(3, 5, 6, 780));
+/// assert_eq!(hmsm(3, 5, 7, 450) - TimeDelta::try_milliseconds(670).unwrap(), hmsm(3, 5, 6, 780));
 /// ```
 ///
 /// Leap seconds are handled,
@@ -1810,11 +1811,11 @@ impl Add<Months> for NaiveDateTime {
 /// # let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
 /// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli_opt(h, m, s, milli).unwrap();
 /// let leap = hmsm(3, 5, 59, 1_300);
-/// assert_eq!(leap - TimeDelta::zero(),            hmsm(3, 5, 59, 1_300));
-/// assert_eq!(leap - TimeDelta::milliseconds(200), hmsm(3, 5, 59, 1_100));
-/// assert_eq!(leap - TimeDelta::milliseconds(500), hmsm(3, 5, 59, 800));
-/// assert_eq!(leap - TimeDelta::seconds(60),       hmsm(3, 5, 0, 300));
-/// assert_eq!(leap - TimeDelta::days(1),
+/// assert_eq!(leap - TimeDelta::zero(), hmsm(3, 5, 59, 1_300));
+/// assert_eq!(leap - TimeDelta::try_milliseconds(200).unwrap(), hmsm(3, 5, 59, 1_100));
+/// assert_eq!(leap - TimeDelta::try_milliseconds(500).unwrap(), hmsm(3, 5, 59, 800));
+/// assert_eq!(leap - TimeDelta::try_seconds(60).unwrap(), hmsm(3, 5, 0, 300));
+/// assert_eq!(leap - TimeDelta::try_days(1).unwrap(),
 ///            from_ymd(2016, 7, 7).and_hms_milli_opt(3, 6, 0, 300).unwrap());
 /// ```
 ///
@@ -1960,14 +1961,15 @@ impl Sub<Months> for NaiveDateTime {
 /// let d = from_ymd(2016, 7, 8);
 /// assert_eq!(
 ///     d.and_hms_opt(3, 5, 7).unwrap() - d.and_hms_opt(2, 4, 6).unwrap(),
-///     TimeDelta::seconds(3600 + 60 + 1)
+///     TimeDelta::try_seconds(3600 + 60 + 1).unwrap()
 /// );
 ///
 /// // July 8 is 190th day in the year 2016
 /// let d0 = from_ymd(2016, 1, 1);
 /// assert_eq!(
 ///     d.and_hms_milli_opt(0, 7, 6, 500).unwrap() - d0.and_hms_opt(0, 0, 0).unwrap(),
-///     TimeDelta::seconds(189 * 86_400 + 7 * 60 + 6) + TimeDelta::milliseconds(500)
+///     TimeDelta::try_seconds(189 * 86_400 + 7 * 60 + 6).unwrap()
+///         + TimeDelta::try_milliseconds(500).unwrap()
 /// );
 /// ```
 ///
@@ -1980,11 +1982,11 @@ impl Sub<Months> for NaiveDateTime {
 /// let leap = from_ymd(2015, 6, 30).and_hms_milli_opt(23, 59, 59, 1_500).unwrap();
 /// assert_eq!(
 ///     leap - from_ymd(2015, 6, 30).and_hms_opt(23, 0, 0).unwrap(),
-///     TimeDelta::seconds(3600) + TimeDelta::milliseconds(500)
+///     TimeDelta::try_seconds(3600).unwrap() + TimeDelta::try_milliseconds(500).unwrap()
 /// );
 /// assert_eq!(
 ///     from_ymd(2015, 7, 1).and_hms_opt(1, 0, 0).unwrap() - leap,
-///     TimeDelta::seconds(3600) - TimeDelta::milliseconds(500)
+///     TimeDelta::try_seconds(3600).unwrap() - TimeDelta::try_milliseconds(500).unwrap()
 /// );
 /// ```
 impl Sub<NaiveDateTime> for NaiveDateTime {
diff --git a/src/naive/time/mod.rs b/src/naive/time/mod.rs
index 57c4f5ca03..23b1cb0e55 100644
--- a/src/naive/time/mod.rs
+++ b/src/naive/time/mod.rs
@@ -594,15 +594,15 @@ impl NaiveTime {
     /// let from_hms = |h, m, s| NaiveTime::from_hms_opt(h, m, s).unwrap();
     ///
     /// assert_eq!(
-    ///     from_hms(3, 4, 5).overflowing_add_signed(TimeDelta::hours(11)),
+    ///     from_hms(3, 4, 5).overflowing_add_signed(TimeDelta::try_hours(11).unwrap()),
     ///     (from_hms(14, 4, 5), 0)
     /// );
     /// assert_eq!(
-    ///     from_hms(3, 4, 5).overflowing_add_signed(TimeDelta::hours(23)),
+    ///     from_hms(3, 4, 5).overflowing_add_signed(TimeDelta::try_hours(23).unwrap()),
     ///     (from_hms(2, 4, 5), 86_400)
     /// );
     /// assert_eq!(
-    ///     from_hms(3, 4, 5).overflowing_add_signed(TimeDelta::hours(-7)),
+    ///     from_hms(3, 4, 5).overflowing_add_signed(TimeDelta::try_hours(-7).unwrap()),
     ///     (from_hms(20, 4, 5), -86_400)
     /// );
     /// ```
@@ -656,15 +656,15 @@ impl NaiveTime {
     /// let from_hms = |h, m, s| NaiveTime::from_hms_opt(h, m, s).unwrap();
     ///
     /// assert_eq!(
-    ///     from_hms(3, 4, 5).overflowing_sub_signed(TimeDelta::hours(2)),
+    ///     from_hms(3, 4, 5).overflowing_sub_signed(TimeDelta::try_hours(2).unwrap()),
     ///     (from_hms(1, 4, 5), 0)
     /// );
     /// assert_eq!(
-    ///     from_hms(3, 4, 5).overflowing_sub_signed(TimeDelta::hours(17)),
+    ///     from_hms(3, 4, 5).overflowing_sub_signed(TimeDelta::try_hours(17).unwrap()),
     ///     (from_hms(10, 4, 5), 86_400)
     /// );
     /// assert_eq!(
-    ///     from_hms(3, 4, 5).overflowing_sub_signed(TimeDelta::hours(-22)),
+    ///     from_hms(3, 4, 5).overflowing_sub_signed(TimeDelta::try_hours(-22).unwrap()),
     ///     (from_hms(1, 4, 5), -86_400)
     /// );
     /// ```
@@ -696,22 +696,31 @@ impl NaiveTime {
     /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 7, 900)), TimeDelta::zero());
     /// assert_eq!(
     ///     since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 7, 875)),
-    ///     TimeDelta::milliseconds(25)
+    ///     TimeDelta::try_milliseconds(25).unwrap()
     /// );
     /// assert_eq!(
     ///     since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 6, 925)),
-    ///     TimeDelta::milliseconds(975)
+    ///     TimeDelta::try_milliseconds(975).unwrap()
+    /// );
+    /// assert_eq!(
+    ///     since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 0, 900)),
+    ///     TimeDelta::try_seconds(7).unwrap()
+    /// );
+    /// assert_eq!(
+    ///     since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 0, 7, 900)),
+    ///     TimeDelta::try_seconds(5 * 60).unwrap()
     /// );
-    /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 5, 0, 900)), TimeDelta::seconds(7));
-    /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(3, 0, 7, 900)), TimeDelta::seconds(5 * 60));
     /// assert_eq!(
     ///     since(from_hmsm(3, 5, 7, 900), from_hmsm(0, 5, 7, 900)),
-    ///     TimeDelta::seconds(3 * 3600)
+    ///     TimeDelta::try_seconds(3 * 3600).unwrap()
+    /// );
+    /// assert_eq!(
+    ///     since(from_hmsm(3, 5, 7, 900), from_hmsm(4, 5, 7, 900)),
+    ///     TimeDelta::try_seconds(-3600).unwrap()
     /// );
-    /// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(4, 5, 7, 900)), TimeDelta::seconds(-3600));
     /// assert_eq!(
     ///     since(from_hmsm(3, 5, 7, 900), from_hmsm(2, 4, 6, 800)),
-    ///     TimeDelta::seconds(3600 + 60 + 1) + TimeDelta::milliseconds(100)
+    ///     TimeDelta::try_seconds(3600 + 60 + 1).unwrap() + TimeDelta::try_milliseconds(100).unwrap()
     /// );
     /// ```
     ///
@@ -723,15 +732,15 @@ impl NaiveTime {
     /// # let from_hmsm = |h, m, s, milli| { NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap() };
     /// # let since = NaiveTime::signed_duration_since;
     /// assert_eq!(since(from_hmsm(3, 0, 59, 1_000), from_hmsm(3, 0, 59, 0)),
-    ///            TimeDelta::seconds(1));
+    ///            TimeDelta::try_seconds(1).unwrap());
     /// assert_eq!(since(from_hmsm(3, 0, 59, 1_500), from_hmsm(3, 0, 59, 0)),
-    ///            TimeDelta::milliseconds(1500));
+    ///            TimeDelta::try_milliseconds(1500).unwrap());
     /// assert_eq!(since(from_hmsm(3, 0, 59, 1_000), from_hmsm(3, 0, 0, 0)),
-    ///            TimeDelta::seconds(60));
+    ///            TimeDelta::try_seconds(60).unwrap());
     /// assert_eq!(since(from_hmsm(3, 0, 0, 0), from_hmsm(2, 59, 59, 1_000)),
-    ///            TimeDelta::seconds(1));
+    ///            TimeDelta::try_seconds(1).unwrap());
     /// assert_eq!(since(from_hmsm(3, 0, 59, 1_000), from_hmsm(2, 59, 59, 1_000)),
-    ///            TimeDelta::seconds(61));
+    ///            TimeDelta::try_seconds(61).unwrap());
     /// ```
     #[must_use]
     pub const fn signed_duration_since(self, rhs: NaiveTime) -> TimeDelta {
@@ -1147,16 +1156,28 @@ impl Timelike for NaiveTime {
 /// let from_hmsm = |h, m, s, milli| NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap();
 ///
 /// assert_eq!(from_hmsm(3, 5, 7, 0) + TimeDelta::zero(), from_hmsm(3, 5, 7, 0));
-/// assert_eq!(from_hmsm(3, 5, 7, 0) + TimeDelta::seconds(1), from_hmsm(3, 5, 8, 0));
-/// assert_eq!(from_hmsm(3, 5, 7, 0) + TimeDelta::seconds(-1), from_hmsm(3, 5, 6, 0));
-/// assert_eq!(from_hmsm(3, 5, 7, 0) + TimeDelta::seconds(60 + 4), from_hmsm(3, 6, 11, 0));
+/// assert_eq!(from_hmsm(3, 5, 7, 0) + TimeDelta::try_seconds(1).unwrap(), from_hmsm(3, 5, 8, 0));
+/// assert_eq!(from_hmsm(3, 5, 7, 0) + TimeDelta::try_seconds(-1).unwrap(), from_hmsm(3, 5, 6, 0));
+/// assert_eq!(
+///     from_hmsm(3, 5, 7, 0) + TimeDelta::try_seconds(60 + 4).unwrap(),
+///     from_hmsm(3, 6, 11, 0)
+/// );
 /// assert_eq!(
-///     from_hmsm(3, 5, 7, 0) + TimeDelta::seconds(7 * 60 * 60 - 6 * 60),
+///     from_hmsm(3, 5, 7, 0) + TimeDelta::try_seconds(7 * 60 * 60 - 6 * 60).unwrap(),
 ///     from_hmsm(9, 59, 7, 0)
 /// );
-/// assert_eq!(from_hmsm(3, 5, 7, 0) + TimeDelta::milliseconds(80), from_hmsm(3, 5, 7, 80));
-/// assert_eq!(from_hmsm(3, 5, 7, 950) + TimeDelta::milliseconds(280), from_hmsm(3, 5, 8, 230));
-/// assert_eq!(from_hmsm(3, 5, 7, 950) + TimeDelta::milliseconds(-980), from_hmsm(3, 5, 6, 970));
+/// assert_eq!(
+///     from_hmsm(3, 5, 7, 0) + TimeDelta::try_milliseconds(80).unwrap(),
+///     from_hmsm(3, 5, 7, 80)
+/// );
+/// assert_eq!(
+///     from_hmsm(3, 5, 7, 950) + TimeDelta::try_milliseconds(280).unwrap(),
+///     from_hmsm(3, 5, 8, 230)
+/// );
+/// assert_eq!(
+///     from_hmsm(3, 5, 7, 950) + TimeDelta::try_milliseconds(-980).unwrap(),
+///     from_hmsm(3, 5, 6, 970)
+/// );
 /// ```
 ///
 /// The addition wraps around.
@@ -1164,9 +1185,9 @@ impl Timelike for NaiveTime {
 /// ```
 /// # use chrono::{TimeDelta, NaiveTime};
 /// # let from_hmsm = |h, m, s, milli| { NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap() };
-/// assert_eq!(from_hmsm(3, 5, 7, 0) + TimeDelta::seconds(22*60*60), from_hmsm(1, 5, 7, 0));
-/// assert_eq!(from_hmsm(3, 5, 7, 0) + TimeDelta::seconds(-8*60*60), from_hmsm(19, 5, 7, 0));
-/// assert_eq!(from_hmsm(3, 5, 7, 0) + TimeDelta::days(800),         from_hmsm(3, 5, 7, 0));
+/// assert_eq!(from_hmsm(3, 5, 7, 0) + TimeDelta::try_seconds(22*60*60).unwrap(), from_hmsm(1, 5, 7, 0));
+/// assert_eq!(from_hmsm(3, 5, 7, 0) + TimeDelta::try_seconds(-8*60*60).unwrap(), from_hmsm(19, 5, 7, 0));
+/// assert_eq!(from_hmsm(3, 5, 7, 0) + TimeDelta::try_days(800).unwrap(), from_hmsm(3, 5, 7, 0));
 /// ```
 ///
 /// Leap seconds are handled, but the addition assumes that it is the only leap second happened.
@@ -1175,13 +1196,13 @@ impl Timelike for NaiveTime {
 /// # use chrono::{TimeDelta, NaiveTime};
 /// # let from_hmsm = |h, m, s, milli| { NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap() };
 /// let leap = from_hmsm(3, 5, 59, 1_300);
-/// assert_eq!(leap + TimeDelta::zero(),             from_hmsm(3, 5, 59, 1_300));
-/// assert_eq!(leap + TimeDelta::milliseconds(-500), from_hmsm(3, 5, 59, 800));
-/// assert_eq!(leap + TimeDelta::milliseconds(500),  from_hmsm(3, 5, 59, 1_800));
-/// assert_eq!(leap + TimeDelta::milliseconds(800),  from_hmsm(3, 6, 0, 100));
-/// assert_eq!(leap + TimeDelta::seconds(10),        from_hmsm(3, 6, 9, 300));
-/// assert_eq!(leap + TimeDelta::seconds(-10),       from_hmsm(3, 5, 50, 300));
-/// assert_eq!(leap + TimeDelta::days(1),            from_hmsm(3, 5, 59, 300));
+/// assert_eq!(leap + TimeDelta::zero(), from_hmsm(3, 5, 59, 1_300));
+/// assert_eq!(leap + TimeDelta::try_milliseconds(-500).unwrap(), from_hmsm(3, 5, 59, 800));
+/// assert_eq!(leap + TimeDelta::try_milliseconds(500).unwrap(), from_hmsm(3, 5, 59, 1_800));
+/// assert_eq!(leap + TimeDelta::try_milliseconds(800).unwrap(), from_hmsm(3, 6, 0, 100));
+/// assert_eq!(leap + TimeDelta::try_seconds(10).unwrap(), from_hmsm(3, 6, 9, 300));
+/// assert_eq!(leap + TimeDelta::try_seconds(-10).unwrap(), from_hmsm(3, 5, 50, 300));
+/// assert_eq!(leap + TimeDelta::try_days(1).unwrap(), from_hmsm(3, 5, 59, 300));
 /// ```
 ///
 /// [leap second handling]: crate::NaiveTime#leap-second-handling
@@ -1265,14 +1286,23 @@ impl Add<FixedOffset> for NaiveTime {
 /// let from_hmsm = |h, m, s, milli| NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap();
 ///
 /// assert_eq!(from_hmsm(3, 5, 7, 0) - TimeDelta::zero(), from_hmsm(3, 5, 7, 0));
-/// assert_eq!(from_hmsm(3, 5, 7, 0) - TimeDelta::seconds(1), from_hmsm(3, 5, 6, 0));
-/// assert_eq!(from_hmsm(3, 5, 7, 0) - TimeDelta::seconds(60 + 5), from_hmsm(3, 4, 2, 0));
+/// assert_eq!(from_hmsm(3, 5, 7, 0) - TimeDelta::try_seconds(1).unwrap(), from_hmsm(3, 5, 6, 0));
+/// assert_eq!(
+///     from_hmsm(3, 5, 7, 0) - TimeDelta::try_seconds(60 + 5).unwrap(),
+///     from_hmsm(3, 4, 2, 0)
+/// );
 /// assert_eq!(
-///     from_hmsm(3, 5, 7, 0) - TimeDelta::seconds(2 * 60 * 60 + 6 * 60),
+///     from_hmsm(3, 5, 7, 0) - TimeDelta::try_seconds(2 * 60 * 60 + 6 * 60).unwrap(),
 ///     from_hmsm(0, 59, 7, 0)
 /// );
-/// assert_eq!(from_hmsm(3, 5, 7, 0) - TimeDelta::milliseconds(80), from_hmsm(3, 5, 6, 920));
-/// assert_eq!(from_hmsm(3, 5, 7, 950) - TimeDelta::milliseconds(280), from_hmsm(3, 5, 7, 670));
+/// assert_eq!(
+///     from_hmsm(3, 5, 7, 0) - TimeDelta::try_milliseconds(80).unwrap(),
+///     from_hmsm(3, 5, 6, 920)
+/// );
+/// assert_eq!(
+///     from_hmsm(3, 5, 7, 950) - TimeDelta::try_milliseconds(280).unwrap(),
+///     from_hmsm(3, 5, 7, 670)
+/// );
 /// ```
 ///
 /// The subtraction wraps around.
@@ -1280,8 +1310,8 @@ impl Add<FixedOffset> for NaiveTime {
 /// ```
 /// # use chrono::{TimeDelta, NaiveTime};
 /// # let from_hmsm = |h, m, s, milli| { NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap() };
-/// assert_eq!(from_hmsm(3, 5, 7, 0) - TimeDelta::seconds(8*60*60), from_hmsm(19, 5, 7, 0));
-/// assert_eq!(from_hmsm(3, 5, 7, 0) - TimeDelta::days(800),        from_hmsm(3, 5, 7, 0));
+/// assert_eq!(from_hmsm(3, 5, 7, 0) - TimeDelta::try_seconds(8*60*60).unwrap(), from_hmsm(19, 5, 7, 0));
+/// assert_eq!(from_hmsm(3, 5, 7, 0) - TimeDelta::try_days(800).unwrap(), from_hmsm(3, 5, 7, 0));
 /// ```
 ///
 /// Leap seconds are handled, but the subtraction assumes that it is the only leap second happened.
@@ -1290,11 +1320,11 @@ impl Add<FixedOffset> for NaiveTime {
 /// # use chrono::{TimeDelta, NaiveTime};
 /// # let from_hmsm = |h, m, s, milli| { NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap() };
 /// let leap = from_hmsm(3, 5, 59, 1_300);
-/// assert_eq!(leap - TimeDelta::zero(),            from_hmsm(3, 5, 59, 1_300));
-/// assert_eq!(leap - TimeDelta::milliseconds(200), from_hmsm(3, 5, 59, 1_100));
-/// assert_eq!(leap - TimeDelta::milliseconds(500), from_hmsm(3, 5, 59, 800));
-/// assert_eq!(leap - TimeDelta::seconds(60),       from_hmsm(3, 5, 0, 300));
-/// assert_eq!(leap - TimeDelta::days(1),           from_hmsm(3, 6, 0, 300));
+/// assert_eq!(leap - TimeDelta::zero(), from_hmsm(3, 5, 59, 1_300));
+/// assert_eq!(leap - TimeDelta::try_milliseconds(200).unwrap(), from_hmsm(3, 5, 59, 1_100));
+/// assert_eq!(leap - TimeDelta::try_milliseconds(500).unwrap(), from_hmsm(3, 5, 59, 800));
+/// assert_eq!(leap - TimeDelta::try_seconds(60).unwrap(), from_hmsm(3, 5, 0, 300));
+/// assert_eq!(leap - TimeDelta::try_days(1).unwrap(), from_hmsm(3, 6, 0, 300));
 /// ```
 ///
 /// [leap second handling]: crate::NaiveTime#leap-second-handling
@@ -1381,15 +1411,33 @@ impl Sub<FixedOffset> for NaiveTime {
 /// let from_hmsm = |h, m, s, milli| NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap();
 ///
 /// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(3, 5, 7, 900), TimeDelta::zero());
-/// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(3, 5, 7, 875), TimeDelta::milliseconds(25));
-/// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(3, 5, 6, 925), TimeDelta::milliseconds(975));
-/// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(3, 5, 0, 900), TimeDelta::seconds(7));
-/// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(3, 0, 7, 900), TimeDelta::seconds(5 * 60));
-/// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(0, 5, 7, 900), TimeDelta::seconds(3 * 3600));
-/// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(4, 5, 7, 900), TimeDelta::seconds(-3600));
+/// assert_eq!(
+///     from_hmsm(3, 5, 7, 900) - from_hmsm(3, 5, 7, 875),
+///     TimeDelta::try_milliseconds(25).unwrap()
+/// );
+/// assert_eq!(
+///     from_hmsm(3, 5, 7, 900) - from_hmsm(3, 5, 6, 925),
+///     TimeDelta::try_milliseconds(975).unwrap()
+/// );
+/// assert_eq!(
+///     from_hmsm(3, 5, 7, 900) - from_hmsm(3, 5, 0, 900),
+///     TimeDelta::try_seconds(7).unwrap()
+/// );
+/// assert_eq!(
+///     from_hmsm(3, 5, 7, 900) - from_hmsm(3, 0, 7, 900),
+///     TimeDelta::try_seconds(5 * 60).unwrap()
+/// );
+/// assert_eq!(
+///     from_hmsm(3, 5, 7, 900) - from_hmsm(0, 5, 7, 900),
+///     TimeDelta::try_seconds(3 * 3600).unwrap()
+/// );
+/// assert_eq!(
+///     from_hmsm(3, 5, 7, 900) - from_hmsm(4, 5, 7, 900),
+///     TimeDelta::try_seconds(-3600).unwrap()
+/// );
 /// assert_eq!(
 ///     from_hmsm(3, 5, 7, 900) - from_hmsm(2, 4, 6, 800),
-///     TimeDelta::seconds(3600 + 60 + 1) + TimeDelta::milliseconds(100)
+///     TimeDelta::try_seconds(3600 + 60 + 1).unwrap() + TimeDelta::try_milliseconds(100).unwrap()
 /// );
 /// ```
 ///
@@ -1399,13 +1447,13 @@ impl Sub<FixedOffset> for NaiveTime {
 /// ```
 /// # use chrono::{TimeDelta, NaiveTime};
 /// # let from_hmsm = |h, m, s, milli| { NaiveTime::from_hms_milli_opt(h, m, s, milli).unwrap() };
-/// assert_eq!(from_hmsm(3, 0, 59, 1_000) - from_hmsm(3, 0, 59, 0), TimeDelta::seconds(1));
+/// assert_eq!(from_hmsm(3, 0, 59, 1_000) - from_hmsm(3, 0, 59, 0), TimeDelta::try_seconds(1).unwrap());
 /// assert_eq!(from_hmsm(3, 0, 59, 1_500) - from_hmsm(3, 0, 59, 0),
-///            TimeDelta::milliseconds(1500));
-/// assert_eq!(from_hmsm(3, 0, 59, 1_000) - from_hmsm(3, 0, 0, 0), TimeDelta::seconds(60));
-/// assert_eq!(from_hmsm(3, 0, 0, 0) - from_hmsm(2, 59, 59, 1_000), TimeDelta::seconds(1));
+///            TimeDelta::try_milliseconds(1500).unwrap());
+/// assert_eq!(from_hmsm(3, 0, 59, 1_000) - from_hmsm(3, 0, 0, 0), TimeDelta::try_seconds(60).unwrap());
+/// assert_eq!(from_hmsm(3, 0, 0, 0) - from_hmsm(2, 59, 59, 1_000), TimeDelta::try_seconds(1).unwrap());
 /// assert_eq!(from_hmsm(3, 0, 59, 1_000) - from_hmsm(2, 59, 59, 1_000),
-///            TimeDelta::seconds(61));
+///            TimeDelta::try_seconds(61).unwrap());
 /// ```
 impl Sub<NaiveTime> for NaiveTime {
     type Output = TimeDelta;
diff --git a/src/offset/local/mod.rs b/src/offset/local/mod.rs
index b379b39e46..3b71a9a0ab 100644
--- a/src/offset/local/mod.rs
+++ b/src/offset/local/mod.rs
@@ -273,7 +273,7 @@ mod tests {
     #[cfg(windows)]
     use crate::offset::local::{lookup_with_dst_transitions, Transition};
     use crate::offset::TimeZone;
-    use crate::{Datelike, TimeDelta, Utc};
+    use crate::{Datelike, Days, Utc};
     #[cfg(windows)]
     use crate::{FixedOffset, LocalResult, NaiveDate, NaiveDateTime};
 
@@ -292,7 +292,7 @@ mod tests {
 
     #[test]
     fn verify_correct_offsets_distant_past() {
-        let distant_past = Local::now() - TimeDelta::days(365 * 500);
+        let distant_past = Local::now() - Days::new(365 * 500);
         let from_local = Local.from_local_datetime(&distant_past.naive_local()).unwrap();
         let from_utc = Local.from_utc_datetime(&distant_past.naive_utc());
 
@@ -305,7 +305,7 @@ mod tests {
 
     #[test]
     fn verify_correct_offsets_distant_future() {
-        let distant_future = Local::now() + TimeDelta::days(365 * 35000);
+        let distant_future = Local::now() + Days::new(365 * 35000);
         let from_local = Local.from_local_datetime(&distant_future.naive_local()).unwrap();
         let from_utc = Local.from_utc_datetime(&distant_future.naive_utc());
 
diff --git a/src/offset/local/windows.rs b/src/offset/local/windows.rs
index de48f0653c..e1ec682eee 100644
--- a/src/offset/local/windows.rs
+++ b/src/offset/local/windows.rs
@@ -256,7 +256,7 @@ mod tests {
             if let Some(our_result) = Local.from_local_datetime(&date).earliest() {
                 assert_eq!(from_local_time(&date), our_result);
             }
-            date += TimeDelta::hours(1);
+            date += TimeDelta::try_hours(1).unwrap();
         }
     }
 }
diff --git a/src/round.rs b/src/round.rs
index ef3e39d2ba..d9b1b9bc0e 100644
--- a/src/round.rs
+++ b/src/round.rs
@@ -127,11 +127,11 @@ pub trait DurationRound: Sized {
     ///     .and_local_timezone(Utc)
     ///     .unwrap();
     /// assert_eq!(
-    ///     dt.duration_round(TimeDelta::milliseconds(10)).unwrap().to_string(),
+    ///     dt.duration_round(TimeDelta::try_milliseconds(10).unwrap()).unwrap().to_string(),
     ///     "2018-01-11 12:00:00.150 UTC"
     /// );
     /// assert_eq!(
-    ///     dt.duration_round(TimeDelta::days(1)).unwrap().to_string(),
+    ///     dt.duration_round(TimeDelta::try_days(1).unwrap()).unwrap().to_string(),
     ///     "2018-01-12 00:00:00 UTC"
     /// );
     /// ```
@@ -149,11 +149,11 @@ pub trait DurationRound: Sized {
     ///     .and_local_timezone(Utc)
     ///     .unwrap();
     /// assert_eq!(
-    ///     dt.duration_trunc(TimeDelta::milliseconds(10)).unwrap().to_string(),
+    ///     dt.duration_trunc(TimeDelta::try_milliseconds(10).unwrap()).unwrap().to_string(),
     ///     "2018-01-11 12:00:00.150 UTC"
     /// );
     /// assert_eq!(
-    ///     dt.duration_trunc(TimeDelta::days(1)).unwrap().to_string(),
+    ///     dt.duration_trunc(TimeDelta::try_days(1).unwrap()).unwrap().to_string(),
     ///     "2018-01-11 00:00:00 UTC"
     /// );
     /// ```
@@ -268,7 +268,7 @@ pub enum RoundingError {
     ///     .unwrap();
     ///
     /// assert_eq!(
-    ///     dt.duration_round(TimeDelta::days(300 * 365)),
+    ///     dt.duration_round(TimeDelta::try_days(300 * 365).unwrap()),
     ///     Err(RoundingError::DurationExceedsLimit)
     /// );
     /// ```
@@ -280,7 +280,10 @@ pub enum RoundingError {
     /// # use chrono::{DurationRound, TimeDelta, RoundingError, TimeZone, Utc};
     /// let dt = Utc.with_ymd_and_hms(2300, 12, 12, 0, 0, 0).unwrap();
     ///
-    /// assert_eq!(dt.duration_round(TimeDelta::days(1)), Err(RoundingError::TimestampExceedsLimit),);
+    /// assert_eq!(
+    ///     dt.duration_round(TimeDelta::try_days(1).unwrap()),
+    ///     Err(RoundingError::TimestampExceedsLimit)
+    /// );
     /// ```
     TimestampExceedsLimit,
 }
@@ -461,7 +464,7 @@ mod tests {
         );
 
         assert_eq!(
-            dt.duration_round(TimeDelta::milliseconds(10)).unwrap().to_string(),
+            dt.duration_round(TimeDelta::try_milliseconds(10).unwrap()).unwrap().to_string(),
             "2016-12-31 23:59:59.180 UTC"
         );
 
@@ -475,7 +478,7 @@ mod tests {
             )
             .unwrap();
         assert_eq!(
-            dt.duration_round(TimeDelta::minutes(5)).unwrap().to_string(),
+            dt.duration_round(TimeDelta::try_minutes(5).unwrap()).unwrap().to_string(),
             "2012-12-12 18:25:00 UTC"
         );
         // round down
@@ -488,24 +491,24 @@ mod tests {
             )
             .unwrap();
         assert_eq!(
-            dt.duration_round(TimeDelta::minutes(5)).unwrap().to_string(),
+            dt.duration_round(TimeDelta::try_minutes(5).unwrap()).unwrap().to_string(),
             "2012-12-12 18:20:00 UTC"
         );
 
         assert_eq!(
-            dt.duration_round(TimeDelta::minutes(10)).unwrap().to_string(),
+            dt.duration_round(TimeDelta::try_minutes(10).unwrap()).unwrap().to_string(),
             "2012-12-12 18:20:00 UTC"
         );
         assert_eq!(
-            dt.duration_round(TimeDelta::minutes(30)).unwrap().to_string(),
+            dt.duration_round(TimeDelta::try_minutes(30).unwrap()).unwrap().to_string(),
             "2012-12-12 18:30:00 UTC"
         );
         assert_eq!(
-            dt.duration_round(TimeDelta::hours(1)).unwrap().to_string(),
+            dt.duration_round(TimeDelta::try_hours(1).unwrap()).unwrap().to_string(),
             "2012-12-12 18:00:00 UTC"
         );
         assert_eq!(
-            dt.duration_round(TimeDelta::days(1)).unwrap().to_string(),
+            dt.duration_round(TimeDelta::try_days(1).unwrap()).unwrap().to_string(),
             "2012-12-13 00:00:00 UTC"
         );
 
@@ -513,11 +516,11 @@ mod tests {
         let dt =
             FixedOffset::east_opt(3600).unwrap().with_ymd_and_hms(2020, 10, 27, 15, 0, 0).unwrap();
         assert_eq!(
-            dt.duration_round(TimeDelta::days(1)).unwrap().to_string(),
+            dt.duration_round(TimeDelta::try_days(1).unwrap()).unwrap().to_string(),
             "2020-10-28 00:00:00 +01:00"
         );
         assert_eq!(
-            dt.duration_round(TimeDelta::weeks(1)).unwrap().to_string(),
+            dt.duration_round(TimeDelta::try_weeks(1).unwrap()).unwrap().to_string(),
             "2020-10-29 00:00:00 +01:00"
         );
 
@@ -525,11 +528,11 @@ mod tests {
         let dt =
             FixedOffset::west_opt(3600).unwrap().with_ymd_and_hms(2020, 10, 27, 15, 0, 0).unwrap();
         assert_eq!(
-            dt.duration_round(TimeDelta::days(1)).unwrap().to_string(),
+            dt.duration_round(TimeDelta::try_days(1).unwrap()).unwrap().to_string(),
             "2020-10-28 00:00:00 -01:00"
         );
         assert_eq!(
-            dt.duration_round(TimeDelta::weeks(1)).unwrap().to_string(),
+            dt.duration_round(TimeDelta::try_weeks(1).unwrap()).unwrap().to_string(),
             "2020-10-29 00:00:00 -01:00"
         );
     }
@@ -552,7 +555,7 @@ mod tests {
         );
 
         assert_eq!(
-            dt.duration_round(TimeDelta::milliseconds(10)).unwrap().to_string(),
+            dt.duration_round(TimeDelta::try_milliseconds(10).unwrap()).unwrap().to_string(),
             "2016-12-31 23:59:59.180"
         );
 
@@ -567,7 +570,7 @@ mod tests {
             .unwrap()
             .naive_utc();
         assert_eq!(
-            dt.duration_round(TimeDelta::minutes(5)).unwrap().to_string(),
+            dt.duration_round(TimeDelta::try_minutes(5).unwrap()).unwrap().to_string(),
             "2012-12-12 18:25:00"
         );
         // round down
@@ -581,24 +584,24 @@ mod tests {
             .unwrap()
             .naive_utc();
         assert_eq!(
-            dt.duration_round(TimeDelta::minutes(5)).unwrap().to_string(),
+            dt.duration_round(TimeDelta::try_minutes(5).unwrap()).unwrap().to_string(),
             "2012-12-12 18:20:00"
         );
 
         assert_eq!(
-            dt.duration_round(TimeDelta::minutes(10)).unwrap().to_string(),
+            dt.duration_round(TimeDelta::try_minutes(10).unwrap()).unwrap().to_string(),
             "2012-12-12 18:20:00"
         );
         assert_eq!(
-            dt.duration_round(TimeDelta::minutes(30)).unwrap().to_string(),
+            dt.duration_round(TimeDelta::try_minutes(30).unwrap()).unwrap().to_string(),
             "2012-12-12 18:30:00"
         );
         assert_eq!(
-            dt.duration_round(TimeDelta::hours(1)).unwrap().to_string(),
+            dt.duration_round(TimeDelta::try_hours(1).unwrap()).unwrap().to_string(),
             "2012-12-12 18:00:00"
         );
         assert_eq!(
-            dt.duration_round(TimeDelta::days(1)).unwrap().to_string(),
+            dt.duration_round(TimeDelta::try_days(1).unwrap()).unwrap().to_string(),
             "2012-12-13 00:00:00"
         );
     }
@@ -607,7 +610,7 @@ mod tests {
     fn test_duration_round_pre_epoch() {
         let dt = Utc.with_ymd_and_hms(1969, 12, 12, 12, 12, 12).unwrap();
         assert_eq!(
-            dt.duration_round(TimeDelta::minutes(10)).unwrap().to_string(),
+            dt.duration_round(TimeDelta::try_minutes(10).unwrap()).unwrap().to_string(),
             "1969-12-12 12:10:00 UTC"
         );
     }
@@ -624,7 +627,7 @@ mod tests {
             .unwrap();
 
         assert_eq!(
-            dt.duration_trunc(TimeDelta::milliseconds(10)).unwrap().to_string(),
+            dt.duration_trunc(TimeDelta::try_milliseconds(10).unwrap()).unwrap().to_string(),
             "2016-12-31 23:59:59.170 UTC"
         );
 
@@ -638,7 +641,7 @@ mod tests {
             )
             .unwrap();
         assert_eq!(
-            dt.duration_trunc(TimeDelta::minutes(5)).unwrap().to_string(),
+            dt.duration_trunc(TimeDelta::try_minutes(5).unwrap()).unwrap().to_string(),
             "2012-12-12 18:20:00 UTC"
         );
         // would round down
@@ -651,23 +654,23 @@ mod tests {
             )
             .unwrap();
         assert_eq!(
-            dt.duration_trunc(TimeDelta::minutes(5)).unwrap().to_string(),
+            dt.duration_trunc(TimeDelta::try_minutes(5).unwrap()).unwrap().to_string(),
             "2012-12-12 18:20:00 UTC"
         );
         assert_eq!(
-            dt.duration_trunc(TimeDelta::minutes(10)).unwrap().to_string(),
+            dt.duration_trunc(TimeDelta::try_minutes(10).unwrap()).unwrap().to_string(),
             "2012-12-12 18:20:00 UTC"
         );
         assert_eq!(
-            dt.duration_trunc(TimeDelta::minutes(30)).unwrap().to_string(),
+            dt.duration_trunc(TimeDelta::try_minutes(30).unwrap()).unwrap().to_string(),
             "2012-12-12 18:00:00 UTC"
         );
         assert_eq!(
-            dt.duration_trunc(TimeDelta::hours(1)).unwrap().to_string(),
+            dt.duration_trunc(TimeDelta::try_hours(1).unwrap()).unwrap().to_string(),
             "2012-12-12 18:00:00 UTC"
         );
         assert_eq!(
-            dt.duration_trunc(TimeDelta::days(1)).unwrap().to_string(),
+            dt.duration_trunc(TimeDelta::try_days(1).unwrap()).unwrap().to_string(),
             "2012-12-12 00:00:00 UTC"
         );
 
@@ -675,11 +678,11 @@ mod tests {
         let dt =
             FixedOffset::east_opt(3600).unwrap().with_ymd_and_hms(2020, 10, 27, 15, 0, 0).unwrap();
         assert_eq!(
-            dt.duration_trunc(TimeDelta::days(1)).unwrap().to_string(),
+            dt.duration_trunc(TimeDelta::try_days(1).unwrap()).unwrap().to_string(),
             "2020-10-27 00:00:00 +01:00"
         );
         assert_eq!(
-            dt.duration_trunc(TimeDelta::weeks(1)).unwrap().to_string(),
+            dt.duration_trunc(TimeDelta::try_weeks(1).unwrap()).unwrap().to_string(),
             "2020-10-22 00:00:00 +01:00"
         );
 
@@ -687,11 +690,11 @@ mod tests {
         let dt =
             FixedOffset::west_opt(3600).unwrap().with_ymd_and_hms(2020, 10, 27, 15, 0, 0).unwrap();
         assert_eq!(
-            dt.duration_trunc(TimeDelta::days(1)).unwrap().to_string(),
+            dt.duration_trunc(TimeDelta::try_days(1).unwrap()).unwrap().to_string(),
             "2020-10-27 00:00:00 -01:00"
         );
         assert_eq!(
-            dt.duration_trunc(TimeDelta::weeks(1)).unwrap().to_string(),
+            dt.duration_trunc(TimeDelta::try_weeks(1).unwrap()).unwrap().to_string(),
             "2020-10-22 00:00:00 -01:00"
         );
     }
@@ -709,7 +712,7 @@ mod tests {
             .naive_utc();
 
         assert_eq!(
-            dt.duration_trunc(TimeDelta::milliseconds(10)).unwrap().to_string(),
+            dt.duration_trunc(TimeDelta::try_milliseconds(10).unwrap()).unwrap().to_string(),
             "2016-12-31 23:59:59.170"
         );
 
@@ -724,7 +727,7 @@ mod tests {
             .unwrap()
             .naive_utc();
         assert_eq!(
-            dt.duration_trunc(TimeDelta::minutes(5)).unwrap().to_string(),
+            dt.duration_trunc(TimeDelta::try_minutes(5).unwrap()).unwrap().to_string(),
             "2012-12-12 18:20:00"
         );
         // would round down
@@ -738,23 +741,23 @@ mod tests {
             .unwrap()
             .naive_utc();
         assert_eq!(
-            dt.duration_trunc(TimeDelta::minutes(5)).unwrap().to_string(),
+            dt.duration_trunc(TimeDelta::try_minutes(5).unwrap()).unwrap().to_string(),
             "2012-12-12 18:20:00"
         );
         assert_eq!(
-            dt.duration_trunc(TimeDelta::minutes(10)).unwrap().to_string(),
+            dt.duration_trunc(TimeDelta::try_minutes(10).unwrap()).unwrap().to_string(),
             "2012-12-12 18:20:00"
         );
         assert_eq!(
-            dt.duration_trunc(TimeDelta::minutes(30)).unwrap().to_string(),
+            dt.duration_trunc(TimeDelta::try_minutes(30).unwrap()).unwrap().to_string(),
             "2012-12-12 18:00:00"
         );
         assert_eq!(
-            dt.duration_trunc(TimeDelta::hours(1)).unwrap().to_string(),
+            dt.duration_trunc(TimeDelta::try_hours(1).unwrap()).unwrap().to_string(),
             "2012-12-12 18:00:00"
         );
         assert_eq!(
-            dt.duration_trunc(TimeDelta::days(1)).unwrap().to_string(),
+            dt.duration_trunc(TimeDelta::try_days(1).unwrap()).unwrap().to_string(),
             "2012-12-12 00:00:00"
         );
     }
@@ -763,7 +766,7 @@ mod tests {
     fn test_duration_trunc_pre_epoch() {
         let dt = Utc.with_ymd_and_hms(1969, 12, 12, 12, 12, 12).unwrap();
         assert_eq!(
-            dt.duration_trunc(TimeDelta::minutes(10)).unwrap().to_string(),
+            dt.duration_trunc(TimeDelta::try_minutes(10).unwrap()).unwrap().to_string(),
             "1969-12-12 12:10:00 UTC"
         );
     }
@@ -785,7 +788,7 @@ mod tests {
 
     #[test]
     fn test_duration_trunc_close_to_epoch() {
-        let span = TimeDelta::minutes(15);
+        let span = TimeDelta::try_minutes(15).unwrap();
 
         let dt = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap().and_hms_opt(0, 0, 15).unwrap();
         assert_eq!(dt.duration_trunc(span).unwrap().to_string(), "1970-01-01 00:00:00");
@@ -796,7 +799,7 @@ mod tests {
 
     #[test]
     fn test_duration_round_close_to_epoch() {
-        let span = TimeDelta::minutes(15);
+        let span = TimeDelta::try_minutes(15).unwrap();
 
         let dt = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap().and_hms_opt(0, 0, 15).unwrap();
         assert_eq!(dt.duration_round(span).unwrap().to_string(), "1970-01-01 00:00:00");
diff --git a/src/time_delta.rs b/src/time_delta.rs
index e87bfa404e..1d05037fb3 100644
--- a/src/time_delta.rs
+++ b/src/time_delta.rs
@@ -102,13 +102,14 @@ impl TimeDelta {
     /// Panics when the duration is out of bounds.
     #[inline]
     #[must_use]
+    #[deprecated(since = "0.4.35", note = "Use `TimeDelta::try_weeks` instead")]
     pub const fn weeks(weeks: i64) -> TimeDelta {
         expect!(TimeDelta::try_weeks(weeks), "TimeDelta::weeks out of bounds")
     }
 
     /// Makes a new `TimeDelta` with the given number of weeks.
     ///
-    /// Equivalent to `TimeDelta::seconds(weeks * 7 * 24 * 60 * 60)` with
+    /// Equivalent to `TimeDelta::try_seconds(weeks * 7 * 24 * 60 * 60)` with
     /// overflow checks.
     ///
     /// # Errors
@@ -129,13 +130,14 @@ impl TimeDelta {
     /// Panics when the `TimeDelta` would be out of bounds.
     #[inline]
     #[must_use]
+    #[deprecated(since = "0.4.35", note = "Use `TimeDelta::try_days` instead")]
     pub const fn days(days: i64) -> TimeDelta {
         expect!(TimeDelta::try_days(days), "TimeDelta::days out of bounds")
     }
 
     /// Makes a new `TimeDelta` with the given number of days.
     ///
-    /// Equivalent to `TimeDelta::seconds(days * 24 * 60 * 60)` with overflow
+    /// Equivalent to `TimeDelta::try_seconds(days * 24 * 60 * 60)` with overflow
     /// checks.
     ///
     /// # Errors
@@ -155,13 +157,14 @@ impl TimeDelta {
     /// Panics when the `TimeDelta` would be out of bounds.
     #[inline]
     #[must_use]
+    #[deprecated(since = "0.4.35", note = "Use `TimeDelta::try_hours` instead")]
     pub const fn hours(hours: i64) -> TimeDelta {
         expect!(TimeDelta::try_hours(hours), "TimeDelta::hours out of bounds")
     }
 
     /// Makes a new `TimeDelta` with the given number of hours.
     ///
-    /// Equivalent to `TimeDelta::seconds(hours * 60 * 60)` with overflow checks.
+    /// Equivalent to `TimeDelta::try_seconds(hours * 60 * 60)` with overflow checks.
     ///
     /// # Errors
     ///
@@ -180,13 +183,14 @@ impl TimeDelta {
     /// Panics when the `TimeDelta` would be out of bounds.
     #[inline]
     #[must_use]
+    #[deprecated(since = "0.4.35", note = "Use `TimeDelta::try_minutes` instead")]
     pub const fn minutes(minutes: i64) -> TimeDelta {
         expect!(TimeDelta::try_minutes(minutes), "TimeDelta::minutes out of bounds")
     }
 
     /// Makes a new `TimeDelta` with the given number of minutes.
     ///
-    /// Equivalent to `TimeDelta::seconds(minutes * 60)` with overflow checks.
+    /// Equivalent to `TimeDelta::try_seconds(minutes * 60)` with overflow checks.
     ///
     /// # Errors
     ///
@@ -204,6 +208,7 @@ impl TimeDelta {
     /// (in this context, this is the same as `i64::MIN / 1_000` due to rounding).
     #[inline]
     #[must_use]
+    #[deprecated(since = "0.4.35", note = "Use `TimeDelta::try_seconds` instead")]
     pub const fn seconds(seconds: i64) -> TimeDelta {
         expect!(TimeDelta::try_seconds(seconds), "TimeDelta::seconds out of bounds")
     }
@@ -227,6 +232,7 @@ impl TimeDelta {
     /// Panics when the `TimeDelta` would be out of bounds, i.e. when `milliseconds` is more than
     /// `i64::MAX` or less than `-i64::MAX`. Notably, this is not the same as `i64::MIN`.
     #[inline]
+    #[deprecated(since = "0.4.35", note = "Use `TimeDelta::try_milliseconds` instead")]
     pub const fn milliseconds(milliseconds: i64) -> TimeDelta {
         expect!(TimeDelta::try_milliseconds(milliseconds), "TimeDelta::milliseconds out of bounds")
     }
@@ -616,64 +622,59 @@ impl arbitrary::Arbitrary<'_> for TimeDelta {
 mod tests {
     use super::OutOfRangeError;
     use super::{TimeDelta, MAX, MIN};
+    use crate::expect;
     use core::time::Duration;
 
     #[test]
     fn test_duration() {
-        assert!(TimeDelta::seconds(1) != TimeDelta::zero());
-        assert_eq!(TimeDelta::seconds(1) + TimeDelta::seconds(2), TimeDelta::seconds(3));
-        assert_eq!(
-            TimeDelta::seconds(86_399) + TimeDelta::seconds(4),
-            TimeDelta::days(1) + TimeDelta::seconds(3)
-        );
-        assert_eq!(TimeDelta::days(10) - TimeDelta::seconds(1000), TimeDelta::seconds(863_000));
+        let days = |d| TimeDelta::try_days(d).unwrap();
+        let seconds = |s| TimeDelta::try_seconds(s).unwrap();
+
+        assert!(seconds(1) != TimeDelta::zero());
+        assert_eq!(seconds(1) + seconds(2), seconds(3));
+        assert_eq!(seconds(86_399) + seconds(4), days(1) + seconds(3));
+        assert_eq!(days(10) - seconds(1000), seconds(863_000));
+        assert_eq!(days(10) - seconds(1_000_000), seconds(-136_000));
         assert_eq!(
-            TimeDelta::days(10) - TimeDelta::seconds(1_000_000),
-            TimeDelta::seconds(-136_000)
-        );
-        assert_eq!(
-            TimeDelta::days(2) + TimeDelta::seconds(86_399) + TimeDelta::nanoseconds(1_234_567_890),
-            TimeDelta::days(3) + TimeDelta::nanoseconds(234_567_890)
-        );
-        assert_eq!(-TimeDelta::days(3), TimeDelta::days(-3));
-        assert_eq!(
-            -(TimeDelta::days(3) + TimeDelta::seconds(70)),
-            TimeDelta::days(-4) + TimeDelta::seconds(86_400 - 70)
+            days(2) + seconds(86_399) + TimeDelta::nanoseconds(1_234_567_890),
+            days(3) + TimeDelta::nanoseconds(234_567_890)
         );
+        assert_eq!(-days(3), days(-3));
+        assert_eq!(-(days(3) + seconds(70)), days(-4) + seconds(86_400 - 70));
 
         let mut d = TimeDelta::default();
-        d += TimeDelta::minutes(1);
-        d -= TimeDelta::seconds(30);
-        assert_eq!(d, TimeDelta::seconds(30));
+        d += TimeDelta::try_minutes(1).unwrap();
+        d -= seconds(30);
+        assert_eq!(d, seconds(30));
     }
 
     #[test]
     fn test_duration_num_days() {
         assert_eq!(TimeDelta::zero().num_days(), 0);
-        assert_eq!(TimeDelta::days(1).num_days(), 1);
-        assert_eq!(TimeDelta::days(-1).num_days(), -1);
-        assert_eq!(TimeDelta::seconds(86_399).num_days(), 0);
-        assert_eq!(TimeDelta::seconds(86_401).num_days(), 1);
-        assert_eq!(TimeDelta::seconds(-86_399).num_days(), 0);
-        assert_eq!(TimeDelta::seconds(-86_401).num_days(), -1);
-        assert_eq!(TimeDelta::days(i32::MAX as i64).num_days(), i32::MAX as i64);
-        assert_eq!(TimeDelta::days(i32::MIN as i64).num_days(), i32::MIN as i64);
+        assert_eq!(TimeDelta::try_days(1).unwrap().num_days(), 1);
+        assert_eq!(TimeDelta::try_days(-1).unwrap().num_days(), -1);
+        assert_eq!(TimeDelta::try_seconds(86_399).unwrap().num_days(), 0);
+        assert_eq!(TimeDelta::try_seconds(86_401).unwrap().num_days(), 1);
+        assert_eq!(TimeDelta::try_seconds(-86_399).unwrap().num_days(), 0);
+        assert_eq!(TimeDelta::try_seconds(-86_401).unwrap().num_days(), -1);
+        assert_eq!(TimeDelta::try_days(i32::MAX as i64).unwrap().num_days(), i32::MAX as i64);
+        assert_eq!(TimeDelta::try_days(i32::MIN as i64).unwrap().num_days(), i32::MIN as i64);
     }
 
     #[test]
     fn test_duration_num_seconds() {
         assert_eq!(TimeDelta::zero().num_seconds(), 0);
-        assert_eq!(TimeDelta::seconds(1).num_seconds(), 1);
-        assert_eq!(TimeDelta::seconds(-1).num_seconds(), -1);
-        assert_eq!(TimeDelta::milliseconds(999).num_seconds(), 0);
-        assert_eq!(TimeDelta::milliseconds(1001).num_seconds(), 1);
-        assert_eq!(TimeDelta::milliseconds(-999).num_seconds(), 0);
-        assert_eq!(TimeDelta::milliseconds(-1001).num_seconds(), -1);
+        assert_eq!(TimeDelta::try_seconds(1).unwrap().num_seconds(), 1);
+        assert_eq!(TimeDelta::try_seconds(-1).unwrap().num_seconds(), -1);
+        assert_eq!(TimeDelta::try_milliseconds(999).unwrap().num_seconds(), 0);
+        assert_eq!(TimeDelta::try_milliseconds(1001).unwrap().num_seconds(), 1);
+        assert_eq!(TimeDelta::try_milliseconds(-999).unwrap().num_seconds(), 0);
+        assert_eq!(TimeDelta::try_milliseconds(-1001).unwrap().num_seconds(), -1);
     }
 
     #[test]
     fn test_duration_seconds_max_allowed() {
-        let duration = TimeDelta::seconds(i64::MAX / 1_000);
+        let duration = TimeDelta::try_seconds(i64::MAX / 1_000).unwrap();
         assert_eq!(duration.num_seconds(), i64::MAX / 1_000);
         assert_eq!(
             duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
@@ -687,6 +688,7 @@ mod tests {
     }
 
     #[test]
+    #[allow(deprecated)]
     #[should_panic(expected = "TimeDelta::seconds out of bounds")]
     fn test_duration_seconds_max_overflow_panic() {
         let _ = TimeDelta::seconds(i64::MAX / 1_000 + 1);
@@ -694,7 +696,7 @@ mod tests {
 
     #[test]
     fn test_duration_seconds_min_allowed() {
-        let duration = TimeDelta::seconds(i64::MIN / 1_000); // Same as -i64::MAX / 1_000 due to rounding
+        let duration = TimeDelta::try_seconds(i64::MIN / 1_000).unwrap(); // Same as -i64::MAX / 1_000 due to rounding
         assert_eq!(duration.num_seconds(), i64::MIN / 1_000); // Same as -i64::MAX / 1_000 due to rounding
         assert_eq!(
             duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
@@ -708,6 +710,7 @@ mod tests {
     }
 
     #[test]
+    #[allow(deprecated)]
     #[should_panic(expected = "TimeDelta::seconds out of bounds")]
     fn test_duration_seconds_min_underflow_panic() {
         let _ = TimeDelta::seconds(-i64::MAX / 1_000 - 1);
@@ -716,8 +719,8 @@ mod tests {
     #[test]
     fn test_duration_num_milliseconds() {
         assert_eq!(TimeDelta::zero().num_milliseconds(), 0);
-        assert_eq!(TimeDelta::milliseconds(1).num_milliseconds(), 1);
-        assert_eq!(TimeDelta::milliseconds(-1).num_milliseconds(), -1);
+        assert_eq!(TimeDelta::try_milliseconds(1).unwrap().num_milliseconds(), 1);
+        assert_eq!(TimeDelta::try_milliseconds(-1).unwrap().num_milliseconds(), -1);
         assert_eq!(TimeDelta::microseconds(999).num_milliseconds(), 0);
         assert_eq!(TimeDelta::microseconds(1001).num_milliseconds(), 1);
         assert_eq!(TimeDelta::microseconds(-999).num_milliseconds(), 0);
@@ -728,7 +731,7 @@ mod tests {
     fn test_duration_milliseconds_max_allowed() {
         // The maximum number of milliseconds acceptable through the constructor is
         // equal to the number that can be stored in a TimeDelta.
-        let duration = TimeDelta::milliseconds(i64::MAX);
+        let duration = TimeDelta::try_milliseconds(i64::MAX).unwrap();
         assert_eq!(duration.num_milliseconds(), i64::MAX);
         assert_eq!(
             duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
@@ -740,8 +743,9 @@ mod tests {
     fn test_duration_milliseconds_max_overflow() {
         // Here we ensure that trying to add one millisecond to the maximum storable
         // value will fail.
-        assert!(TimeDelta::milliseconds(i64::MAX)
-            .checked_add(&TimeDelta::milliseconds(1))
+        assert!(TimeDelta::try_milliseconds(i64::MAX)
+            .unwrap()
+            .checked_add(&TimeDelta::try_milliseconds(1).unwrap())
             .is_none());
     }
 
@@ -750,7 +754,7 @@ mod tests {
         // The minimum number of milliseconds acceptable through the constructor is
         // not equal to the number that can be stored in a TimeDelta - there is a
         // difference of one (i64::MIN vs -i64::MAX).
-        let duration = TimeDelta::milliseconds(-i64::MAX);
+        let duration = TimeDelta::try_milliseconds(-i64::MAX).unwrap();
         assert_eq!(duration.num_milliseconds(), -i64::MAX);
         assert_eq!(
             duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
@@ -762,12 +766,14 @@ mod tests {
     fn test_duration_milliseconds_min_underflow() {
         // Here we ensure that trying to subtract one millisecond from the minimum
         // storable value will fail.
-        assert!(TimeDelta::milliseconds(-i64::MAX)
-            .checked_sub(&TimeDelta::milliseconds(1))
+        assert!(TimeDelta::try_milliseconds(-i64::MAX)
+            .unwrap()
+            .checked_sub(&TimeDelta::try_milliseconds(1).unwrap())
             .is_none());
     }
 
     #[test]
+    #[allow(deprecated)]
     #[should_panic(expected = "TimeDelta::milliseconds out of bounds")]
     fn test_duration_milliseconds_min_underflow_panic() {
         // Here we ensure that trying to create a value one millisecond below the
@@ -790,15 +796,21 @@ mod tests {
         // overflow checks
         const MICROS_PER_DAY: i64 = 86_400_000_000;
         assert_eq!(
-            TimeDelta::days(i64::MAX / MICROS_PER_DAY).num_microseconds(),
+            TimeDelta::try_days(i64::MAX / MICROS_PER_DAY).unwrap().num_microseconds(),
             Some(i64::MAX / MICROS_PER_DAY * MICROS_PER_DAY)
         );
         assert_eq!(
-            TimeDelta::days(-i64::MAX / MICROS_PER_DAY).num_microseconds(),
+            TimeDelta::try_days(-i64::MAX / MICROS_PER_DAY).unwrap().num_microseconds(),
             Some(-i64::MAX / MICROS_PER_DAY * MICROS_PER_DAY)
         );
-        assert_eq!(TimeDelta::days(i64::MAX / MICROS_PER_DAY + 1).num_microseconds(), None);
-        assert_eq!(TimeDelta::days(-i64::MAX / MICROS_PER_DAY - 1).num_microseconds(), None);
+        assert_eq!(
+            TimeDelta::try_days(i64::MAX / MICROS_PER_DAY + 1).unwrap().num_microseconds(),
+            None
+        );
+        assert_eq!(
+            TimeDelta::try_days(-i64::MAX / MICROS_PER_DAY - 1).unwrap().num_microseconds(),
+            None
+        );
     }
     #[test]
     fn test_duration_microseconds_max_allowed() {
@@ -815,7 +827,7 @@ mod tests {
         // microseconds by creating a TimeDelta with the maximum number of
         // milliseconds and then checking that the number of microseconds matches
         // the storage limit.
-        let duration = TimeDelta::milliseconds(i64::MAX);
+        let duration = TimeDelta::try_milliseconds(i64::MAX).unwrap();
         assert!(duration.num_microseconds().is_none());
         assert_eq!(
             duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
@@ -834,7 +846,8 @@ mod tests {
         );
         // Here we ensure that trying to add one microsecond to the maximum storable
         // value will fail.
-        assert!(TimeDelta::milliseconds(i64::MAX)
+        assert!(TimeDelta::try_milliseconds(i64::MAX)
+            .unwrap()
             .checked_add(&TimeDelta::microseconds(1))
             .is_none());
     }
@@ -853,7 +866,7 @@ mod tests {
         // microseconds by creating a TimeDelta with the minimum number of
         // milliseconds and then checking that the number of microseconds matches
         // the storage limit.
-        let duration = TimeDelta::milliseconds(-i64::MAX);
+        let duration = TimeDelta::try_milliseconds(-i64::MAX).unwrap();
         assert!(duration.num_microseconds().is_none());
         assert_eq!(
             duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
@@ -872,7 +885,8 @@ mod tests {
         );
         // Here we ensure that trying to subtract one microsecond from the minimum
         // storable value will fail.
-        assert!(TimeDelta::milliseconds(-i64::MAX)
+        assert!(TimeDelta::try_milliseconds(-i64::MAX)
+            .unwrap()
             .checked_sub(&TimeDelta::microseconds(1))
             .is_none());
     }
@@ -886,15 +900,21 @@ mod tests {
         // overflow checks
         const NANOS_PER_DAY: i64 = 86_400_000_000_000;
         assert_eq!(
-            TimeDelta::days(i64::MAX / NANOS_PER_DAY).num_nanoseconds(),
+            TimeDelta::try_days(i64::MAX / NANOS_PER_DAY).unwrap().num_nanoseconds(),
             Some(i64::MAX / NANOS_PER_DAY * NANOS_PER_DAY)
         );
         assert_eq!(
-            TimeDelta::days(-i64::MAX / NANOS_PER_DAY).num_nanoseconds(),
+            TimeDelta::try_days(-i64::MAX / NANOS_PER_DAY).unwrap().num_nanoseconds(),
             Some(-i64::MAX / NANOS_PER_DAY * NANOS_PER_DAY)
         );
-        assert_eq!(TimeDelta::days(i64::MAX / NANOS_PER_DAY + 1).num_nanoseconds(), None);
-        assert_eq!(TimeDelta::days(-i64::MAX / NANOS_PER_DAY - 1).num_nanoseconds(), None);
+        assert_eq!(
+            TimeDelta::try_days(i64::MAX / NANOS_PER_DAY + 1).unwrap().num_nanoseconds(),
+            None
+        );
+        assert_eq!(
+            TimeDelta::try_days(-i64::MAX / NANOS_PER_DAY - 1).unwrap().num_nanoseconds(),
+            None
+        );
     }
     #[test]
     fn test_duration_nanoseconds_max_allowed() {
@@ -910,7 +930,7 @@ mod tests {
         // Here we create a TimeDelta with the maximum possible number of nanoseconds
         // by creating a TimeDelta with the maximum number of milliseconds and then
         // checking that the number of nanoseconds matches the storage limit.
-        let duration = TimeDelta::milliseconds(i64::MAX);
+        let duration = TimeDelta::try_milliseconds(i64::MAX).unwrap();
         assert!(duration.num_nanoseconds().is_none());
         assert_eq!(
             duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
@@ -930,7 +950,8 @@ mod tests {
         );
         // Here we ensure that trying to add one nanosecond to the maximum storable
         // value will fail.
-        assert!(TimeDelta::milliseconds(i64::MAX)
+        assert!(TimeDelta::try_milliseconds(i64::MAX)
+            .unwrap()
             .checked_add(&TimeDelta::nanoseconds(1))
             .is_none());
     }
@@ -949,7 +970,7 @@ mod tests {
         // Here we create a TimeDelta with the minimum possible number of nanoseconds
         // by creating a TimeDelta with the minimum number of milliseconds and then
         // checking that the number of nanoseconds matches the storage limit.
-        let duration = TimeDelta::milliseconds(-i64::MAX);
+        let duration = TimeDelta::try_milliseconds(-i64::MAX).unwrap();
         assert!(duration.num_nanoseconds().is_none());
         assert_eq!(
             duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
@@ -969,7 +990,8 @@ mod tests {
         );
         // Here we ensure that trying to subtract one nanosecond from the minimum
         // storable value will fail.
-        assert!(TimeDelta::milliseconds(-i64::MAX)
+        assert!(TimeDelta::try_milliseconds(-i64::MAX)
+            .unwrap()
             .checked_sub(&TimeDelta::nanoseconds(1))
             .is_none());
     }
@@ -980,7 +1002,7 @@ mod tests {
             MAX.secs as i128 * 1_000_000_000 + MAX.nanos as i128,
             i64::MAX as i128 * 1_000_000
         );
-        assert_eq!(MAX, TimeDelta::milliseconds(i64::MAX));
+        assert_eq!(MAX, TimeDelta::try_milliseconds(i64::MAX).unwrap());
         assert_eq!(MAX.num_milliseconds(), i64::MAX);
         assert_eq!(MAX.num_microseconds(), None);
         assert_eq!(MAX.num_nanoseconds(), None);
@@ -992,7 +1014,7 @@ mod tests {
             MIN.secs as i128 * 1_000_000_000 + MIN.nanos as i128,
             -i64::MAX as i128 * 1_000_000
         );
-        assert_eq!(MIN, TimeDelta::milliseconds(-i64::MAX));
+        assert_eq!(MIN, TimeDelta::try_milliseconds(-i64::MAX).unwrap());
         assert_eq!(MIN.num_milliseconds(), -i64::MAX);
         assert_eq!(MIN.num_microseconds(), None);
         assert_eq!(MIN.num_nanoseconds(), None);
@@ -1000,67 +1022,65 @@ mod tests {
 
     #[test]
     fn test_duration_ord() {
-        assert!(TimeDelta::milliseconds(1) < TimeDelta::milliseconds(2));
-        assert!(TimeDelta::milliseconds(2) > TimeDelta::milliseconds(1));
-        assert!(TimeDelta::milliseconds(-1) > TimeDelta::milliseconds(-2));
-        assert!(TimeDelta::milliseconds(-2) < TimeDelta::milliseconds(-1));
-        assert!(TimeDelta::milliseconds(-1) < TimeDelta::milliseconds(1));
-        assert!(TimeDelta::milliseconds(1) > TimeDelta::milliseconds(-1));
-        assert!(TimeDelta::milliseconds(0) < TimeDelta::milliseconds(1));
-        assert!(TimeDelta::milliseconds(0) > TimeDelta::milliseconds(-1));
-        assert!(TimeDelta::milliseconds(1_001) < TimeDelta::milliseconds(1_002));
-        assert!(TimeDelta::milliseconds(-1_001) > TimeDelta::milliseconds(-1_002));
+        let milliseconds = |ms| TimeDelta::try_milliseconds(ms).unwrap();
+
+        assert!(milliseconds(1) < milliseconds(2));
+        assert!(milliseconds(2) > milliseconds(1));
+        assert!(milliseconds(-1) > milliseconds(-2));
+        assert!(milliseconds(-2) < milliseconds(-1));
+        assert!(milliseconds(-1) < milliseconds(1));
+        assert!(milliseconds(1) > milliseconds(-1));
+        assert!(milliseconds(0) < milliseconds(1));
+        assert!(milliseconds(0) > milliseconds(-1));
+        assert!(milliseconds(1_001) < milliseconds(1_002));
+        assert!(milliseconds(-1_001) > milliseconds(-1_002));
         assert!(TimeDelta::nanoseconds(1_234_567_890) < TimeDelta::nanoseconds(1_234_567_891));
         assert!(TimeDelta::nanoseconds(-1_234_567_890) > TimeDelta::nanoseconds(-1_234_567_891));
-        assert!(TimeDelta::milliseconds(i64::MAX) > TimeDelta::milliseconds(i64::MAX - 1));
-        assert!(TimeDelta::milliseconds(-i64::MAX) < TimeDelta::milliseconds(-i64::MAX + 1));
+        assert!(milliseconds(i64::MAX) > milliseconds(i64::MAX - 1));
+        assert!(milliseconds(-i64::MAX) < milliseconds(-i64::MAX + 1));
     }
 
     #[test]
     fn test_duration_checked_ops() {
+        let milliseconds = |ms| TimeDelta::try_milliseconds(ms).unwrap();
+
         assert_eq!(
-            TimeDelta::milliseconds(i64::MAX).checked_add(&TimeDelta::milliseconds(0)),
-            Some(TimeDelta::milliseconds(i64::MAX))
+            milliseconds(i64::MAX).checked_add(&milliseconds(0)),
+            Some(milliseconds(i64::MAX))
         );
         assert_eq!(
-            TimeDelta::milliseconds(i64::MAX - 1).checked_add(&TimeDelta::microseconds(999)),
-            Some(TimeDelta::milliseconds(i64::MAX - 2) + TimeDelta::microseconds(1999))
+            milliseconds(i64::MAX - 1).checked_add(&TimeDelta::microseconds(999)),
+            Some(milliseconds(i64::MAX - 2) + TimeDelta::microseconds(1999))
         );
-        assert!(TimeDelta::milliseconds(i64::MAX)
-            .checked_add(&TimeDelta::microseconds(1000))
-            .is_none());
-        assert!(TimeDelta::milliseconds(i64::MAX)
-            .checked_add(&TimeDelta::nanoseconds(1))
-            .is_none());
+        assert!(milliseconds(i64::MAX).checked_add(&TimeDelta::microseconds(1000)).is_none());
+        assert!(milliseconds(i64::MAX).checked_add(&TimeDelta::nanoseconds(1)).is_none());
 
         assert_eq!(
-            TimeDelta::milliseconds(-i64::MAX).checked_sub(&TimeDelta::milliseconds(0)),
-            Some(TimeDelta::milliseconds(-i64::MAX))
+            milliseconds(-i64::MAX).checked_sub(&milliseconds(0)),
+            Some(milliseconds(-i64::MAX))
         );
         assert_eq!(
-            TimeDelta::milliseconds(-i64::MAX + 1).checked_sub(&TimeDelta::microseconds(999)),
-            Some(TimeDelta::milliseconds(-i64::MAX + 2) - TimeDelta::microseconds(1999))
+            milliseconds(-i64::MAX + 1).checked_sub(&TimeDelta::microseconds(999)),
+            Some(milliseconds(-i64::MAX + 2) - TimeDelta::microseconds(1999))
         );
-        assert!(TimeDelta::milliseconds(-i64::MAX)
-            .checked_sub(&TimeDelta::milliseconds(1))
-            .is_none());
-        assert!(TimeDelta::milliseconds(-i64::MAX)
-            .checked_sub(&TimeDelta::nanoseconds(1))
-            .is_none());
+        assert!(milliseconds(-i64::MAX).checked_sub(&milliseconds(1)).is_none());
+        assert!(milliseconds(-i64::MAX).checked_sub(&TimeDelta::nanoseconds(1)).is_none());
     }
 
     #[test]
     fn test_duration_abs() {
-        assert_eq!(TimeDelta::milliseconds(1300).abs(), TimeDelta::milliseconds(1300));
-        assert_eq!(TimeDelta::milliseconds(1000).abs(), TimeDelta::milliseconds(1000));
-        assert_eq!(TimeDelta::milliseconds(300).abs(), TimeDelta::milliseconds(300));
-        assert_eq!(TimeDelta::milliseconds(0).abs(), TimeDelta::milliseconds(0));
-        assert_eq!(TimeDelta::milliseconds(-300).abs(), TimeDelta::milliseconds(300));
-        assert_eq!(TimeDelta::milliseconds(-700).abs(), TimeDelta::milliseconds(700));
-        assert_eq!(TimeDelta::milliseconds(-1000).abs(), TimeDelta::milliseconds(1000));
-        assert_eq!(TimeDelta::milliseconds(-1300).abs(), TimeDelta::milliseconds(1300));
-        assert_eq!(TimeDelta::milliseconds(-1700).abs(), TimeDelta::milliseconds(1700));
-        assert_eq!(TimeDelta::milliseconds(-i64::MAX).abs(), TimeDelta::milliseconds(i64::MAX));
+        let milliseconds = |ms| TimeDelta::try_milliseconds(ms).unwrap();
+
+        assert_eq!(milliseconds(1300).abs(), milliseconds(1300));
+        assert_eq!(milliseconds(1000).abs(), milliseconds(1000));
+        assert_eq!(milliseconds(300).abs(), milliseconds(300));
+        assert_eq!(milliseconds(0).abs(), milliseconds(0));
+        assert_eq!(milliseconds(-300).abs(), milliseconds(300));
+        assert_eq!(milliseconds(-700).abs(), milliseconds(700));
+        assert_eq!(milliseconds(-1000).abs(), milliseconds(1000));
+        assert_eq!(milliseconds(-1300).abs(), milliseconds(1300));
+        assert_eq!(milliseconds(-1700).abs(), milliseconds(1700));
+        assert_eq!(milliseconds(-i64::MAX).abs(), milliseconds(i64::MAX));
     }
 
     #[test]
@@ -1070,19 +1090,30 @@ mod tests {
         assert_eq!(TimeDelta::zero() * i32::MIN, TimeDelta::zero());
         assert_eq!(TimeDelta::nanoseconds(1) * 0, TimeDelta::zero());
         assert_eq!(TimeDelta::nanoseconds(1) * 1, TimeDelta::nanoseconds(1));
-        assert_eq!(TimeDelta::nanoseconds(1) * 1_000_000_000, TimeDelta::seconds(1));
-        assert_eq!(TimeDelta::nanoseconds(1) * -1_000_000_000, -TimeDelta::seconds(1));
-        assert_eq!(-TimeDelta::nanoseconds(1) * 1_000_000_000, -TimeDelta::seconds(1));
+        assert_eq!(TimeDelta::nanoseconds(1) * 1_000_000_000, TimeDelta::try_seconds(1).unwrap());
+        assert_eq!(TimeDelta::nanoseconds(1) * -1_000_000_000, -TimeDelta::try_seconds(1).unwrap());
+        assert_eq!(-TimeDelta::nanoseconds(1) * 1_000_000_000, -TimeDelta::try_seconds(1).unwrap());
         assert_eq!(
             TimeDelta::nanoseconds(30) * 333_333_333,
-            TimeDelta::seconds(10) - TimeDelta::nanoseconds(10)
+            TimeDelta::try_seconds(10).unwrap() - TimeDelta::nanoseconds(10)
+        );
+        assert_eq!(
+            (TimeDelta::nanoseconds(1)
+                + TimeDelta::try_seconds(1).unwrap()
+                + TimeDelta::try_days(1).unwrap())
+                * 3,
+            TimeDelta::nanoseconds(3)
+                + TimeDelta::try_seconds(3).unwrap()
+                + TimeDelta::try_days(3).unwrap()
+        );
+        assert_eq!(
+            TimeDelta::try_milliseconds(1500).unwrap() * -2,
+            TimeDelta::try_seconds(-3).unwrap()
         );
         assert_eq!(
-            (TimeDelta::nanoseconds(1) + TimeDelta::seconds(1) + TimeDelta::days(1)) * 3,
-            TimeDelta::nanoseconds(3) + TimeDelta::seconds(3) + TimeDelta::days(3)
+            TimeDelta::try_milliseconds(-1500).unwrap() * 2,
+            TimeDelta::try_seconds(-3).unwrap()
         );
-        assert_eq!(TimeDelta::milliseconds(1500) * -2, TimeDelta::seconds(-3));
-        assert_eq!(TimeDelta::milliseconds(-1500) * 2, TimeDelta::seconds(-3));
     }
 
     #[test]
@@ -1093,85 +1124,110 @@ mod tests {
         assert_eq!(TimeDelta::nanoseconds(123_456_789) / -1, -TimeDelta::nanoseconds(123_456_789));
         assert_eq!(-TimeDelta::nanoseconds(123_456_789) / -1, TimeDelta::nanoseconds(123_456_789));
         assert_eq!(-TimeDelta::nanoseconds(123_456_789) / 1, -TimeDelta::nanoseconds(123_456_789));
-        assert_eq!(TimeDelta::seconds(1) / 3, TimeDelta::nanoseconds(333_333_333));
-        assert_eq!(TimeDelta::seconds(4) / 3, TimeDelta::nanoseconds(1_333_333_333));
-        assert_eq!(TimeDelta::seconds(-1) / 2, TimeDelta::milliseconds(-500));
-        assert_eq!(TimeDelta::seconds(1) / -2, TimeDelta::milliseconds(-500));
-        assert_eq!(TimeDelta::seconds(-1) / -2, TimeDelta::milliseconds(500));
-        assert_eq!(TimeDelta::seconds(-4) / 3, TimeDelta::nanoseconds(-1_333_333_333));
-        assert_eq!(TimeDelta::seconds(-4) / -3, TimeDelta::nanoseconds(1_333_333_333));
+        assert_eq!(TimeDelta::try_seconds(1).unwrap() / 3, TimeDelta::nanoseconds(333_333_333));
+        assert_eq!(TimeDelta::try_seconds(4).unwrap() / 3, TimeDelta::nanoseconds(1_333_333_333));
+        assert_eq!(
+            TimeDelta::try_seconds(-1).unwrap() / 2,
+            TimeDelta::try_milliseconds(-500).unwrap()
+        );
+        assert_eq!(
+            TimeDelta::try_seconds(1).unwrap() / -2,
+            TimeDelta::try_milliseconds(-500).unwrap()
+        );
+        assert_eq!(
+            TimeDelta::try_seconds(-1).unwrap() / -2,
+            TimeDelta::try_milliseconds(500).unwrap()
+        );
+        assert_eq!(TimeDelta::try_seconds(-4).unwrap() / 3, TimeDelta::nanoseconds(-1_333_333_333));
+        assert_eq!(TimeDelta::try_seconds(-4).unwrap() / -3, TimeDelta::nanoseconds(1_333_333_333));
     }
 
     #[test]
     fn test_duration_sum() {
-        let duration_list_1 = [TimeDelta::zero(), TimeDelta::seconds(1)];
+        let duration_list_1 = [TimeDelta::zero(), TimeDelta::try_seconds(1).unwrap()];
         let sum_1: TimeDelta = duration_list_1.iter().sum();
-        assert_eq!(sum_1, TimeDelta::seconds(1));
+        assert_eq!(sum_1, TimeDelta::try_seconds(1).unwrap());
 
         let duration_list_2 = [
             TimeDelta::zero(),
-            TimeDelta::seconds(1),
-            TimeDelta::seconds(6),
-            TimeDelta::seconds(10),
+            TimeDelta::try_seconds(1).unwrap(),
+            TimeDelta::try_seconds(6).unwrap(),
+            TimeDelta::try_seconds(10).unwrap(),
         ];
         let sum_2: TimeDelta = duration_list_2.iter().sum();
-        assert_eq!(sum_2, TimeDelta::seconds(17));
+        assert_eq!(sum_2, TimeDelta::try_seconds(17).unwrap());
 
         let duration_arr = [
             TimeDelta::zero(),
-            TimeDelta::seconds(1),
-            TimeDelta::seconds(6),
-            TimeDelta::seconds(10),
+            TimeDelta::try_seconds(1).unwrap(),
+            TimeDelta::try_seconds(6).unwrap(),
+            TimeDelta::try_seconds(10).unwrap(),
         ];
         let sum_3: TimeDelta = duration_arr.into_iter().sum();
-        assert_eq!(sum_3, TimeDelta::seconds(17));
+        assert_eq!(sum_3, TimeDelta::try_seconds(17).unwrap());
     }
 
     #[test]
     fn test_duration_fmt() {
         assert_eq!(TimeDelta::zero().to_string(), "P0D");
-        assert_eq!(TimeDelta::days(42).to_string(), "PT3628800S");
-        assert_eq!(TimeDelta::days(-42).to_string(), "-PT3628800S");
-        assert_eq!(TimeDelta::seconds(42).to_string(), "PT42S");
-        assert_eq!(TimeDelta::milliseconds(42).to_string(), "PT0.042S");
+        assert_eq!(TimeDelta::try_days(42).unwrap().to_string(), "PT3628800S");
+        assert_eq!(TimeDelta::try_days(-42).unwrap().to_string(), "-PT3628800S");
+        assert_eq!(TimeDelta::try_seconds(42).unwrap().to_string(), "PT42S");
+        assert_eq!(TimeDelta::try_milliseconds(42).unwrap().to_string(), "PT0.042S");
         assert_eq!(TimeDelta::microseconds(42).to_string(), "PT0.000042S");
         assert_eq!(TimeDelta::nanoseconds(42).to_string(), "PT0.000000042S");
         assert_eq!(
-            (TimeDelta::days(7) + TimeDelta::milliseconds(6543)).to_string(),
+            (TimeDelta::try_days(7).unwrap() + TimeDelta::try_milliseconds(6543).unwrap())
+                .to_string(),
             "PT604806.543S"
         );
-        assert_eq!(TimeDelta::seconds(-86_401).to_string(), "-PT86401S");
+        assert_eq!(TimeDelta::try_seconds(-86_401).unwrap().to_string(), "-PT86401S");
         assert_eq!(TimeDelta::nanoseconds(-1).to_string(), "-PT0.000000001S");
 
         // the format specifier should have no effect on `TimeDelta`
         assert_eq!(
-            format!("{:30}", TimeDelta::days(1) + TimeDelta::milliseconds(2345)),
+            format!(
+                "{:30}",
+                TimeDelta::try_days(1).unwrap() + TimeDelta::try_milliseconds(2345).unwrap()
+            ),
             "PT86402.345S"
         );
     }
 
     #[test]
     fn test_to_std() {
-        assert_eq!(TimeDelta::seconds(1).to_std(), Ok(Duration::new(1, 0)));
-        assert_eq!(TimeDelta::seconds(86_401).to_std(), Ok(Duration::new(86_401, 0)));
-        assert_eq!(TimeDelta::milliseconds(123).to_std(), Ok(Duration::new(0, 123_000_000)));
-        assert_eq!(TimeDelta::milliseconds(123_765).to_std(), Ok(Duration::new(123, 765_000_000)));
+        assert_eq!(TimeDelta::try_seconds(1).unwrap().to_std(), Ok(Duration::new(1, 0)));
+        assert_eq!(TimeDelta::try_seconds(86_401).unwrap().to_std(), Ok(Duration::new(86_401, 0)));
+        assert_eq!(
+            TimeDelta::try_milliseconds(123).unwrap().to_std(),
+            Ok(Duration::new(0, 123_000_000))
+        );
+        assert_eq!(
+            TimeDelta::try_milliseconds(123_765).unwrap().to_std(),
+            Ok(Duration::new(123, 765_000_000))
+        );
         assert_eq!(TimeDelta::nanoseconds(777).to_std(), Ok(Duration::new(0, 777)));
         assert_eq!(MAX.to_std(), Ok(Duration::new(9_223_372_036_854_775, 807_000_000)));
-        assert_eq!(TimeDelta::seconds(-1).to_std(), Err(OutOfRangeError(())));
-        assert_eq!(TimeDelta::milliseconds(-1).to_std(), Err(OutOfRangeError(())));
+        assert_eq!(TimeDelta::try_seconds(-1).unwrap().to_std(), Err(OutOfRangeError(())));
+        assert_eq!(TimeDelta::try_milliseconds(-1).unwrap().to_std(), Err(OutOfRangeError(())));
     }
 
     #[test]
     fn test_from_std() {
-        assert_eq!(Ok(TimeDelta::seconds(1)), TimeDelta::from_std(Duration::new(1, 0)));
-        assert_eq!(Ok(TimeDelta::seconds(86_401)), TimeDelta::from_std(Duration::new(86_401, 0)));
         assert_eq!(
-            Ok(TimeDelta::milliseconds(123)),
+            Ok(TimeDelta::try_seconds(1).unwrap()),
+            TimeDelta::from_std(Duration::new(1, 0))
+        );
+        assert_eq!(
+            Ok(TimeDelta::try_seconds(86_401).unwrap()),
+            TimeDelta::from_std(Duration::new(86_401, 0))
+        );
+        assert_eq!(
+            Ok(TimeDelta::try_milliseconds(123).unwrap()),
             TimeDelta::from_std(Duration::new(0, 123_000_000))
         );
         assert_eq!(
-            Ok(TimeDelta::milliseconds(123_765)),
+            Ok(TimeDelta::try_milliseconds(123_765).unwrap()),
             TimeDelta::from_std(Duration::new(123, 765_000_000))
         );
         assert_eq!(Ok(TimeDelta::nanoseconds(777)), TimeDelta::from_std(Duration::new(0, 777)));
@@ -1188,12 +1244,12 @@ mod tests {
 
     #[test]
     fn test_duration_const() {
-        const ONE_WEEK: TimeDelta = TimeDelta::weeks(1);
-        const ONE_DAY: TimeDelta = TimeDelta::days(1);
-        const ONE_HOUR: TimeDelta = TimeDelta::hours(1);
-        const ONE_MINUTE: TimeDelta = TimeDelta::minutes(1);
-        const ONE_SECOND: TimeDelta = TimeDelta::seconds(1);
-        const ONE_MILLI: TimeDelta = TimeDelta::milliseconds(1);
+        const ONE_WEEK: TimeDelta = expect!(TimeDelta::try_weeks(1), "");
+        const ONE_DAY: TimeDelta = expect!(TimeDelta::try_days(1), "");
+        const ONE_HOUR: TimeDelta = expect!(TimeDelta::try_hours(1), "");
+        const ONE_MINUTE: TimeDelta = expect!(TimeDelta::try_minutes(1), "");
+        const ONE_SECOND: TimeDelta = expect!(TimeDelta::try_seconds(1), "");
+        const ONE_MILLI: TimeDelta = expect!(TimeDelta::try_milliseconds(1), "");
         const ONE_MICRO: TimeDelta = TimeDelta::microseconds(1);
         const ONE_NANO: TimeDelta = TimeDelta::nanoseconds(1);
         let combo: TimeDelta = ONE_WEEK
@@ -1215,7 +1271,7 @@ mod tests {
         assert!(ONE_NANO != TimeDelta::zero());
         assert_eq!(
             combo,
-            TimeDelta::seconds(86400 * 7 + 86400 + 3600 + 60 + 1)
+            TimeDelta::try_seconds(86400 * 7 + 86400 + 3600 + 60 + 1).unwrap()
                 + TimeDelta::nanoseconds(1 + 1_000 + 1_000_000)
         );
     }
@@ -1223,7 +1279,7 @@ mod tests {
     #[test]
     #[cfg(feature = "rkyv-validation")]
     fn test_rkyv_validation() {
-        let duration = TimeDelta::seconds(1);
+        let duration = TimeDelta::try_seconds(1).unwrap();
         let bytes = rkyv::to_bytes::<_, 16>(&duration).unwrap();
         assert_eq!(rkyv::from_bytes::<TimeDelta>(&bytes).unwrap(), duration);
     }
diff --git a/src/traits.rs b/src/traits.rs
index ae6cde494f..e582093b0b 100644
--- a/src/traits.rs
+++ b/src/traits.rs
@@ -330,7 +330,7 @@ pub trait Timelike: Sized {
 #[cfg(test)]
 mod tests {
     use super::Datelike;
-    use crate::{NaiveDate, TimeDelta};
+    use crate::{Days, NaiveDate};
 
     /// Tests `Datelike::num_days_from_ce` against an alternative implementation.
     ///
@@ -377,7 +377,7 @@ mod tests {
                 "on {:?}",
                 jan1_year
             );
-            let mid_year = jan1_year + TimeDelta::days(133);
+            let mid_year = jan1_year + Days::new(133);
             assert_eq!(
                 mid_year.num_days_from_ce(),
                 num_days_from_ce(&mid_year),


Test patch:
diff --git a/src/datetime/tests.rs b/src/datetime/tests.rs
index f53b3c953a..81e5c1bb59 100644
--- a/src/datetime/tests.rs
+++ b/src/datetime/tests.rs
@@ -53,7 +53,7 @@ impl TimeZone for DstTester {
             DstTester::TO_WINTER_MONTH_DAY.1,
         )
         .unwrap()
-        .and_time(DstTester::transition_start_local() - TimeDelta::hours(1));
+        .and_time(DstTester::transition_start_local() - TimeDelta::try_hours(1).unwrap());
 
         let local_to_summer_transition_start = NaiveDate::from_ymd_opt(
             local.year(),
@@ -69,7 +69,7 @@ impl TimeZone for DstTester {
             DstTester::TO_SUMMER_MONTH_DAY.1,
         )
         .unwrap()
-        .and_time(DstTester::transition_start_local() + TimeDelta::hours(1));
+        .and_time(DstTester::transition_start_local() + TimeDelta::try_hours(1).unwrap());
 
         if *local < local_to_winter_transition_end || *local >= local_to_summer_transition_end {
             LocalResult::Single(DstTester::summer_offset())
@@ -301,13 +301,13 @@ fn test_nanosecond_range() {
     // Just beyond range
     let maximum = "2262-04-11T23:47:16.854775804UTC";
     let parsed: DateTime<Utc> = maximum.parse().unwrap();
-    let beyond_max = parsed + TimeDelta::milliseconds(300);
+    let beyond_max = parsed + TimeDelta::try_milliseconds(300).unwrap();
     assert!(beyond_max.timestamp_nanos_opt().is_none());
 
     // Far beyond range
     let maximum = "2262-04-11T23:47:16.854775804UTC";
     let parsed: DateTime<Utc> = maximum.parse().unwrap();
-    let beyond_max = parsed + TimeDelta::days(365);
+    let beyond_max = parsed + Days::new(365);
     assert!(beyond_max.timestamp_nanos_opt().is_none());
 }
 
@@ -580,12 +580,12 @@ fn test_datetime_offset() {
     let dt = Utc.with_ymd_and_hms(2014, 5, 6, 7, 8, 9).unwrap();
     assert_eq!(dt, edt.with_ymd_and_hms(2014, 5, 6, 3, 8, 9).unwrap());
     assert_eq!(
-        dt + TimeDelta::seconds(3600 + 60 + 1),
+        dt + TimeDelta::try_seconds(3600 + 60 + 1).unwrap(),
         Utc.with_ymd_and_hms(2014, 5, 6, 8, 9, 10).unwrap()
     );
     assert_eq!(
         dt.signed_duration_since(edt.with_ymd_and_hms(2014, 5, 6, 10, 11, 12).unwrap()),
-        TimeDelta::seconds(-7 * 3600 - 3 * 60 - 3)
+        TimeDelta::try_seconds(-7 * 3600 - 3 * 60 - 3).unwrap()
     );
 
     assert_eq!(*Utc.with_ymd_and_hms(2014, 5, 6, 7, 8, 9).unwrap().offset(), Utc);
@@ -1455,20 +1455,16 @@ fn test_datetime_before_windows_api_limits() {
 #[test]
 #[cfg(feature = "clock")]
 fn test_years_elapsed() {
-    const WEEKS_PER_YEAR: f32 = 52.1775;
-
-    // This is always at least one year because 1 year = 52.1775 weeks.
-    let one_year_ago =
-        Utc::now().date_naive() - TimeDelta::weeks((WEEKS_PER_YEAR * 1.5).ceil() as i64);
-    // A bit more than 2 years.
-    let two_year_ago =
-        Utc::now().date_naive() - TimeDelta::weeks((WEEKS_PER_YEAR * 2.5).ceil() as i64);
+    // A bit more than 1 year
+    let one_year_ago = Utc::now().date_naive() - Days::new(400);
+    // A bit more than 2 years
+    let two_year_ago = Utc::now().date_naive() - Days::new(750);
 
     assert_eq!(Utc::now().date_naive().years_since(one_year_ago), Some(1));
     assert_eq!(Utc::now().date_naive().years_since(two_year_ago), Some(2));
 
     // If the given DateTime is later than now, the function will always return 0.
-    let future = Utc::now().date_naive() + TimeDelta::weeks(12);
+    let future = Utc::now().date_naive() + Days(100);
     assert_eq!(Utc::now().date_naive().years_since(future), None);
 }
 
@@ -1478,20 +1474,20 @@ fn test_datetime_add_assign() {
     let datetime = naivedatetime.and_utc();
     let mut datetime_add = datetime;
 
-    datetime_add += TimeDelta::seconds(60);
-    assert_eq!(datetime_add, datetime + TimeDelta::seconds(60));
+    datetime_add += TimeDelta::try_seconds(60).unwrap();
+    assert_eq!(datetime_add, datetime + TimeDelta::try_seconds(60).unwrap());
 
     let timezone = FixedOffset::east_opt(60 * 60).unwrap();
     let datetime = datetime.with_timezone(&timezone);
     let datetime_add = datetime_add.with_timezone(&timezone);
 
-    assert_eq!(datetime_add, datetime + TimeDelta::seconds(60));
+    assert_eq!(datetime_add, datetime + TimeDelta::try_seconds(60).unwrap());
 
     let timezone = FixedOffset::west_opt(2 * 60 * 60).unwrap();
     let datetime = datetime.with_timezone(&timezone);
     let datetime_add = datetime_add.with_timezone(&timezone);
 
-    assert_eq!(datetime_add, datetime + TimeDelta::seconds(60));
+    assert_eq!(datetime_add, datetime + TimeDelta::try_seconds(60).unwrap());
 }
 
 #[test]
@@ -1504,8 +1500,8 @@ fn test_datetime_add_assign_local() {
 
     // ensure we cross a DST transition
     for i in 1..=365 {
-        datetime_add += TimeDelta::days(1);
-        assert_eq!(datetime_add, datetime + TimeDelta::days(i))
+        datetime_add += TimeDelta::try_days(1).unwrap();
+        assert_eq!(datetime_add, datetime + TimeDelta::try_days(i).unwrap())
     }
 }
 
@@ -1515,20 +1511,20 @@ fn test_datetime_sub_assign() {
     let datetime = naivedatetime.and_utc();
     let mut datetime_sub = datetime;
 
-    datetime_sub -= TimeDelta::minutes(90);
-    assert_eq!(datetime_sub, datetime - TimeDelta::minutes(90));
+    datetime_sub -= TimeDelta::try_minutes(90).unwrap();
+    assert_eq!(datetime_sub, datetime - TimeDelta::try_minutes(90).unwrap());
 
     let timezone = FixedOffset::east_opt(60 * 60).unwrap();
     let datetime = datetime.with_timezone(&timezone);
     let datetime_sub = datetime_sub.with_timezone(&timezone);
 
-    assert_eq!(datetime_sub, datetime - TimeDelta::minutes(90));
+    assert_eq!(datetime_sub, datetime - TimeDelta::try_minutes(90).unwrap());
 
     let timezone = FixedOffset::west_opt(2 * 60 * 60).unwrap();
     let datetime = datetime.with_timezone(&timezone);
     let datetime_sub = datetime_sub.with_timezone(&timezone);
 
-    assert_eq!(datetime_sub, datetime - TimeDelta::minutes(90));
+    assert_eq!(datetime_sub, datetime - TimeDelta::try_minutes(90).unwrap());
 }
 
 #[test]
@@ -1611,7 +1607,10 @@ fn test_min_max_setters() {
     assert_eq!(beyond_min.with_ordinal0(beyond_min.ordinal0()), Some(beyond_min));
     assert_eq!(beyond_min.with_ordinal0(200), None);
     assert_eq!(beyond_min.with_hour(beyond_min.hour()), Some(beyond_min));
-    assert_eq!(beyond_min.with_hour(23), beyond_min.checked_add_signed(TimeDelta::hours(1)));
+    assert_eq!(
+        beyond_min.with_hour(23),
+        beyond_min.checked_add_signed(TimeDelta::try_hours(1).unwrap())
+    );
     assert_eq!(beyond_min.with_hour(5), None);
     assert_eq!(beyond_min.with_minute(0), Some(beyond_min));
     assert_eq!(beyond_min.with_second(0), Some(beyond_min));
@@ -1632,7 +1631,10 @@ fn test_min_max_setters() {
     assert_eq!(beyond_max.with_ordinal0(beyond_max.ordinal0()), Some(beyond_max));
     assert_eq!(beyond_max.with_ordinal0(200), None);
     assert_eq!(beyond_max.with_hour(beyond_max.hour()), Some(beyond_max));
-    assert_eq!(beyond_max.with_hour(0), beyond_max.checked_sub_signed(TimeDelta::hours(1)));
+    assert_eq!(
+        beyond_max.with_hour(0),
+        beyond_max.checked_sub_signed(TimeDelta::try_hours(1).unwrap())
+    );
     assert_eq!(beyond_max.with_hour(5), None);
     assert_eq!(beyond_max.with_minute(beyond_max.minute()), Some(beyond_max));
     assert_eq!(beyond_max.with_second(beyond_max.second()), Some(beyond_max));
@@ -1713,8 +1715,8 @@ fn test_datetime_sub_assign_local() {
 
     // ensure we cross a DST transition
     for i in 1..=365 {
-        datetime_sub -= TimeDelta::days(1);
-        assert_eq!(datetime_sub, datetime - TimeDelta::days(i))
+        datetime_sub -= TimeDelta::try_days(1).unwrap();
+        assert_eq!(datetime_sub, datetime - TimeDelta::try_days(i).unwrap())
     }
 }
 
diff --git a/src/naive/date/tests.rs b/src/naive/date/tests.rs
index 361a88ef59..6d8c299896 100644
--- a/src/naive/date/tests.rs
+++ b/src/naive/date/tests.rs
@@ -454,23 +454,31 @@ fn test_date_add() {
     }
 
     check((2014, 1, 1), TimeDelta::zero(), Some((2014, 1, 1)));
-    check((2014, 1, 1), TimeDelta::seconds(86399), Some((2014, 1, 1)));
+    check((2014, 1, 1), TimeDelta::try_seconds(86399).unwrap(), Some((2014, 1, 1)));
     // always round towards zero
-    check((2014, 1, 1), TimeDelta::seconds(-86399), Some((2014, 1, 1)));
-    check((2014, 1, 1), TimeDelta::days(1), Some((2014, 1, 2)));
-    check((2014, 1, 1), TimeDelta::days(-1), Some((2013, 12, 31)));
-    check((2014, 1, 1), TimeDelta::days(364), Some((2014, 12, 31)));
-    check((2014, 1, 1), TimeDelta::days(365 * 4 + 1), Some((2018, 1, 1)));
-    check((2014, 1, 1), TimeDelta::days(365 * 400 + 97), Some((2414, 1, 1)));
+    check((2014, 1, 1), TimeDelta::try_seconds(-86399).unwrap(), Some((2014, 1, 1)));
+    check((2014, 1, 1), TimeDelta::try_days(1).unwrap(), Some((2014, 1, 2)));
+    check((2014, 1, 1), TimeDelta::try_days(-1).unwrap(), Some((2013, 12, 31)));
+    check((2014, 1, 1), TimeDelta::try_days(364).unwrap(), Some((2014, 12, 31)));
+    check((2014, 1, 1), TimeDelta::try_days(365 * 4 + 1).unwrap(), Some((2018, 1, 1)));
+    check((2014, 1, 1), TimeDelta::try_days(365 * 400 + 97).unwrap(), Some((2414, 1, 1)));
 
-    check((-7, 1, 1), TimeDelta::days(365 * 12 + 3), Some((5, 1, 1)));
+    check((-7, 1, 1), TimeDelta::try_days(365 * 12 + 3).unwrap(), Some((5, 1, 1)));
 
     // overflow check
-    check((0, 1, 1), TimeDelta::days(MAX_DAYS_FROM_YEAR_0 as i64), Some((MAX_YEAR, 12, 31)));
-    check((0, 1, 1), TimeDelta::days(MAX_DAYS_FROM_YEAR_0 as i64 + 1), None);
+    check(
+        (0, 1, 1),
+        TimeDelta::try_days(MAX_DAYS_FROM_YEAR_0 as i64).unwrap(),
+        Some((MAX_YEAR, 12, 31)),
+    );
+    check((0, 1, 1), TimeDelta::try_days(MAX_DAYS_FROM_YEAR_0 as i64 + 1).unwrap(), None);
     check((0, 1, 1), TimeDelta::max_value(), None);
-    check((0, 1, 1), TimeDelta::days(MIN_DAYS_FROM_YEAR_0 as i64), Some((MIN_YEAR, 1, 1)));
-    check((0, 1, 1), TimeDelta::days(MIN_DAYS_FROM_YEAR_0 as i64 - 1), None);
+    check(
+        (0, 1, 1),
+        TimeDelta::try_days(MIN_DAYS_FROM_YEAR_0 as i64).unwrap(),
+        Some((MIN_YEAR, 1, 1)),
+    );
+    check((0, 1, 1), TimeDelta::try_days(MIN_DAYS_FROM_YEAR_0 as i64 - 1).unwrap(), None);
     check((0, 1, 1), TimeDelta::min_value(), None);
 }
 
@@ -484,14 +492,14 @@ fn test_date_sub() {
     }
 
     check((2014, 1, 1), (2014, 1, 1), TimeDelta::zero());
-    check((2014, 1, 2), (2014, 1, 1), TimeDelta::days(1));
-    check((2014, 12, 31), (2014, 1, 1), TimeDelta::days(364));
-    check((2015, 1, 3), (2014, 1, 1), TimeDelta::days(365 + 2));
-    check((2018, 1, 1), (2014, 1, 1), TimeDelta::days(365 * 4 + 1));
-    check((2414, 1, 1), (2014, 1, 1), TimeDelta::days(365 * 400 + 97));
+    check((2014, 1, 2), (2014, 1, 1), TimeDelta::try_days(1).unwrap());
+    check((2014, 12, 31), (2014, 1, 1), TimeDelta::try_days(364).unwrap());
+    check((2015, 1, 3), (2014, 1, 1), TimeDelta::try_days(365 + 2).unwrap());
+    check((2018, 1, 1), (2014, 1, 1), TimeDelta::try_days(365 * 4 + 1).unwrap());
+    check((2414, 1, 1), (2014, 1, 1), TimeDelta::try_days(365 * 400 + 97).unwrap());
 
-    check((MAX_YEAR, 12, 31), (0, 1, 1), TimeDelta::days(MAX_DAYS_FROM_YEAR_0 as i64));
-    check((MIN_YEAR, 1, 1), (0, 1, 1), TimeDelta::days(MIN_DAYS_FROM_YEAR_0 as i64));
+    check((MAX_YEAR, 12, 31), (0, 1, 1), TimeDelta::try_days(MAX_DAYS_FROM_YEAR_0 as i64).unwrap());
+    check((MIN_YEAR, 1, 1), (0, 1, 1), TimeDelta::try_days(MIN_DAYS_FROM_YEAR_0 as i64).unwrap());
 }
 
 #[test]
@@ -539,9 +547,9 @@ fn test_date_sub_days() {
 fn test_date_addassignment() {
     let ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
     let mut date = ymd(2016, 10, 1);
-    date += TimeDelta::days(10);
+    date += TimeDelta::try_days(10).unwrap();
     assert_eq!(date, ymd(2016, 10, 11));
-    date += TimeDelta::days(30);
+    date += TimeDelta::try_days(30).unwrap();
     assert_eq!(date, ymd(2016, 11, 10));
 }
 
@@ -549,9 +557,9 @@ fn test_date_addassignment() {
 fn test_date_subassignment() {
     let ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
     let mut date = ymd(2016, 10, 11);
-    date -= TimeDelta::days(10);
+    date -= TimeDelta::try_days(10).unwrap();
     assert_eq!(date, ymd(2016, 10, 1));
-    date -= TimeDelta::days(2);
+    date -= TimeDelta::try_days(2).unwrap();
     assert_eq!(date, ymd(2016, 9, 29));
 }
 
diff --git a/src/naive/datetime/tests.rs b/src/naive/datetime/tests.rs
index 751ff7e696..27e884c036 100644
--- a/src/naive/datetime/tests.rs
+++ b/src/naive/datetime/tests.rs
@@ -15,13 +15,14 @@ fn test_datetime_add() {
         assert_eq!(lhs.checked_add_signed(rhs), sum);
         assert_eq!(lhs.checked_sub_signed(-rhs), sum);
     }
+    let seconds = |s| TimeDelta::try_seconds(s).unwrap();
 
-    check((2014, 5, 6, 7, 8, 9), TimeDelta::seconds(3600 + 60 + 1), Some((2014, 5, 6, 8, 9, 10)));
-    check((2014, 5, 6, 7, 8, 9), TimeDelta::seconds(-(3600 + 60 + 1)), Some((2014, 5, 6, 6, 7, 8)));
-    check((2014, 5, 6, 7, 8, 9), TimeDelta::seconds(86399), Some((2014, 5, 7, 7, 8, 8)));
-    check((2014, 5, 6, 7, 8, 9), TimeDelta::seconds(86_400 * 10), Some((2014, 5, 16, 7, 8, 9)));
-    check((2014, 5, 6, 7, 8, 9), TimeDelta::seconds(-86_400 * 10), Some((2014, 4, 26, 7, 8, 9)));
-    check((2014, 5, 6, 7, 8, 9), TimeDelta::seconds(86_400 * 10), Some((2014, 5, 16, 7, 8, 9)));
+    check((2014, 5, 6, 7, 8, 9), seconds(3600 + 60 + 1), Some((2014, 5, 6, 8, 9, 10)));
+    check((2014, 5, 6, 7, 8, 9), seconds(-(3600 + 60 + 1)), Some((2014, 5, 6, 6, 7, 8)));
+    check((2014, 5, 6, 7, 8, 9), seconds(86399), Some((2014, 5, 7, 7, 8, 8)));
+    check((2014, 5, 6, 7, 8, 9), seconds(86_400 * 10), Some((2014, 5, 16, 7, 8, 9)));
+    check((2014, 5, 6, 7, 8, 9), seconds(-86_400 * 10), Some((2014, 4, 26, 7, 8, 9)));
+    check((2014, 5, 6, 7, 8, 9), seconds(86_400 * 10), Some((2014, 5, 16, 7, 8, 9)));
 
     // overflow check
     // assumes that we have correct values for MAX/MIN_DAYS_FROM_YEAR_0 from `naive::date`.
@@ -31,16 +32,16 @@ fn test_datetime_add() {
     check((0, 1, 1, 0, 0, 0), max_days_from_year_0, Some((NaiveDate::MAX.year(), 12, 31, 0, 0, 0)));
     check(
         (0, 1, 1, 0, 0, 0),
-        max_days_from_year_0 + TimeDelta::seconds(86399),
+        max_days_from_year_0 + seconds(86399),
         Some((NaiveDate::MAX.year(), 12, 31, 23, 59, 59)),
     );
-    check((0, 1, 1, 0, 0, 0), max_days_from_year_0 + TimeDelta::seconds(86_400), None);
+    check((0, 1, 1, 0, 0, 0), max_days_from_year_0 + seconds(86_400), None);
     check((0, 1, 1, 0, 0, 0), TimeDelta::max_value(), None);
 
     let min_days_from_year_0 =
         NaiveDate::MIN.signed_duration_since(NaiveDate::from_ymd_opt(0, 1, 1).unwrap());
     check((0, 1, 1, 0, 0, 0), min_days_from_year_0, Some((NaiveDate::MIN.year(), 1, 1, 0, 0, 0)));
-    check((0, 1, 1, 0, 0, 0), min_days_from_year_0 - TimeDelta::seconds(1), None);
+    check((0, 1, 1, 0, 0, 0), min_days_from_year_0 - seconds(1), None);
     check((0, 1, 1, 0, 0, 0), TimeDelta::min_value(), None);
 }
 
@@ -52,19 +53,19 @@ fn test_datetime_sub() {
     assert_eq!(since(ymdhms(2014, 5, 6, 7, 8, 9), ymdhms(2014, 5, 6, 7, 8, 9)), TimeDelta::zero());
     assert_eq!(
         since(ymdhms(2014, 5, 6, 7, 8, 10), ymdhms(2014, 5, 6, 7, 8, 9)),
-        TimeDelta::seconds(1)
+        TimeDelta::try_seconds(1).unwrap()
     );
     assert_eq!(
         since(ymdhms(2014, 5, 6, 7, 8, 9), ymdhms(2014, 5, 6, 7, 8, 10)),
-        TimeDelta::seconds(-1)
+        TimeDelta::try_seconds(-1).unwrap()
     );
     assert_eq!(
         since(ymdhms(2014, 5, 7, 7, 8, 9), ymdhms(2014, 5, 6, 7, 8, 10)),
-        TimeDelta::seconds(86399)
+        TimeDelta::try_seconds(86399).unwrap()
     );
     assert_eq!(
         since(ymdhms(2001, 9, 9, 1, 46, 39), ymdhms(1970, 1, 1, 0, 0, 0)),
-        TimeDelta::seconds(999_999_999)
+        TimeDelta::try_seconds(999_999_999).unwrap()
     );
 }
 
@@ -73,9 +74,9 @@ fn test_datetime_addassignment() {
     let ymdhms =
         |y, m, d, h, n, s| NaiveDate::from_ymd_opt(y, m, d).unwrap().and_hms_opt(h, n, s).unwrap();
     let mut date = ymdhms(2016, 10, 1, 10, 10, 10);
-    date += TimeDelta::minutes(10_000_000);
+    date += TimeDelta::try_minutes(10_000_000).unwrap();
     assert_eq!(date, ymdhms(2035, 10, 6, 20, 50, 10));
-    date += TimeDelta::days(10);
+    date += TimeDelta::try_days(10).unwrap();
     assert_eq!(date, ymdhms(2035, 10, 16, 20, 50, 10));
 }
 
@@ -84,9 +85,9 @@ fn test_datetime_subassignment() {
     let ymdhms =
         |y, m, d, h, n, s| NaiveDate::from_ymd_opt(y, m, d).unwrap().and_hms_opt(h, n, s).unwrap();
     let mut date = ymdhms(2016, 10, 1, 10, 10, 10);
-    date -= TimeDelta::minutes(10_000_000);
+    date -= TimeDelta::try_minutes(10_000_000).unwrap();
     assert_eq!(date, ymdhms(1997, 9, 26, 23, 30, 10));
-    date -= TimeDelta::days(10);
+    date -= TimeDelta::try_days(10).unwrap();
     assert_eq!(date, ymdhms(1997, 9, 16, 23, 30, 10));
 }
 
diff --git a/src/naive/time/tests.rs b/src/naive/time/tests.rs
index a991117a7f..a8754aebd6 100644
--- a/src/naive/time/tests.rs
+++ b/src/naive/time/tests.rs
@@ -94,22 +94,26 @@ fn test_time_add() {
     let hmsm = |h, m, s, ms| NaiveTime::from_hms_milli_opt(h, m, s, ms).unwrap();
 
     check!(hmsm(3, 5, 59, 900), TimeDelta::zero(), hmsm(3, 5, 59, 900));
-    check!(hmsm(3, 5, 59, 900), TimeDelta::milliseconds(100), hmsm(3, 6, 0, 0));
-    check!(hmsm(3, 5, 59, 1_300), TimeDelta::milliseconds(-1800), hmsm(3, 5, 58, 500));
-    check!(hmsm(3, 5, 59, 1_300), TimeDelta::milliseconds(-800), hmsm(3, 5, 59, 500));
-    check!(hmsm(3, 5, 59, 1_300), TimeDelta::milliseconds(-100), hmsm(3, 5, 59, 1_200));
-    check!(hmsm(3, 5, 59, 1_300), TimeDelta::milliseconds(100), hmsm(3, 5, 59, 1_400));
-    check!(hmsm(3, 5, 59, 1_300), TimeDelta::milliseconds(800), hmsm(3, 6, 0, 100));
-    check!(hmsm(3, 5, 59, 1_300), TimeDelta::milliseconds(1800), hmsm(3, 6, 1, 100));
-    check!(hmsm(3, 5, 59, 900), TimeDelta::seconds(86399), hmsm(3, 5, 58, 900)); // overwrap
-    check!(hmsm(3, 5, 59, 900), TimeDelta::seconds(-86399), hmsm(3, 6, 0, 900));
-    check!(hmsm(3, 5, 59, 900), TimeDelta::days(12345), hmsm(3, 5, 59, 900));
-    check!(hmsm(3, 5, 59, 1_300), TimeDelta::days(1), hmsm(3, 5, 59, 300));
-    check!(hmsm(3, 5, 59, 1_300), TimeDelta::days(-1), hmsm(3, 6, 0, 300));
+    check!(hmsm(3, 5, 59, 900), TimeDelta::try_milliseconds(100).unwrap(), hmsm(3, 6, 0, 0));
+    check!(hmsm(3, 5, 59, 1_300), TimeDelta::try_milliseconds(-1800).unwrap(), hmsm(3, 5, 58, 500));
+    check!(hmsm(3, 5, 59, 1_300), TimeDelta::try_milliseconds(-800).unwrap(), hmsm(3, 5, 59, 500));
+    check!(
+        hmsm(3, 5, 59, 1_300),
+        TimeDelta::try_milliseconds(-100).unwrap(),
+        hmsm(3, 5, 59, 1_200)
+    );
+    check!(hmsm(3, 5, 59, 1_300), TimeDelta::try_milliseconds(100).unwrap(), hmsm(3, 5, 59, 1_400));
+    check!(hmsm(3, 5, 59, 1_300), TimeDelta::try_milliseconds(800).unwrap(), hmsm(3, 6, 0, 100));
+    check!(hmsm(3, 5, 59, 1_300), TimeDelta::try_milliseconds(1800).unwrap(), hmsm(3, 6, 1, 100));
+    check!(hmsm(3, 5, 59, 900), TimeDelta::try_seconds(86399).unwrap(), hmsm(3, 5, 58, 900)); // overwrap
+    check!(hmsm(3, 5, 59, 900), TimeDelta::try_seconds(-86399).unwrap(), hmsm(3, 6, 0, 900));
+    check!(hmsm(3, 5, 59, 900), TimeDelta::try_days(12345).unwrap(), hmsm(3, 5, 59, 900));
+    check!(hmsm(3, 5, 59, 1_300), TimeDelta::try_days(1).unwrap(), hmsm(3, 5, 59, 300));
+    check!(hmsm(3, 5, 59, 1_300), TimeDelta::try_days(-1).unwrap(), hmsm(3, 6, 0, 300));
 
     // regression tests for #37
-    check!(hmsm(0, 0, 0, 0), TimeDelta::milliseconds(-990), hmsm(23, 59, 59, 10));
-    check!(hmsm(0, 0, 0, 0), TimeDelta::milliseconds(-9990), hmsm(23, 59, 50, 10));
+    check!(hmsm(0, 0, 0, 0), TimeDelta::try_milliseconds(-990).unwrap(), hmsm(23, 59, 59, 10));
+    check!(hmsm(0, 0, 0, 0), TimeDelta::try_milliseconds(-9990).unwrap(), hmsm(23, 59, 50, 10));
 }
 
 #[test]
@@ -117,25 +121,25 @@ fn test_time_overflowing_add() {
     let hmsm = |h, m, s, ms| NaiveTime::from_hms_milli_opt(h, m, s, ms).unwrap();
 
     assert_eq!(
-        hmsm(3, 4, 5, 678).overflowing_add_signed(TimeDelta::hours(11)),
+        hmsm(3, 4, 5, 678).overflowing_add_signed(TimeDelta::try_hours(11).unwrap()),
         (hmsm(14, 4, 5, 678), 0)
     );
     assert_eq!(
-        hmsm(3, 4, 5, 678).overflowing_add_signed(TimeDelta::hours(23)),
+        hmsm(3, 4, 5, 678).overflowing_add_signed(TimeDelta::try_hours(23).unwrap()),
         (hmsm(2, 4, 5, 678), 86_400)
     );
     assert_eq!(
-        hmsm(3, 4, 5, 678).overflowing_add_signed(TimeDelta::hours(-7)),
+        hmsm(3, 4, 5, 678).overflowing_add_signed(TimeDelta::try_hours(-7).unwrap()),
         (hmsm(20, 4, 5, 678), -86_400)
     );
 
     // overflowing_add_signed with leap seconds may be counter-intuitive
     assert_eq!(
-        hmsm(3, 4, 59, 1_678).overflowing_add_signed(TimeDelta::days(1)),
+        hmsm(3, 4, 59, 1_678).overflowing_add_signed(TimeDelta::try_days(1).unwrap()),
         (hmsm(3, 4, 59, 678), 86_400)
     );
     assert_eq!(
-        hmsm(3, 4, 59, 1_678).overflowing_add_signed(TimeDelta::days(-1)),
+        hmsm(3, 4, 59, 1_678).overflowing_add_signed(TimeDelta::try_days(-1).unwrap()),
         (hmsm(3, 5, 0, 678), -86_400)
     );
 }
@@ -144,9 +148,9 @@ fn test_time_overflowing_add() {
 fn test_time_addassignment() {
     let hms = |h, m, s| NaiveTime::from_hms_opt(h, m, s).unwrap();
     let mut time = hms(12, 12, 12);
-    time += TimeDelta::hours(10);
+    time += TimeDelta::try_hours(10).unwrap();
     assert_eq!(time, hms(22, 12, 12));
-    time += TimeDelta::hours(10);
+    time += TimeDelta::try_hours(10).unwrap();
     assert_eq!(time, hms(8, 12, 12));
 }
 
@@ -154,9 +158,9 @@ fn test_time_addassignment() {
 fn test_time_subassignment() {
     let hms = |h, m, s| NaiveTime::from_hms_opt(h, m, s).unwrap();
     let mut time = hms(12, 12, 12);
-    time -= TimeDelta::hours(10);
+    time -= TimeDelta::try_hours(10).unwrap();
     assert_eq!(time, hms(2, 12, 12));
-    time -= TimeDelta::hours(10);
+    time -= TimeDelta::try_hours(10).unwrap();
     assert_eq!(time, hms(16, 12, 12));
 }
 
@@ -173,24 +177,24 @@ fn test_time_sub() {
     let hmsm = |h, m, s, ms| NaiveTime::from_hms_milli_opt(h, m, s, ms).unwrap();
 
     check!(hmsm(3, 5, 7, 900), hmsm(3, 5, 7, 900), TimeDelta::zero());
-    check!(hmsm(3, 5, 7, 900), hmsm(3, 5, 7, 600), TimeDelta::milliseconds(300));
-    check!(hmsm(3, 5, 7, 200), hmsm(2, 4, 6, 200), TimeDelta::seconds(3600 + 60 + 1));
+    check!(hmsm(3, 5, 7, 900), hmsm(3, 5, 7, 600), TimeDelta::try_milliseconds(300).unwrap());
+    check!(hmsm(3, 5, 7, 200), hmsm(2, 4, 6, 200), TimeDelta::try_seconds(3600 + 60 + 1).unwrap());
     check!(
         hmsm(3, 5, 7, 200),
         hmsm(2, 4, 6, 300),
-        TimeDelta::seconds(3600 + 60) + TimeDelta::milliseconds(900)
+        TimeDelta::try_seconds(3600 + 60).unwrap() + TimeDelta::try_milliseconds(900).unwrap()
     );
 
     // treats the leap second as if it coincides with the prior non-leap second,
     // as required by `time1 - time2 = duration` and `time2 - time1 = -duration` equivalence.
-    check!(hmsm(3, 6, 0, 200), hmsm(3, 5, 59, 1_800), TimeDelta::milliseconds(400));
-    //check!(hmsm(3, 5, 7, 1_200), hmsm(3, 5, 6, 1_800), TimeDelta::milliseconds(1400));
-    //check!(hmsm(3, 5, 7, 1_200), hmsm(3, 5, 6, 800), TimeDelta::milliseconds(1400));
+    check!(hmsm(3, 6, 0, 200), hmsm(3, 5, 59, 1_800), TimeDelta::try_milliseconds(400).unwrap());
+    //check!(hmsm(3, 5, 7, 1_200), hmsm(3, 5, 6, 1_800), TimeDelta::try_milliseconds(1400).unwrap());
+    //check!(hmsm(3, 5, 7, 1_200), hmsm(3, 5, 6, 800), TimeDelta::try_milliseconds(1400).unwrap());
 
     // additional equality: `time1 + duration = time2` is equivalent to
     // `time2 - time1 = duration` IF AND ONLY IF `time2` represents a non-leap second.
-    assert_eq!(hmsm(3, 5, 6, 800) + TimeDelta::milliseconds(400), hmsm(3, 5, 7, 200));
-    //assert_eq!(hmsm(3, 5, 6, 1_800) + TimeDelta::milliseconds(400), hmsm(3, 5, 7, 200));
+    assert_eq!(hmsm(3, 5, 6, 800) + TimeDelta::try_milliseconds(400).unwrap(), hmsm(3, 5, 7, 200));
+    //assert_eq!(hmsm(3, 5, 6, 1_800) + TimeDelta::try_milliseconds(400).unwrap(), hmsm(3, 5, 7, 200));
 }
 
 #[test]
diff --git a/tests/dateutils.rs b/tests/dateutils.rs
index cf3d908a4b..34f4ac7e3a 100644
--- a/tests/dateutils.rs
+++ b/tests/dateutils.rs
@@ -1,6 +1,6 @@
 #![cfg(all(unix, feature = "clock", feature = "std"))]
 
-use chrono::{Datelike, Local, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Timelike};
+use chrono::{Datelike, Days, Local, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Timelike};
 use std::{path, process, thread};
 
 fn verify_against_date_command_local(path: &'static str, dt: NaiveDateTime) {
@@ -94,7 +94,7 @@ fn try_verify_against_date_command() {
             let end = NaiveDate::from_ymd_opt(*year + 1, 1, 1).unwrap().and_time(NaiveTime::MIN);
             while date <= end {
                 verify_against_date_command_local(DATE_PATH, date);
-                date += chrono::TimeDelta::hours(1);
+                date += chrono::TimeDelta::try_hours(1).unwrap();
             }
         }));
     }
@@ -157,6 +157,6 @@ fn try_verify_against_date_command_format() {
     let mut date = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap().and_hms_opt(12, 11, 13).unwrap();
     while date.year() < 2008 {
         verify_against_date_command_format_local(DATE_PATH, date);
-        date += chrono::TimeDelta::days(55);
+        date = date + Days::new(55);
     }
 }
diff --git a/tests/wasm.rs b/tests/wasm.rs
index 6937da9f71..ceb9b3de97 100644
--- a/tests/wasm.rs
+++ b/tests/wasm.rs
@@ -25,7 +25,7 @@ fn now() {
     let actual = NaiveDateTime::parse_from_str(&now, "%s").unwrap().and_utc();
     let diff = utc - actual;
     assert!(
-        diff < chrono::TimeDelta::minutes(5),
+        diff < chrono::TimeDelta::try_minutes(5).unwrap(),
         "expected {} - {} == {} < 5m (env var: {})",
         utc,
         actual,