about summary refs log tree commit diff
path: root/library/core
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-02-11 08:25:42 +0100
committerGitHub <noreply@github.com>2024-02-11 08:25:42 +0100
commitba405a47bd23baa174f93541fe6005eea57c8bc3 (patch)
tree5fc8d4c0d083ce5f2e51bd61d331548ce9d6d011 /library/core
parent0c5d8d3d3eba124329f9a3d11f1459488e117708 (diff)
parente077ff0eedd600c1e8e1a556a520b456457b0312 (diff)
downloadrust-ba405a47bd23baa174f93541fe6005eea57c8bc3.tar.gz
rust-ba405a47bd23baa174f93541fe6005eea57c8bc3.zip
Rollup merge of #120307 - djc:duration-constructors, r=Mark-Simulacrum
core: add Duration constructors

Add more `Duration` constructors.

Tracking issue: #120301.

These match similar convenience constructors available on both `chrono::Duration` and `time::Duration`.

What's the best ordering for these with respect to the existing constructors?
Diffstat (limited to 'library/core')
-rw-r--r--library/core/src/time.rs120
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/core/tests/time.rs43
3 files changed, 164 insertions, 0 deletions
diff --git a/library/core/src/time.rs b/library/core/src/time.rs
index 0fc437d3477..b533f539938 100644
--- a/library/core/src/time.rs
+++ b/library/core/src/time.rs
@@ -28,6 +28,14 @@ const NANOS_PER_MILLI: u32 = 1_000_000;
 const NANOS_PER_MICRO: u32 = 1_000;
 const MILLIS_PER_SEC: u64 = 1_000;
 const MICROS_PER_SEC: u64 = 1_000_000;
+#[unstable(feature = "duration_units", issue = "120301")]
+const SECS_PER_MINUTE: u64 = 60;
+#[unstable(feature = "duration_units", issue = "120301")]
+const MINS_PER_HOUR: u64 = 60;
+#[unstable(feature = "duration_units", issue = "120301")]
+const HOURS_PER_DAY: u64 = 24;
+#[unstable(feature = "duration_units", issue = "120301")]
+const DAYS_PER_WEEK: u64 = 7;
 
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[repr(transparent)]
@@ -296,6 +304,118 @@ impl Duration {
         Duration::new(nanos / (NANOS_PER_SEC as u64), (nanos % (NANOS_PER_SEC as u64)) as u32)
     }
 
