about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/core/src/time.rs120
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/core/tests/time.rs43
-rw-r--r--src/doc/unstable-book/src/library-features/duration-constructors.md9
4 files changed, 173 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);
diff --git a/src/doc/unstable-book/src/library-features/duration-constructors.md b/src/doc/unstable-book/src/library-features/duration-constructors.md
new file mode 100644
index 00000000000..098519c7c90
--- /dev/null
+++ b/src/doc/unstable-book/src/library-features/duration-constructors.md
@@ -0,0 +1,9 @@
+# `duration_constructors`
+
+The tracking issue for this feature is: [#120301]
+
+[#120301]: https://github.com/rust-lang/rust/issues/120301
+
+------------------------
+
+Add the methods `from_mins`, `from_hours` and `from_days` to `Duration`.