Skip to content

Commit ba405a4

Browse files
authoredFeb 11, 2024
Rollup merge of rust-lang#120307 - djc:duration-constructors, r=Mark-Simulacrum
core: add Duration constructors Add more `Duration` constructors. Tracking issue: rust-lang#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?
2 parents 0c5d8d3 + e077ff0 commit ba405a4

File tree

4 files changed

+173
-0
lines changed

4 files changed

+173
-0
lines changed
 

‎library/core/src/time.rs

+120
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ const NANOS_PER_MILLI: u32 = 1_000_000;
2828
const NANOS_PER_MICRO: u32 = 1_000;
2929
const MILLIS_PER_SEC: u64 = 1_000;
3030
const MICROS_PER_SEC: u64 = 1_000_000;
31+
#[unstable(feature = "duration_units", issue = "120301")]
32+
const SECS_PER_MINUTE: u64 = 60;
33+
#[unstable(feature = "duration_units", issue = "120301")]
34+
const MINS_PER_HOUR: u64 = 60;
35+
#[unstable(feature = "duration_units", issue = "120301")]
36+
const HOURS_PER_DAY: u64 = 24;
37+
#[unstable(feature = "duration_units", issue = "120301")]
38+
const DAYS_PER_WEEK: u64 = 7;
3139

3240
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
3341
#[repr(transparent)]
@@ -296,6 +304,118 @@ impl Duration {
296304
Duration::new(nanos / (NANOS_PER_SEC as u64), (nanos % (NANOS_PER_SEC as u64)) as u32)
297305
}
298306

307+
/// Creates a new `Duration` from the specified number of weeks.
308+
///
309+
/// # Panics
310+
///
311+
/// Panics if the given number of weeks overflows the `Duration` size.
312+
///
313+
/// # Examples
314+
///
315+
/// ```
316+
/// #![feature(duration_constructors)]
317+
/// use std::time::Duration;
318+
///
319+
/// let duration = Duration::from_weeks(4);
320+
///
321+
/// assert_eq!(4 * 7 * 24 * 60 * 60, duration.as_secs());
322+
/// assert_eq!(0, duration.subsec_nanos());
323+
/// ```
324+
#[unstable(feature = "duration_constructors", issue = "120301")]
325+
#[must_use]
326+
#[inline]
327+
pub const fn from_weeks(weeks: u64) -> Duration {
328+
if weeks > u64::MAX / (SECS_PER_MINUTE * MINS_PER_HOUR * HOURS_PER_DAY * DAYS_PER_WEEK) {
329+
panic!("overflow in Duration::from_days");
330+
}
331+
332+
Duration::from_secs(weeks * MINS_PER_HOUR * SECS_PER_MINUTE * HOURS_PER_DAY * DAYS_PER_WEEK)
333+
}
334+
335+
/// Creates a new `Duration` from the specified number of days.
336+
///
337+
/// # Panics
338+
///
339+
/// Panics if the given number of days overflows the `Duration` size.
340+
///
341+
/// # Examples
342+
///
343+
/// ```
344+
/// #![feature(duration_constructors)]
345+
/// use std::time::Duration;
346+
///
347+
/// let duration = Duration::from_days(7);
348+
///
349+
/// assert_eq!(7 * 24 * 60 * 60, duration.as_secs());
350+
/// assert_eq!(0, duration.subsec_nanos());
351+
/// ```
352+
#[unstable(feature = "duration_constructors", issue = "120301")]
353+
#[must_use]
354+
#[inline]
355+
pub const fn from_days(days: u64) -> Duration {
356+
if days > u64::MAX / (SECS_PER_MINUTE * MINS_PER_HOUR * HOURS_PER_DAY) {
357+
panic!("overflow in Duration::from_days");
358+
}
359+
360+
Duration::from_secs(days * MINS_PER_HOUR * SECS_PER_MINUTE * HOURS_PER_DAY)
361+
}
362+
363+
/// Creates a new `Duration` from the specified number of hours.
364+
///
365+
/// # Panics
366+
///
367+
/// Panics if the given number of hours overflows the `Duration` size.
368+
///
369+
/// # Examples
370+
///
371+
/// ```
372+
/// #![feature(duration_constructors)]
373+
/// use std::time::Duration;
374+
///
375+
/// let duration = Duration::from_hours(6);
376+
///
377+
/// assert_eq!(6 * 60 * 60, duration.as_secs());
378+
/// assert_eq!(0, duration.subsec_nanos());
379+
/// ```
380+
#[unstable(feature = "duration_constructors", issue = "120301")]
381+
#[must_use]
382+
#[inline]
383+
pub const fn from_hours(hours: u64) -> Duration {
384+
if hours > u64::MAX / (SECS_PER_MINUTE * MINS_PER_HOUR) {
385+
panic!("overflow in Duration::from_hours");
386+
}
387+
388+
Duration::from_secs(hours * MINS_PER_HOUR * SECS_PER_MINUTE)
389+
}
390+
391+
/// Creates a new `Duration` from the specified number of minutes.
392+
///
393+
/// # Panics
394+
///
395+
/// Panics if the given number of minutes overflows the `Duration` size.
396+
///
397+
/// # Examples
398+
///
399+
/// ```
400+
/// #![feature(duration_constructors)]
401+
/// use std::time::Duration;
402+
///
403+
/// let duration = Duration::from_mins(10);
404+
///
405+
/// assert_eq!(10 * 60, duration.as_secs());
406+
/// assert_eq!(0, duration.subsec_nanos());
407+
/// ```
408+
#[unstable(feature = "duration_constructors", issue = "120301")]
409+
#[must_use]
410+
#[inline]
411+
pub const fn from_mins(mins: u64) -> Duration {
412+
if mins > u64::MAX / SECS_PER_MINUTE {
413+
panic!("overflow in Duration::from_mins");
414+
}
415+
416+
Duration::from_secs(mins * SECS_PER_MINUTE)
417+
}
418+
299419
/// Returns true if this `Duration` spans no time.
300420
///
301421
/// # Examples