+    /// Creates a new `Duration` from the specified number of weeks.
+    ///
+    /// # Panics
+    ///
+    /// Panics if the given number of weeks overflows the `Duration` size.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(duration_constructors)]
+    /// use std::time::Duration;
+    ///
+    /// let duration = Duration::from_weeks(4);
+    ///
+    /// assert_eq!(4 * 7 * 24 * 60 * 60, duration.as_secs());
+    /// assert_eq!(0, duration.subsec_nanos());
+    /// ```
+    #[unstable(feature = "duration_constructors", issue = "120301")]
+    #[must_use]
+    #[inline]
+    pub const fn from_weeks(weeks: u64) -> Duration {
+        if weeks > u64::MAX / (SECS_PER_MINUTE * MINS_PER_HOUR * HOURS_PER_DAY * DAYS_PER_WEEK) {
+            panic!("overflow in Duration::from_days");
+        }
+
+        Duration::from_secs(weeks * MINS_PER_HOUR * SECS_PER_MINUTE * HOURS_PER_DAY * DAYS_PER_WEEK)
+    }
+
+    /// Creates a new `Duration` from the specified number of days.
+    ///
+    /// # Panics
+    ///
+    /// Panics if the given number of days overflows the `Duration` size.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(duration_constructors)]
+    /// use std::time::Duration;
+    ///
+    /// let duration = Duration::from_days(7);
+    ///
+    /// assert_eq!(7 * 24 * 60 * 60, duration.as_secs());
+    /// assert_eq!(0, duration.subsec_nanos());
+    /// ```
+    #[unstable(feature = "duration_constructors", issue = "120301")]
+    #[must_use]
+    #[inline]
+    pub const fn from_days(days: u64) -> Duration {
+        if days > u64::MAX / (SECS_PER_MINUTE * MINS_PER_HOUR * HOURS_PER_DAY) {
+            panic!("overflow in Duration::from_days");
+        }
+
+        Duration::from_secs(days * MINS_PER_HOUR * SECS_PER_MINUTE * HOURS_PER_DAY)
+    }
+
+    /// Creates a new `Duration` from the specified number of hours.
+    ///
+    /// # Panics
+    ///
+    /// Panics if the given number of hours overflows the `Duration` size.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(duration_constructors)]
+    /// use std::time::Duration;
+    ///
+    /// let duration = Duration::from_hours(6);
+    ///
+    /// assert_eq!(6 * 60 * 60, duration.as_secs());
+    /// assert_eq!(0, duration.subsec_nanos());
+    /// ```
+    #[unstable(feature = "duration_constructors", issue = "120301")]
+    #[must_use]
+    #[inline]
+    pub const fn from_hours(hours: u64) -> Duration {
+        if hours > u64::MAX / (SECS_PER_MINUTE * MINS_PER_HOUR) {
+            panic!("overflow in Duration::from_hours");
+        }
+
+        Duration::from_secs(hours * MINS_PER_HOUR * SECS_PER_MINUTE)
+    }
+
+    /// Creates a new `Duration` from the specified number of minutes.
+    ///
+    /// # Panics
+    ///
+    /// Panics if the given number of minutes overflows the `Duration` size.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(duration_constructors)]
+    /// use std::time::Duration;
+    ///
+    /// let duration = Duration::from_mins(10);
+    ///
+    /// assert_eq!(10 * 60, duration.as_secs());
+    /// assert_eq!(0, duration.subsec_nanos());
+    /// ```
+    #[unstable(feature = "duration_constructors", issue = "120301")]
+    #[must_use]
+    #[inline]
+    pub const fn from_mins(mins: u64) -> Duration {
+        if mins > u64::MAX / SECS_PER_MINUTE {
+            panic!("overflow in Duration::from_mins");
+        }
+
+        Duration::from_secs(mins * SECS_PER_MINUTE)
+    }
+
     /// Returns true if this `Duration` spans no time.
     ///
     /// # Examples
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 6deebc0d263..2fe79650dbf 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -32,6 +32,7 @@
 #![feature(duration_abs_diff)]
 #![feature(duration_consts_float)]
 #![feature(duration_constants)]
+#![feature(duration_constructors)]
 #![feature(exact_size_is_empty)]
 #![feature(extern_types)]
 #![feature(flt2dec)]
diff --git a/library/core/tests/time.rs b/library/core/tests/time.rs
index 23f07bf84b3..fe7bb11c675 100644
--- a/library/core/tests/time.rs
+++ b/library/core/tests/time.rs
@@ -18,6 +18,49 @@ fn new_overflow() {
 }
 
 #[test]
+#[should_panic]
+fn from_mins_overflow() {
+    let overflow = u64::MAX / 60 + 1;
+    let _ = Duration::from_mins(overflow);
+}
+
+#[test]
+#[should_panic]
+fn from_hours_overflow() {
+    let overflow = u64::MAX / (60 * 60) + 1;
+    let _ = Duration::from_hours(overflow);
+}
+
+#[test]
+#[should_panic]
+fn from_days_overflow() {
+    let overflow = u64::MAX / (24 * 60 * 60) + 1;
+    let _ = Duration::from_days(overflow);
+}
+
+#[test]
+#[should_panic]
+fn from_weeks_overflow() {
+    let overflow = u64::MAX / (7 * 24 * 60 * 60) + 1;
+    let _ = Duration::from_weeks(overflow);
+}
+
+#[test]
+fn constructors() {
+    assert_eq!(Duration::from_weeks(1), Duration::from_secs(7 * 24 * 60 * 60));
+    assert_eq!(Duration::from_weeks(0), Duration::ZERO);
+
+    assert_eq!(Duration::from_days(1), Duration::from_secs(86_400));
+    assert_eq!(Duration::from_days(0), Duration::ZERO);
+
+    assert_eq!(Duration::from_hours(1), Duration::from_secs(3_600));
+    assert_eq!(Duration::from_hours(0), Duration::ZERO);
+
+    assert_eq!(Duration::from_mins(1), Duration::from_secs(60));
+    assert_eq!(Duration::from_mins(0), Duration::ZERO);
+}
+
+#[test]
 fn secs() {
     assert_eq!(Duration::new(0, 0).as_secs(), 0);
     assert_eq!(Duration::new(0, 500_000_005).as_secs(), 0);