‎library/core/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#![feature(duration_abs_diff)]
3333
#![feature(duration_consts_float)]
3434
#![feature(duration_constants)]
35+
#![feature(duration_constructors)]
3536
#![feature(exact_size_is_empty)]
3637
#![feature(extern_types)]
3738
#![feature(flt2dec)]

‎library/core/tests/time.rs

+43
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,49 @@ fn new_overflow() {
1717
let _ = Duration::new(u64::MAX, 1_000_000_000);
1818
}
1919

20+
#[test]
21+
#[should_panic]
22+
fn from_mins_overflow() {
23+
let overflow = u64::MAX / 60 + 1;
24+
let _ = Duration::from_mins(overflow);
25+
}
26+
27+
#[test]
28+
#[should_panic]
29+
fn from_hours_overflow() {
30+
let overflow = u64::MAX / (60 * 60) + 1;
31+
let _ = Duration::from_hours(overflow);
32+
}
33+
34+
#[test]
35+
#[should_panic]
36+
fn from_days_overflow() {
37+
let overflow = u64::MAX / (24 * 60 * 60) + 1;
38+
let _ = Duration::from_days(overflow);
39+
}
40+
41+
#[test]
42+
#[should_panic]
43+
fn from_weeks_overflow() {
44+
let overflow = u64::MAX / (7 * 24 * 60 * 60) + 1;
45+
let _ = Duration::from_weeks(overflow);
46+
}
47+
48+
#[test]
49+
fn constructors() {
50+
assert_eq!(Duration::from_weeks(1), Duration::from_secs(7 * 24 * 60 * 60));
51+
assert_eq!(Duration::from_weeks(0), Duration::ZERO);
52+
53+
assert_eq!(Duration::from_days(1), Duration::from_secs(86_400));
54+
assert_eq!(Duration::from_days(0), Duration::ZERO);
55+
56+
assert_eq!(Duration::from_hours(1), Duration::from_secs(3_600));
57+
assert_eq!(Duration::from_hours(0), Duration::ZERO);
58+
59+
assert_eq!(Duration::from_mins(1), Duration::from_secs(60));
60+
assert_eq!(Duration::from_mins(0), Duration::ZERO);
61+
}
62+
2063
#[test]
2164
fn secs() {
2265
assert_eq!(Duration::new(0, 0).as_secs(), 0);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# `duration_constructors`
2+
3+
The tracking issue for this feature is: [#120301]
4+
5+
[#120301]: https://github.com/rust-lang/rust/issues/120301
6+
7+
------------------------
8+
9+
Add the methods `from_mins`, `from_hours` and `from_days` to `Duration`.

0 commit comments

Comments
 (0)
Please sign in to comment.