core/
time.rs

1#![stable(feature = "duration_core", since = "1.25.0")]
2
3//! Temporal quantification.
4//!
5//! # Examples:
6//!
7//! There are multiple ways to create a new [`Duration`]:
8//!
9//! ```
10//! # use std::time::Duration;
11//! let five_seconds = Duration::from_secs(5);
12//! assert_eq!(five_seconds, Duration::from_millis(5_000));
13//! assert_eq!(five_seconds, Duration::from_micros(5_000_000));
14//! assert_eq!(five_seconds, Duration::from_nanos(5_000_000_000));
15//!
16//! let ten_seconds = Duration::from_secs(10);
17//! let seven_nanos = Duration::from_nanos(7);
18//! let total = ten_seconds + seven_nanos;
19//! assert_eq!(total, Duration::new(10, 7));
20//! ```
21
22use crate::fmt;
23use crate::iter::Sum;
24use crate::num::niche_types::Nanoseconds;
25use crate::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
26
27const NANOS_PER_SEC: u32 = 1_000_000_000;
28const NANOS_PER_MILLI: u32 = 1_000_000;
29const NANOS_PER_MICRO: u32 = 1_000;
30const MILLIS_PER_SEC: u64 = 1_000;
31const MICROS_PER_SEC: u64 = 1_000_000;
32#[unstable(feature = "duration_units", issue = "120301")]
33const SECS_PER_MINUTE: u64 = 60;
34#[unstable(feature = "duration_units", issue = "120301")]
35const MINS_PER_HOUR: u64 = 60;
36#[unstable(feature = "duration_units", issue = "120301")]
37const HOURS_PER_DAY: u64 = 24;
38#[unstable(feature = "duration_units", issue = "120301")]
39const DAYS_PER_WEEK: u64 = 7;
40
41/// A `Duration` type to represent a span of time, typically used for system
42/// timeouts.
43///
44/// Each `Duration` is composed of a whole number of seconds and a fractional part
45/// represented in nanoseconds. If the underlying system does not support
46/// nanosecond-level precision, APIs binding a system timeout will typically round up
47/// the number of nanoseconds.
48///
49/// [`Duration`]s implement many common traits, including [`Add`], [`Sub`], and other
50/// [`ops`] traits. It implements [`Default`] by returning a zero-length `Duration`.
51///
52/// [`ops`]: crate::ops
53///
54/// # Examples
55///
56/// ```
57/// use std::time::Duration;
58///
59/// let five_seconds = Duration::new(5, 0);
60/// let five_seconds_and_five_nanos = five_seconds + Duration::new(0, 5);
61///
62/// assert_eq!(five_seconds_and_five_nanos.as_secs(), 5);
63/// assert_eq!(five_seconds_and_five_nanos.subsec_nanos(), 5);
64///
65/// let ten_millis = Duration::from_millis(10);
66/// ```
67///
68/// # Formatting `Duration` values
69///
70/// `Duration` intentionally does not have a `Display` impl, as there are a
71/// variety of ways to format spans of time for human readability. `Duration`
72/// provides a `Debug` impl that shows the full precision of the value.
73///
74/// The `Debug` output uses the non-ASCII "µs" suffix for microseconds. If your
75/// program output may appear in contexts that cannot rely on full Unicode
76/// compatibility, you may wish to format `Duration` objects yourself or use a
77/// crate to do so.
78#[stable(feature = "duration", since = "1.3.0")]
79#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
80#[rustc_diagnostic_item = "Duration"]
81pub struct Duration {
82    secs: u64,
83    nanos: Nanoseconds, // Always 0 <= nanos < NANOS_PER_SEC
84}
85
86impl Duration {
87    /// The duration of one second.
88    ///
89    /// # Examples
90    ///
91    /// ```
92    /// #![feature(duration_constants)]
93    /// use std::time::Duration;
94    ///
95    /// assert_eq!(Duration::SECOND, Duration::from_secs(1));
96    /// ```
97    #[unstable(feature = "duration_constants", issue = "57391")]
98    pub const SECOND: Duration = Duration::from_secs(1);
99
100    /// The duration of one millisecond.
101    ///
102    /// # Examples
103    ///
104    /// ```
105    /// #![feature(duration_constants)]
106    /// use std::time::Duration;
107    ///
108    /// assert_eq!(Duration::MILLISECOND, Duration::from_millis(1));
109    /// ```
110    #[unstable(feature = "duration_constants", issue = "57391")]
111    pub const MILLISECOND: Duration = Duration::from_millis(1);
112
113    /// The duration of one microsecond.
114    ///
115    /// # Examples
116    ///
117    /// ```
118    /// #![feature(duration_constants)]
119    /// use std::time::Duration;
120    ///
121    /// assert_eq!(Duration::MICROSECOND, Duration::from_micros(1));
122    /// ```
123    #[unstable(feature = "duration_constants", issue = "57391")]
124    pub const MICROSECOND: Duration = Duration::from_micros(1);
125
126    /// The duration of one nanosecond.
127    ///
128    /// # Examples
129    ///
130    /// ```
131    /// #![feature(duration_constants)]
132    /// use std::time::Duration;
133    ///
134    /// assert_eq!(Duration::NANOSECOND, Duration::from_nanos(1));
135    /// ```
136    #[unstable(feature = "duration_constants", issue = "57391")]
137    pub const NANOSECOND: Duration = Duration::from_nanos(1);
138
139    /// A duration of zero time.
140    ///
141    /// # Examples
142    ///
143    /// ```
144    /// use std::time::Duration;
145    ///
146    /// let duration = Duration::ZERO;
147    /// assert!(duration.is_zero());
148    /// assert_eq!(duration.as_nanos(), 0);
149    /// ```
150    #[stable(feature = "duration_zero", since = "1.53.0")]
151    pub const ZERO: Duration = Duration::from_nanos(0);
152
153    /// The maximum duration.
154    ///
155    /// May vary by platform as necessary. Must be able to contain the difference between
156    /// two instances of [`Instant`] or two instances of [`SystemTime`].
157    /// This constraint gives it a value of about 584,942,417,355 years in practice,
158    /// which is currently used on all platforms.
159    ///
160    /// # Examples
161    ///
162    /// ```
163    /// use std::time::Duration;
164    ///
165    /// assert_eq!(Duration::MAX, Duration::new(u64::MAX, 1_000_000_000 - 1));
166    /// ```
167    /// [`Instant`]: ../../std/time/struct.Instant.html
168    /// [`SystemTime`]: ../../std/time/struct.SystemTime.html
169    #[stable(feature = "duration_saturating_ops", since = "1.53.0")]
170    pub const MAX: Duration = Duration::new(u64::MAX, NANOS_PER_SEC - 1);
171
172    /// Creates a new `Duration` from the specified number of whole seconds and
173    /// additional nanoseconds.
174    ///
175    /// If the number of nanoseconds is greater than 1 billion (the number of
176    /// nanoseconds in a second), then it will carry over into the seconds provided.
177    ///
178    /// # Panics
179    ///
180    /// This constructor will panic if the carry from the nanoseconds overflows
181    /// the seconds counter.
182    ///
183    /// # Examples
184    ///
185    /// ```
186    /// use std::time::Duration;
187    ///
188    /// let five_seconds = Duration::new(5, 0);
189    /// ```
190    #[stable(feature = "duration", since = "1.3.0")]
191    #[inline]
192    #[must_use]
193    #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
194    pub const fn new(secs: u64, nanos: u32) -> Duration {
195        if nanos < NANOS_PER_SEC {
196            // SAFETY: nanos < NANOS_PER_SEC, therefore nanos is within the valid range
197            Duration { secs, nanos: unsafe { Nanoseconds::new_unchecked(nanos) } }
198        } else {
199            let secs = secs
200                .checked_add((nanos / NANOS_PER_SEC) as u64)
201                .expect("overflow in Duration::new");
202            let nanos = nanos % NANOS_PER_SEC;
203            // SAFETY: nanos % NANOS_PER_SEC < NANOS_PER_SEC, therefore nanos is within the valid range
204            Duration { secs, nanos: unsafe { Nanoseconds::new_unchecked(nanos) } }
205        }
206    }
207
208    /// Creates a new `Duration` from the specified number of whole seconds.
209    ///
210    /// # Examples
211    ///
212    /// ```
213    /// use std::time::Duration;
214    ///
215    /// let duration = Duration::from_secs(5);
216    ///
217    /// assert_eq!(5, duration.as_secs());
218    /// assert_eq!(0, duration.subsec_nanos());
219    /// ```
220    #[stable(feature = "duration", since = "1.3.0")]
221    #[must_use]
222    #[inline]
223    #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
224    pub const fn from_secs(secs: u64) -> Duration {
225        Duration { secs, nanos: Nanoseconds::ZERO }
226    }
227
228    /// Creates a new `Duration` from the specified number of milliseconds.
229    ///
230    /// # Examples
231    ///
232    /// ```
233    /// use std::time::Duration;
234    ///
235    /// let duration = Duration::from_millis(2_569);
236    ///
237    /// assert_eq!(2, duration.as_secs());
238    /// assert_eq!(569_000_000, duration.subsec_nanos());
239    /// ```
240    #[stable(feature = "duration", since = "1.3.0")]
241    #[must_use]
242    #[inline]
243    #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
244    pub const fn from_millis(millis: u64) -> Duration {
245        let secs = millis / MILLIS_PER_SEC;
246        let subsec_millis = (millis % MILLIS_PER_SEC) as u32;
247        // SAFETY: (x % 1_000) * 1_000_000 < 1_000_000_000
248        //         => x % 1_000 < 1_000
249        let subsec_nanos = unsafe { Nanoseconds::new_unchecked(subsec_millis * NANOS_PER_MILLI) };
250
251        Duration { secs, nanos: subsec_nanos }
252    }
253
254    /// Creates a new `Duration` from the specified number of microseconds.
255    ///
256    /// # Examples
257    ///
258    /// ```
259    /// use std::time::Duration;
260    ///
261    /// let duration = Duration::from_micros(1_000_002);
262    ///
263    /// assert_eq!(1, duration.as_secs());
264    /// assert_eq!(2_000, duration.subsec_nanos());
265    /// ```
266    #[stable(feature = "duration_from_micros", since = "1.27.0")]
267    #[must_use]
268    #[inline]
269    #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
270    pub const fn from_micros(micros: u64) -> Duration {
271        let secs = micros / MICROS_PER_SEC;
272        let subsec_micros = (micros % MICROS_PER_SEC) as u32;
273        // SAFETY: (x % 1_000_000) * 1_000 < 1_000_000_000
274        //         => x % 1_000_000 < 1_000_000
275        let subsec_nanos = unsafe { Nanoseconds::new_unchecked(subsec_micros * NANOS_PER_MICRO) };
276
277        Duration { secs, nanos: subsec_nanos }
278    }
279
280    /// Creates a new `Duration` from the specified number of nanoseconds.
281    ///
282    /// Note: Using this on the return value of `as_nanos()` might cause unexpected behavior:
283    /// `as_nanos()` returns a u128, and can return values that do not fit in u64, e.g. 585 years.
284    /// Instead, consider using the pattern `Duration::new(d.as_secs(), d.subsec_nanos())`
285    /// if you cannot copy/clone the Duration directly.
286    ///
287    /// # Examples
288    ///
289    /// ```
290    /// use std::time::Duration;
291    ///
292    /// let duration = Duration::from_nanos(1_000_000_123);
293    ///
294    /// assert_eq!(1, duration.as_secs());
295    /// assert_eq!(123, duration.subsec_nanos());
296    /// ```
297    #[stable(feature = "duration_extras", since = "1.27.0")]
298    #[must_use]
299    #[inline]
300    #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
301    pub const fn from_nanos(nanos: u64) -> Duration {
302        const NANOS_PER_SEC: u64 = self::NANOS_PER_SEC as u64;
303        let secs = nanos / NANOS_PER_SEC;
304        let subsec_nanos = (nanos % NANOS_PER_SEC) as u32;
305        // SAFETY: x % 1_000_000_000 < 1_000_000_000
306        let subsec_nanos = unsafe { Nanoseconds::new_unchecked(subsec_nanos) };
307
308        Duration { secs, nanos: subsec_nanos }
309    }
310
311    /// Creates a new `Duration` from the specified number of weeks.
312    ///
313    /// # Panics
314    ///
315    /// Panics if the given number of weeks overflows the `Duration` size.
316    ///
317    /// # Examples
318    ///
319    /// ```
320    /// #![feature(duration_constructors)]
321    /// use std::time::Duration;
322    ///
323    /// let duration = Duration::from_weeks(4);
324    ///
325    /// assert_eq!(4 * 7 * 24 * 60 * 60, duration.as_secs());
326    /// assert_eq!(0, duration.subsec_nanos());
327    /// ```
328    #[unstable(feature = "duration_constructors", issue = "120301")]
329    #[must_use]
330    #[inline]
331    pub const fn from_weeks(weeks: u64) -> Duration {
332        if weeks > u64::MAX / (SECS_PER_MINUTE * MINS_PER_HOUR * HOURS_PER_DAY * DAYS_PER_WEEK) {
333            panic!("overflow in Duration::from_weeks");
334        }
335
336        Duration::from_secs(weeks * MINS_PER_HOUR * SECS_PER_MINUTE * HOURS_PER_DAY * DAYS_PER_WEEK)
337    }
338
339    /// Creates a new `Duration` from the specified number of days.
340    ///
341    /// # Panics
342    ///
343    /// Panics if the given number of days overflows the `Duration` size.
344    ///
345    /// # Examples
346    ///
347    /// ```
348    /// #![feature(duration_constructors)]
349    /// use std::time::Duration;
350    ///
351    /// let duration = Duration::from_days(7);
352    ///
353    /// assert_eq!(7 * 24 * 60 * 60, duration.as_secs());
354    /// assert_eq!(0, duration.subsec_nanos());
355    /// ```
356    #[unstable(feature = "duration_constructors", issue = "120301")]
357    #[must_use]
358    #[inline]
359    pub const fn from_days(days: u64) -> Duration {
360        if days > u64::MAX / (SECS_PER_MINUTE * MINS_PER_HOUR * HOURS_PER_DAY) {
361            panic!("overflow in Duration::from_days");
362        }
363
364        Duration::from_secs(days * MINS_PER_HOUR * SECS_PER_MINUTE * HOURS_PER_DAY)
365    }
366
367    /// Creates a new `Duration` from the specified number of hours.
368    ///
369    /// # Panics
370    ///
371    /// Panics if the given number of hours overflows the `Duration` size.
372    ///
373    /// # Examples
374    ///
375    /// ```
376    /// #![feature(duration_constructors_lite)]
377    /// use std::time::Duration;
378    ///
379    /// let duration = Duration::from_hours(6);
380    ///
381    /// assert_eq!(6 * 60 * 60, duration.as_secs());
382    /// assert_eq!(0, duration.subsec_nanos());
383    /// ```
384    #[unstable(feature = "duration_constructors_lite", issue = "140881")]
385    #[must_use]
386    #[inline]
387    pub const fn from_hours(hours: u64) -> Duration {
388        if hours > u64::MAX / (SECS_PER_MINUTE * MINS_PER_HOUR) {
389            panic!("overflow in Duration::from_hours");
390        }
391
392        Duration::from_secs(hours * MINS_PER_HOUR * SECS_PER_MINUTE)
393    }
394
395    /// Creates a new `Duration` from the specified number of minutes.
396    ///
397    /// # Panics
398    ///
399    /// Panics if the given number of minutes overflows the `Duration` size.
400    ///
401    /// # Examples
402    ///
403    /// ```
404    /// #![feature(duration_constructors_lite)]
405    /// use std::time::Duration;
406    ///
407    /// let duration = Duration::from_mins(10);
408    ///
409    /// assert_eq!(10 * 60, duration.as_secs());
410    /// assert_eq!(0, duration.subsec_nanos());
411    /// ```
412    #[unstable(feature = "duration_constructors_lite", issue = "140881")]
413    #[must_use]
414    #[inline]
415    pub const fn from_mins(mins: u64) -> Duration {
416        if mins > u64::MAX / SECS_PER_MINUTE {
417            panic!("overflow in Duration::from_mins");
418        }
419
420        Duration::from_secs(mins * SECS_PER_MINUTE)
421    }
422
423    /// Returns true if this `Duration` spans no time.
424    ///
425    /// # Examples
426    ///
427    /// ```
428    /// use std::time::Duration;
429    ///
430    /// assert!(Duration::ZERO.is_zero());
431    /// assert!(Duration::new(0, 0).is_zero());
432    /// assert!(Duration::from_nanos(0).is_zero());
433    /// assert!(Duration::from_secs(0).is_zero());
434    ///
435    /// assert!(!Duration::new(1, 1).is_zero());
436    /// assert!(!Duration::from_nanos(1).is_zero());
437    /// assert!(!Duration::from_secs(1).is_zero());
438    /// ```
439    #[must_use]
440    #[stable(feature = "duration_zero", since = "1.53.0")]
441    #[rustc_const_stable(feature = "duration_zero", since = "1.53.0")]
442    #[inline]
443    pub const fn is_zero(&self) -> bool {
444        self.secs == 0 && self.nanos.as_inner() == 0
445    }
446
447    /// Returns the number of _whole_ seconds contained by this `Duration`.
448    ///
449    /// The returned value does not include the fractional (nanosecond) part of the
450    /// duration, which can be obtained using [`subsec_nanos`].
451    ///
452    /// # Examples
453    ///
454    /// ```
455    /// use std::time::Duration;
456    ///
457    /// let duration = Duration::new(5, 730_023_852);
458    /// assert_eq!(duration.as_secs(), 5);
459    /// ```
460    ///
461    /// To determine the total number of seconds represented by the `Duration`
462    /// including the fractional part, use [`as_secs_f64`] or [`as_secs_f32`]
463    ///
464    /// [`as_secs_f64`]: Duration::as_secs_f64
465    /// [`as_secs_f32`]: Duration::as_secs_f32
466    /// [`subsec_nanos`]: Duration::subsec_nanos
467    #[stable(feature = "duration", since = "1.3.0")]
468    #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
469    #[must_use]
470    #[inline]
471    pub const fn as_secs(&self) -> u64 {
472        self.secs
473    }
474
475    /// Returns the fractional part of this `Duration`, in whole milliseconds.
476    ///
477    /// This method does **not** return the length of the duration when
478    /// represented by milliseconds. The returned number always represents a
479    /// fractional portion of a second (i.e., it is less than one thousand).
480    ///
481    /// # Examples
482    ///
483    /// ```
484    /// use std::time::Duration;
485    ///
486    /// let duration = Duration::from_millis(5_432);
487    /// assert_eq!(duration.as_secs(), 5);
488    /// assert_eq!(duration.subsec_millis(), 432);
489    /// ```
490    #[stable(feature = "duration_extras", since = "1.27.0")]
491    #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
492    #[must_use]
493    #[inline]
494    pub const fn subsec_millis(&self) -> u32 {
495        self.nanos.as_inner() / NANOS_PER_MILLI
496    }
497
498    /// Returns the fractional part of this `Duration`, in whole microseconds.
499    ///
500    /// This method does **not** return the length of the duration when
501    /// represented by microseconds. The returned number always represents a
502    /// fractional portion of a second (i.e., it is less than one million).
503    ///
504    /// # Examples
505    ///
506    /// ```
507    /// use std::time::Duration;
508    ///
509    /// let duration = Duration::from_micros(1_234_567);
510    /// assert_eq!(duration.as_secs(), 1);
511    /// assert_eq!(duration.subsec_micros(), 234_567);
512    /// ```
513    #[stable(feature = "duration_extras", since = "1.27.0")]
514    #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
515    #[must_use]
516    #[inline]
517    pub const fn subsec_micros(&self) -> u32 {
518        self.nanos.as_inner() / NANOS_PER_MICRO
519    }
520
521    /// Returns the fractional part of this `Duration`, in nanoseconds.
522    ///
523    /// This method does **not** return the length of the duration when
524    /// represented by nanoseconds. The returned number always represents a
525    /// fractional portion of a second (i.e., it is less than one billion).
526    ///
527    /// # Examples
528    ///
529    /// ```
530    /// use std::time::Duration;
531    ///
532    /// let duration = Duration::from_millis(5_010);
533    /// assert_eq!(duration.as_secs(), 5);
534    /// assert_eq!(duration.subsec_nanos(), 10_000_000);
535    /// ```
536    #[stable(feature = "duration", since = "1.3.0")]
537    #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
538    #[must_use]
539    #[inline]
540    pub const fn subsec_nanos(&self) -> u32 {
541        self.nanos.as_inner()
542    }
543
544    /// Returns the total number of whole milliseconds contained by this `Duration`.
545    ///
546    /// # Examples
547    ///
548    /// ```
549    /// use std::time::Duration;
550    ///
551    /// let duration = Duration::new(5, 730_023_852);
552    /// assert_eq!(duration.as_millis(), 5_730);
553    /// ```
554    #[stable(feature = "duration_as_u128", since = "1.33.0")]
555    #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
556    #[must_use]
557    #[inline]
558    pub const fn as_millis(&self) -> u128 {
559        self.secs as u128 * MILLIS_PER_SEC as u128
560            + (self.nanos.as_inner() / NANOS_PER_MILLI) as u128
561    }
562
563    /// Returns the total number of whole microseconds contained by this `Duration`.
564    ///
565    /// # Examples
566    ///
567    /// ```
568    /// use std::time::Duration;
569    ///
570    /// let duration = Duration::new(5, 730_023_852);
571    /// assert_eq!(duration.as_micros(), 5_730_023);
572    /// ```
573    #[stable(feature = "duration_as_u128", since = "1.33.0")]
574    #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
575    #[must_use]
576    #[inline]
577    pub const fn as_micros(&self) -> u128 {
578        self.secs as u128 * MICROS_PER_SEC as u128
579            + (self.nanos.as_inner() / NANOS_PER_MICRO) as u128
580    }
581
582    /// Returns the total number of nanoseconds contained by this `Duration`.
583    ///
584    /// # Examples
585    ///
586    /// ```
587    /// use std::time::Duration;
588    ///
589    /// let duration = Duration::new(5, 730_023_852);
590    /// assert_eq!(duration.as_nanos(), 5_730_023_852);
591    /// ```
592    #[stable(feature = "duration_as_u128", since = "1.33.0")]
593    #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
594    #[must_use]
595    #[inline]
596    pub const fn as_nanos(&self) -> u128 {
597        self.secs as u128 * NANOS_PER_SEC as u128 + self.nanos.as_inner() as u128
598    }
599
600    /// Computes the absolute difference between `self` and `other`.
601    ///
602    /// # Examples
603    ///
604    /// ```
605    /// use std::time::Duration;
606    ///
607    /// assert_eq!(Duration::new(100, 0).abs_diff(Duration::new(80, 0)), Duration::new(20, 0));
608    /// assert_eq!(Duration::new(100, 400_000_000).abs_diff(Duration::new(110, 0)), Duration::new(9, 600_000_000));
609    /// ```
610    #[stable(feature = "duration_abs_diff", since = "1.81.0")]
611    #[rustc_const_stable(feature = "duration_abs_diff", since = "1.81.0")]
612    #[must_use = "this returns the result of the operation, \
613                  without modifying the original"]
614    #[inline]
615    pub const fn abs_diff(self, other: Duration) -> Duration {
616        if let Some(res) = self.checked_sub(other) { res } else { other.checked_sub(self).unwrap() }
617    }
618
619    /// Checked `Duration` addition. Computes `self + other`, returning [`None`]
620    /// if overflow occurred.
621    ///
622    /// # Examples
623    ///
624    /// ```
625    /// use std::time::Duration;
626    ///
627    /// assert_eq!(Duration::new(0, 0).checked_add(Duration::new(0, 1)), Some(Duration::new(0, 1)));
628    /// assert_eq!(Duration::new(1, 0).checked_add(Duration::new(u64::MAX, 0)), None);
629    /// ```
630    #[stable(feature = "duration_checked_ops", since = "1.16.0")]
631    #[must_use = "this returns the result of the operation, \
632                  without modifying the original"]
633    #[inline]
634    #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
635    pub const fn checked_add(self, rhs: Duration) -> Option<Duration> {
636        if let Some(mut secs) = self.secs.checked_add(rhs.secs) {
637            let mut nanos = self.nanos.as_inner() + rhs.nanos.as_inner();
638            if nanos >= NANOS_PER_SEC {
639                nanos -= NANOS_PER_SEC;
640                if let Some(new_secs) = secs.checked_add(1) {
641                    secs = new_secs;
642                } else {
643                    return None;
644                }
645            }
646            debug_assert!(nanos < NANOS_PER_SEC);
647            Some(Duration::new(secs, nanos))
648        } else {
649            None
650        }
651    }
652
653    /// Saturating `Duration` addition. Computes `self + other`, returning [`Duration::MAX`]
654    /// if overflow occurred.
655    ///
656    /// # Examples
657    ///
658    /// ```
659    /// #![feature(duration_constants)]
660    /// use std::time::Duration;
661    ///
662    /// assert_eq!(Duration::new(0, 0).saturating_add(Duration::new(0, 1)), Duration::new(0, 1));
663    /// assert_eq!(Duration::new(1, 0).saturating_add(Duration::new(u64::MAX, 0)), Duration::MAX);
664    /// ```
665    #[stable(feature = "duration_saturating_ops", since = "1.53.0")]
666    #[must_use = "this returns the result of the operation, \
667                  without modifying the original"]
668    #[inline]
669    #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
670    pub const fn saturating_add(self, rhs: Duration) -> Duration {
671        match self.checked_add(rhs) {
672            Some(res) => res,
673            None => Duration::MAX,
674        }
675    }
676
677    /// Checked `Duration` subtraction. Computes `self - other`, returning [`None`]
678    /// if the result would be negative or if overflow occurred.
679    ///
680    /// # Examples
681    ///
682    /// ```
683    /// use std::time::Duration;
684    ///
685    /// assert_eq!(Duration::new(0, 1).checked_sub(Duration::new(0, 0)), Some(Duration::new(0, 1)));
686    /// assert_eq!(Duration::new(0, 0).checked_sub(Duration::new(0, 1)), None);
687    /// ```
688    #[stable(feature = "duration_checked_ops", since = "1.16.0")]
689    #[must_use = "this returns the result of the operation, \
690                  without modifying the original"]
691    #[inline]
692    #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
693    pub const fn checked_sub(self, rhs: Duration) -> Option<Duration> {
694        if let Some(mut secs) = self.secs.checked_sub(rhs.secs) {
695            let nanos = if self.nanos.as_inner() >= rhs.nanos.as_inner() {
696                self.nanos.as_inner() - rhs.nanos.as_inner()
697            } else if let Some(sub_secs) = secs.checked_sub(1) {
698                secs = sub_secs;
699                self.nanos.as_inner() + NANOS_PER_SEC - rhs.nanos.as_inner()
700            } else {
701                return None;
702            };
703            debug_assert!(nanos < NANOS_PER_SEC);
704            Some(Duration::new(secs, nanos))
705        } else {
706            None
707        }
708    }
709
710    /// Saturating `Duration` subtraction. Computes `self - other`, returning [`Duration::ZERO`]
711    /// if the result would be negative or if overflow occurred.
712    ///
713    /// # Examples
714    ///
715    /// ```
716    /// use std::time::Duration;
717    ///
718    /// assert_eq!(Duration::new(0, 1).saturating_sub(Duration::new(0, 0)), Duration::new(0, 1));
719    /// assert_eq!(Duration::new(0, 0).saturating_sub(Duration::new(0, 1)), Duration::ZERO);
720    /// ```
721    #[stable(feature = "duration_saturating_ops", since = "1.53.0")]
722    #[must_use = "this returns the result of the operation, \
723                  without modifying the original"]
724    #[inline]
725    #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
726    pub const fn saturating_sub(self, rhs: Duration) -> Duration {
727        match self.checked_sub(rhs) {
728            Some(res) => res,
729            None => Duration::ZERO,
730        }
731    }
732
733    /// Checked `Duration` multiplication. Computes `self * other`, returning
734    /// [`None`] if overflow occurred.
735    ///
736    /// # Examples
737    ///
738    /// ```
739    /// use std::time::Duration;
740    ///
741    /// assert_eq!(Duration::new(0, 500_000_001).checked_mul(2), Some(Duration::new(1, 2)));
742    /// assert_eq!(Duration::new(u64::MAX - 1, 0).checked_mul(2), None);
743    /// ```
744    #[stable(feature = "duration_checked_ops", since = "1.16.0")]
745    #[must_use = "this returns the result of the operation, \
746                  without modifying the original"]
747    #[inline]
748    #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
749    pub const fn checked_mul(self, rhs: u32) -> Option<Duration> {
750        // Multiply nanoseconds as u64, because it cannot overflow that way.
751        let total_nanos = self.nanos.as_inner() as u64 * rhs as u64;
752        let extra_secs = total_nanos / (NANOS_PER_SEC as u64);
753        let nanos = (total_nanos % (NANOS_PER_SEC as u64)) as u32;
754        // FIXME(const-hack): use `and_then` once that is possible.
755        if let Some(s) = self.secs.checked_mul(rhs as u64) {
756            if let Some(secs) = s.checked_add(extra_secs) {
757                debug_assert!(nanos < NANOS_PER_SEC);
758                return Some(Duration::new(secs, nanos));
759            }
760        }
761        None
762    }
763
764    /// Saturating `Duration` multiplication. Computes `self * other`, returning
765    /// [`Duration::MAX`] if overflow occurred.
766    ///
767    /// # Examples
768    ///
769    /// ```
770    /// #![feature(duration_constants)]
771    /// use std::time::Duration;
772    ///
773    /// assert_eq!(Duration::new(0, 500_000_001).saturating_mul(2), Duration::new(1, 2));
774    /// assert_eq!(Duration::new(u64::MAX - 1, 0).saturating_mul(2), Duration::MAX);
775    /// ```
776    #[stable(feature = "duration_saturating_ops", since = "1.53.0")]
777    #[must_use = "this returns the result of the operation, \
778                  without modifying the original"]
779    #[inline]
780    #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
781    pub const fn saturating_mul(self, rhs: u32) -> Duration {
782        match self.checked_mul(rhs) {
783            Some(res) => res,
784            None => Duration::MAX,
785        }
786    }
787
788    /// Checked `Duration` division. Computes `self / other`, returning [`None`]
789    /// if `other == 0`.
790    ///
791    /// # Examples
792    ///
793    /// ```
794    /// use std::time::Duration;
795    ///
796    /// assert_eq!(Duration::new(2, 0).checked_div(2), Some(Duration::new(1, 0)));
797    /// assert_eq!(Duration::new(1, 0).checked_div(2), Some(Duration::new(0, 500_000_000)));
798    /// assert_eq!(Duration::new(2, 0).checked_div(0), None);
799    /// ```
800    #[stable(feature = "duration_checked_ops", since = "1.16.0")]
801    #[must_use = "this returns the result of the operation, \
802                  without modifying the original"]
803    #[inline]
804    #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
805    pub const fn checked_div(self, rhs: u32) -> Option<Duration> {
806        if rhs != 0 {
807            let (secs, extra_secs) = (self.secs / (rhs as u64), self.secs % (rhs as u64));
808            let (mut nanos, extra_nanos) =
809                (self.nanos.as_inner() / rhs, self.nanos.as_inner() % rhs);
810            nanos +=
811                ((extra_secs * (NANOS_PER_SEC as u64) + extra_nanos as u64) / (rhs as u64)) as u32;
812            debug_assert!(nanos < NANOS_PER_SEC);
813            Some(Duration::new(secs, nanos))
814        } else {
815            None
816        }
817    }
818
819    /// Returns the number of seconds contained by this `Duration` as `f64`.
820    ///
821    /// The returned value includes the fractional (nanosecond) part of the duration.
822    ///
823    /// # Examples
824    /// ```
825    /// use std::time::Duration;
826    ///
827    /// let dur = Duration::new(2, 700_000_000);
828    /// assert_eq!(dur.as_secs_f64(), 2.7);
829    /// ```
830    #[stable(feature = "duration_float", since = "1.38.0")]
831    #[must_use]
832    #[inline]
833    #[rustc_const_stable(feature = "duration_consts_float", since = "1.83.0")]
834    pub const fn as_secs_f64(&self) -> f64 {
835        (self.secs as f64) + (self.nanos.as_inner() as f64) / (NANOS_PER_SEC as f64)
836    }
837
838    /// Returns the number of seconds contained by this `Duration` as `f32`.
839    ///
840    /// The returned value includes the fractional (nanosecond) part of the duration.
841    ///
842    /// # Examples
843    /// ```
844    /// use std::time::Duration;
845    ///
846    /// let dur = Duration::new(2, 700_000_000);
847    /// assert_eq!(dur.as_secs_f32(), 2.7);
848    /// ```
849    #[stable(feature = "duration_float", since = "1.38.0")]
850    #[must_use]
851    #[inline]
852    #[rustc_const_stable(feature = "duration_consts_float", since = "1.83.0")]
853    pub const fn as_secs_f32(&self) -> f32 {
854        (self.secs as f32) + (self.nanos.as_inner() as f32) / (NANOS_PER_SEC as f32)
855    }
856
857    /// Returns the number of milliseconds contained by this `Duration` as `f64`.
858    ///
859    /// The returned value includes the fractional (nanosecond) part of the duration.
860    ///
861    /// # Examples
862    /// ```
863    /// #![feature(duration_millis_float)]
864    /// use std::time::Duration;
865    ///
866    /// let dur = Duration::new(2, 345_678_000);
867    /// assert_eq!(dur.as_millis_f64(), 2_345.678);
868    /// ```
869    #[unstable(feature = "duration_millis_float", issue = "122451")]
870    #[must_use]
871    #[inline]
872    pub const fn as_millis_f64(&self) -> f64 {
873        (self.secs as f64) * (MILLIS_PER_SEC as f64)
874            + (self.nanos.as_inner() as f64) / (NANOS_PER_MILLI as f64)
875    }
876
877    /// Returns the number of milliseconds contained by this `Duration` as `f32`.
878    ///
879    /// The returned value includes the fractional (nanosecond) part of the duration.
880    ///
881    /// # Examples
882    /// ```
883    /// #![feature(duration_millis_float)]
884    /// use std::time::Duration;
885    ///
886    /// let dur = Duration::new(2, 345_678_000);
887    /// assert_eq!(dur.as_millis_f32(), 2_345.678);
888    /// ```
889    #[unstable(feature = "duration_millis_float", issue = "122451")]
890    #[must_use]
891    #[inline]
892    pub const fn as_millis_f32(&self) -> f32 {
893        (self.secs as f32) * (MILLIS_PER_SEC as f32)
894            + (self.nanos.as_inner() as f32) / (NANOS_PER_MILLI as f32)
895    }
896
897    /// Creates a new `Duration` from the specified number of seconds represented
898    /// as `f64`.
899    ///
900    /// # Panics
901    /// This constructor will panic if `secs` is negative, overflows `Duration` or not finite.
902    ///
903    /// # Examples
904    /// ```
905    /// use std::time::Duration;
906    ///
907    /// let res = Duration::from_secs_f64(0.0);
908    /// assert_eq!(res, Duration::new(0, 0));
909    /// let res = Duration::from_secs_f64(1e-20);
910    /// assert_eq!(res, Duration::new(0, 0));
911    /// let res = Duration::from_secs_f64(4.2e-7);
912    /// assert_eq!(res, Duration::new(0, 420));
913    /// let res = Duration::from_secs_f64(2.7);
914    /// assert_eq!(res, Duration::new(2, 700_000_000));
915    /// let res = Duration::from_secs_f64(3e10);
916    /// assert_eq!(res, Duration::new(30_000_000_000, 0));
917    /// // subnormal float
918    /// let res = Duration::from_secs_f64(f64::from_bits(1));
919    /// assert_eq!(res, Duration::new(0, 0));
920    /// // conversion uses rounding
921    /// let res = Duration::from_secs_f64(0.999e-9);
922    /// assert_eq!(res, Duration::new(0, 1));
923    /// ```
924    #[stable(feature = "duration_float", since = "1.38.0")]
925    #[must_use]
926    #[inline]
927    pub fn from_secs_f64(secs: f64) -> Duration {
928        match Duration::try_from_secs_f64(secs) {
929            Ok(v) => v,
930            Err(e) => panic!("{}", e.description()),
931        }
932    }
933
934    /// Creates a new `Duration` from the specified number of seconds represented
935    /// as `f32`.
936    ///
937    /// # Panics
938    /// This constructor will panic if `secs` is negative, overflows `Duration` or not finite.
939    ///
940    /// # Examples
941    /// ```
942    /// use std::time::Duration;
943    ///
944    /// let res = Duration::from_secs_f32(0.0);
945    /// assert_eq!(res, Duration::new(0, 0));
946    /// let res = Duration::from_secs_f32(1e-20);
947    /// assert_eq!(res, Duration::new(0, 0));
948    /// let res = Duration::from_secs_f32(4.2e-7);
949    /// assert_eq!(res, Duration::new(0, 420));
950    /// let res = Duration::from_secs_f32(2.7);
951    /// assert_eq!(res, Duration::new(2, 700_000_048));
952    /// let res = Duration::from_secs_f32(3e10);
953    /// assert_eq!(res, Duration::new(30_000_001_024, 0));
954    /// // subnormal float
955    /// let res = Duration::from_secs_f32(f32::from_bits(1));
956    /// assert_eq!(res, Duration::new(0, 0));
957    /// // conversion uses rounding
958    /// let res = Duration::from_secs_f32(0.999e-9);
959    /// assert_eq!(res, Duration::new(0, 1));
960    /// ```
961    #[stable(feature = "duration_float", since = "1.38.0")]
962    #[must_use]
963    #[inline]
964    pub fn from_secs_f32(secs: f32) -> Duration {
965        match Duration::try_from_secs_f32(secs) {
966            Ok(v) => v,
967            Err(e) => panic!("{}", e.description()),
968        }
969    }
970
971    /// Multiplies `Duration` by `f64`.
972    ///
973    /// # Panics
974    /// This method will panic if result is negative, overflows `Duration` or not finite.
975    ///
976    /// # Examples
977    /// ```
978    /// use std::time::Duration;
979    ///
980    /// let dur = Duration::new(2, 700_000_000);
981    /// assert_eq!(dur.mul_f64(3.14), Duration::new(8, 478_000_000));
982    /// assert_eq!(dur.mul_f64(3.14e5), Duration::new(847_800, 0));
983    /// ```
984    #[stable(feature = "duration_float", since = "1.38.0")]
985    #[must_use = "this returns the result of the operation, \
986                  without modifying the original"]
987    #[inline]
988    pub fn mul_f64(self, rhs: f64) -> Duration {
989        Duration::from_secs_f64(rhs * self.as_secs_f64())
990    }
991
992    /// Multiplies `Duration` by `f32`.
993    ///
994    /// # Panics
995    /// This method will panic if result is negative, overflows `Duration` or not finite.
996    ///
997    /// # Examples
998    /// ```
999    /// use std::time::Duration;
1000    ///
1001    /// let dur = Duration::new(2, 700_000_000);
1002    /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_641));
1003    /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847_800, 0));
1004    /// ```
1005    #[stable(feature = "duration_float", since = "1.38.0")]
1006    #[must_use = "this returns the result of the operation, \
1007                  without modifying the original"]
1008    #[inline]
1009    pub fn mul_f32(self, rhs: f32) -> Duration {
1010        Duration::from_secs_f32(rhs * self.as_secs_f32())
1011    }
1012
1013    /// Divides `Duration` by `f64`.
1014    ///
1015    /// # Panics
1016    /// This method will panic if result is negative, overflows `Duration` or not finite.
1017    ///
1018    /// # Examples
1019    /// ```
1020    /// use std::time::Duration;
1021    ///
1022    /// let dur = Duration::new(2, 700_000_000);
1023    /// assert_eq!(dur.div_f64(3.14), Duration::new(0, 859_872_611));
1024    /// assert_eq!(dur.div_f64(3.14e5), Duration::new(0, 8_599));
1025    /// ```
1026    #[stable(feature = "duration_float", since = "1.38.0")]
1027    #[must_use = "this returns the result of the operation, \
1028                  without modifying the original"]
1029    #[inline]
1030    pub fn div_f64(self, rhs: f64) -> Duration {
1031        Duration::from_secs_f64(self.as_secs_f64() / rhs)
1032    }
1033
1034    /// Divides `Duration` by `f32`.
1035    ///
1036    /// # Panics
1037    /// This method will panic if result is negative, overflows `Duration` or not finite.
1038    ///
1039    /// # Examples
1040    /// ```
1041    /// use std::time::Duration;
1042    ///
1043    /// let dur = Duration::new(2, 700_000_000);
1044    /// // note that due to rounding errors result is slightly
1045    /// // different from 0.859_872_611
1046    /// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_580));
1047    /// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_599));
1048    /// ```
1049    #[stable(feature = "duration_float", since = "1.38.0")]
1050    #[must_use = "this returns the result of the operation, \
1051                  without modifying the original"]
1052    #[inline]
1053    pub fn div_f32(self, rhs: f32) -> Duration {
1054        Duration::from_secs_f32(self.as_secs_f32() / rhs)
1055    }
1056
1057    /// Divides `Duration` by `Duration` and returns `f64`.
1058    ///
1059    /// # Examples
1060    /// ```
1061    /// use std::time::Duration;
1062    ///
1063    /// let dur1 = Duration::new(2, 700_000_000);
1064    /// let dur2 = Duration::new(5, 400_000_000);
1065    /// assert_eq!(dur1.div_duration_f64(dur2), 0.5);
1066    /// ```
1067    #[stable(feature = "div_duration", since = "1.80.0")]
1068    #[must_use = "this returns the result of the operation, \
1069                  without modifying the original"]
1070    #[inline]
1071    #[rustc_const_stable(feature = "duration_consts_float", since = "1.83.0")]
1072    pub const fn div_duration_f64(self, rhs: Duration) -> f64 {
1073        let self_nanos =
1074            (self.secs as f64) * (NANOS_PER_SEC as f64) + (self.nanos.as_inner() as f64);
1075        let rhs_nanos = (rhs.secs as f64) * (NANOS_PER_SEC as f64) + (rhs.nanos.as_inner() as f64);
1076        self_nanos / rhs_nanos
1077    }
1078
1079    /// Divides `Duration` by `Duration` and returns `f32`.
1080    ///
1081    /// # Examples
1082    /// ```
1083    /// use std::time::Duration;
1084    ///
1085    /// let dur1 = Duration::new(2, 700_000_000);
1086    /// let dur2 = Duration::new(5, 400_000_000);
1087    /// assert_eq!(dur1.div_duration_f32(dur2), 0.5);
1088    /// ```
1089    #[stable(feature = "div_duration", since = "1.80.0")]
1090    #[must_use = "this returns the result of the operation, \
1091                  without modifying the original"]
1092    #[inline]
1093    #[rustc_const_stable(feature = "duration_consts_float", since = "1.83.0")]
1094    pub const fn div_duration_f32(self, rhs: Duration) -> f32 {
1095        let self_nanos =
1096            (self.secs as f32) * (NANOS_PER_SEC as f32) + (self.nanos.as_inner() as f32);
1097        let rhs_nanos = (rhs.secs as f32) * (NANOS_PER_SEC as f32) + (rhs.nanos.as_inner() as f32);
1098        self_nanos / rhs_nanos
1099    }
1100}
1101
1102#[stable(feature = "duration", since = "1.3.0")]
1103impl Add for Duration {
1104    type Output = Duration;
1105
1106    #[inline]
1107    fn add(self, rhs: Duration) -> Duration {
1108        self.checked_add(rhs).expect("overflow when adding durations")
1109    }
1110}
1111
1112#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
1113impl AddAssign for Duration {
1114    #[inline]
1115    fn add_assign(&mut self, rhs: Duration) {
1116        *self = *self + rhs;
1117    }
1118}
1119
1120#[stable(feature = "duration", since = "1.3.0")]
1121impl Sub for Duration {
1122    type Output = Duration;
1123
1124    #[inline]
1125    fn sub(self, rhs: Duration) -> Duration {
1126        self.checked_sub(rhs).expect("overflow when subtracting durations")
1127    }
1128}
1129
1130#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
1131impl SubAssign for Duration {
1132    #[inline]
1133    fn sub_assign(&mut self, rhs: Duration) {
1134        *self = *self - rhs;
1135    }
1136}
1137
1138#[stable(feature = "duration", since = "1.3.0")]
1139impl Mul<u32> for Duration {
1140    type Output = Duration;
1141
1142    #[inline]
1143    fn mul(self, rhs: u32) -> Duration {
1144        self.checked_mul(rhs).expect("overflow when multiplying duration by scalar")
1145    }
1146}
1147
1148#[stable(feature = "symmetric_u32_duration_mul", since = "1.31.0")]
1149impl Mul<Duration> for u32 {
1150    type Output = Duration;
1151
1152    #[inline]
1153    fn mul(self, rhs: Duration) -> Duration {
1154        rhs * self
1155    }
1156}
1157
1158#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
1159impl MulAssign<u32> for Duration {
1160    #[inline]
1161    fn mul_assign(&mut self, rhs: u32) {
1162        *self = *self * rhs;
1163    }
1164}
1165
1166#[stable(feature = "duration", since = "1.3.0")]
1167impl Div<u32> for Duration {
1168    type Output = Duration;
1169
1170    #[inline]
1171    #[track_caller]
1172    fn div(self, rhs: u32) -> Duration {
1173        self.checked_div(rhs).expect("divide by zero error when dividing duration by scalar")
1174    }
1175}
1176
1177#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
1178impl DivAssign<u32> for Duration {
1179    #[inline]
1180    #[track_caller]
1181    fn div_assign(&mut self, rhs: u32) {
1182        *self = *self / rhs;
1183    }
1184}
1185
1186macro_rules! sum_durations {
1187    ($iter:expr) => {{
1188        let mut total_secs: u64 = 0;
1189        let mut total_nanos: u64 = 0;
1190
1191        for entry in $iter {
1192            total_secs =
1193                total_secs.checked_add(entry.secs).expect("overflow in iter::sum over durations");
1194            total_nanos = match total_nanos.checked_add(entry.nanos.as_inner() as u64) {
1195                Some(n) => n,
1196                None => {
1197                    total_secs = total_secs
1198                        .checked_add(total_nanos / NANOS_PER_SEC as u64)
1199                        .expect("overflow in iter::sum over durations");
1200                    (total_nanos % NANOS_PER_SEC as u64) + entry.nanos.as_inner() as u64
1201                }
1202            };
1203        }
1204        total_secs = total_secs
1205            .checked_add(total_nanos / NANOS_PER_SEC as u64)
1206            .expect("overflow in iter::sum over durations");
1207        total_nanos = total_nanos % NANOS_PER_SEC as u64;
1208        Duration::new(total_secs, total_nanos as u32)
1209    }};
1210}
1211
1212#[stable(feature = "duration_sum", since = "1.16.0")]
1213impl Sum for Duration {
1214    fn sum<I: Iterator<Item = Duration>>(iter: I) -> Duration {
1215        sum_durations!(iter)
1216    }
1217}
1218
1219#[stable(feature = "duration_sum", since = "1.16.0")]
1220impl<'a> Sum<&'a Duration> for Duration {
1221    fn sum<I: Iterator<Item = &'a Duration>>(iter: I) -> Duration {
1222        sum_durations!(iter)
1223    }
1224}
1225
1226#[stable(feature = "duration_debug_impl", since = "1.27.0")]
1227impl fmt::Debug for Duration {
1228    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1229        /// Formats a floating point number in decimal notation.
1230        ///
1231        /// The number is given as the `integer_part` and a fractional part.
1232        /// The value of the fractional part is `fractional_part / divisor`. So
1233        /// `integer_part` = 3, `fractional_part` = 12 and `divisor` = 100
1234        /// represents the number `3.012`. Trailing zeros are omitted.
1235        ///
1236        /// `divisor` must not be above 100_000_000. It also should be a power
1237        /// of 10, everything else doesn't make sense. `fractional_part` has
1238        /// to be less than `10 * divisor`!
1239        ///
1240        /// A prefix and postfix may be added. The whole thing is padded
1241        /// to the formatter's `width`, if specified.
1242        fn fmt_decimal(
1243            f: &mut fmt::Formatter<'_>,
1244            integer_part: u64,
1245            mut fractional_part: u32,
1246            mut divisor: u32,
1247            prefix: &str,
1248            postfix: &str,
1249        ) -> fmt::Result {
1250            // Encode the fractional part into a temporary buffer. The buffer
1251            // only need to hold 9 elements, because `fractional_part` has to
1252            // be smaller than 10^9. The buffer is prefilled with '0' digits
1253            // to simplify the code below.
1254            let mut buf = [b'0'; 9];
1255
1256            // The next digit is written at this position
1257            let mut pos = 0;
1258
1259            // We keep writing digits into the buffer while there are non-zero
1260            // digits left and we haven't written enough digits yet.
1261            while fractional_part > 0 && pos < f.precision().unwrap_or(9) {
1262                // Write new digit into the buffer
1263                buf[pos] = b'0' + (fractional_part / divisor) as u8;
1264
1265                fractional_part %= divisor;
1266                divisor /= 10;
1267                pos += 1;
1268            }
1269
1270            // If a precision < 9 was specified, there may be some non-zero
1271            // digits left that weren't written into the buffer. In that case we
1272            // need to perform rounding to match the semantics of printing
1273            // normal floating point numbers. However, we only need to do work
1274            // when rounding up. This happens if the first digit of the
1275            // remaining ones is >= 5.
1276            let integer_part = if fractional_part > 0 && fractional_part >= divisor * 5 {
1277                // Round up the number contained in the buffer. We go through
1278                // the buffer backwards and keep track of the carry.
1279                let mut rev_pos = pos;
1280                let mut carry = true;
1281                while carry && rev_pos > 0 {
1282                    rev_pos -= 1;
1283
1284                    // If the digit in the buffer is not '9', we just need to
1285                    // increment it and can stop then (since we don't have a
1286                    // carry anymore). Otherwise, we set it to '0' (overflow)
1287                    // and continue.
1288                    if buf[rev_pos] < b'9' {
1289                        buf[rev_pos] += 1;
1290                        carry = false;
1291                    } else {
1292                        buf[rev_pos] = b'0';
1293                    }
1294                }
1295
1296                // If we still have the carry bit set, that means that we set
1297                // the whole buffer to '0's and need to increment the integer
1298                // part.
1299                if carry {
1300                    // If `integer_part == u64::MAX` and precision < 9, any
1301                    // carry of the overflow during rounding of the
1302                    // `fractional_part` into the `integer_part` will cause the
1303                    // `integer_part` itself to overflow. Avoid this by using an
1304                    // `Option<u64>`, with `None` representing `u64::MAX + 1`.
1305                    integer_part.checked_add(1)
1306                } else {
1307                    Some(integer_part)
1308                }
1309            } else {
1310                Some(integer_part)
1311            };
1312
1313            // Determine the end of the buffer: if precision is set, we just
1314            // use as many digits from the buffer (capped to 9). If it isn't
1315            // set, we only use all digits up to the last non-zero one.
1316            let end = f.precision().map(|p| crate::cmp::min(p, 9)).unwrap_or(pos);
1317
1318            // This closure emits the formatted duration without emitting any
1319            // padding (padding is calculated below).
1320            let emit_without_padding = |f: &mut fmt::Formatter<'_>| {
1321                if let Some(integer_part) = integer_part {
1322                    write!(f, "{}{}", prefix, integer_part)?;
1323                } else {
1324                    // u64::MAX + 1 == 18446744073709551616
1325                    write!(f, "{}18446744073709551616", prefix)?;
1326                }
1327
1328                // Write the decimal point and the fractional part (if any).
1329                if end > 0 {
1330                    // SAFETY: We are only writing ASCII digits into the buffer and
1331                    // it was initialized with '0's, so it contains valid UTF8.
1332                    let s = unsafe { crate::str::from_utf8_unchecked(&buf[..end]) };
1333
1334                    // If the user request a precision > 9, we pad '0's at the end.
1335                    let w = f.precision().unwrap_or(pos);
1336                    write!(f, ".{:0<width$}", s, width = w)?;
1337                }
1338
1339                write!(f, "{}", postfix)
1340            };
1341
1342            match f.width() {
1343                None => {
1344                    // No `width` specified. There's no need to calculate the
1345                    // length of the output in this case, just emit it.
1346                    emit_without_padding(f)
1347                }
1348                Some(requested_w) => {
1349                    // A `width` was specified. Calculate the actual width of
1350                    // the output in order to calculate the required padding.
1351                    // It consists of 4 parts:
1352                    // 1. The prefix: is either "+" or "", so we can just use len().
1353                    // 2. The postfix: can be "µs" so we have to count UTF8 characters.
1354                    let mut actual_w = prefix.len() + postfix.chars().count();
1355                    // 3. The integer part:
1356                    if let Some(integer_part) = integer_part {
1357                        if let Some(log) = integer_part.checked_ilog10() {
1358                            // integer_part is > 0, so has length log10(x)+1
1359                            actual_w += 1 + log as usize;
1360                        } else {
1361                            // integer_part is 0, so has length 1.
1362                            actual_w += 1;
1363                        }
1364                    } else {
1365                        // integer_part is u64::MAX + 1, so has length 20
1366                        actual_w += 20;
1367                    }
1368                    // 4. The fractional part (if any):
1369                    if end > 0 {
1370                        let frac_part_w = f.precision().unwrap_or(pos);
1371                        actual_w += 1 + frac_part_w;
1372                    }
1373
1374                    if requested_w <= actual_w {
1375                        // Output is already longer than `width`, so don't pad.
1376                        emit_without_padding(f)
1377                    } else {
1378                        // We need to add padding. Use the `Formatter::padding` helper function.
1379                        let default_align = fmt::Alignment::Left;
1380                        let post_padding =
1381                            f.padding((requested_w - actual_w) as u16, default_align)?;
1382                        emit_without_padding(f)?;
1383                        post_padding.write(f)
1384                    }
1385                }
1386            }
1387        }
1388
1389        // Print leading '+' sign if requested
1390        let prefix = if f.sign_plus() { "+" } else { "" };
1391
1392        if self.secs > 0 {
1393            fmt_decimal(f, self.secs, self.nanos.as_inner(), NANOS_PER_SEC / 10, prefix, "s")
1394        } else if self.nanos.as_inner() >= NANOS_PER_MILLI {
1395            fmt_decimal(
1396                f,
1397                (self.nanos.as_inner() / NANOS_PER_MILLI) as u64,
1398                self.nanos.as_inner() % NANOS_PER_MILLI,
1399                NANOS_PER_MILLI / 10,
1400                prefix,
1401                "ms",
1402            )
1403        } else if self.nanos.as_inner() >= NANOS_PER_MICRO {
1404            fmt_decimal(
1405                f,
1406                (self.nanos.as_inner() / NANOS_PER_MICRO) as u64,
1407                self.nanos.as_inner() % NANOS_PER_MICRO,
1408                NANOS_PER_MICRO / 10,
1409                prefix,
1410                "µs",
1411            )
1412        } else {
1413            fmt_decimal(f, self.nanos.as_inner() as u64, 0, 1, prefix, "ns")
1414        }
1415    }
1416}
1417
1418/// An error which can be returned when converting a floating-point value of seconds
1419/// into a [`Duration`].
1420///
1421/// This error is used as the error type for [`Duration::try_from_secs_f32`] and
1422/// [`Duration::try_from_secs_f64`].
1423///
1424/// # Example
1425///
1426/// ```
1427/// use std::time::Duration;
1428///
1429/// if let Err(e) = Duration::try_from_secs_f32(-1.0) {
1430///     println!("Failed conversion to Duration: {e}");
1431/// }
1432/// ```
1433#[derive(Debug, Clone, PartialEq, Eq)]
1434#[stable(feature = "duration_checked_float", since = "1.66.0")]
1435pub struct TryFromFloatSecsError {
1436    kind: TryFromFloatSecsErrorKind,
1437}
1438
1439impl TryFromFloatSecsError {
1440    const fn description(&self) -> &'static str {
1441        match self.kind {
1442            TryFromFloatSecsErrorKind::Negative => {
1443                "cannot convert float seconds to Duration: value is negative"
1444            }
1445            TryFromFloatSecsErrorKind::OverflowOrNan => {
1446                "cannot convert float seconds to Duration: value is either too big or NaN"
1447            }
1448        }
1449    }
1450}
1451
1452#[stable(feature = "duration_checked_float", since = "1.66.0")]
1453impl fmt::Display for TryFromFloatSecsError {
1454    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1455        self.description().fmt(f)
1456    }
1457}
1458
1459#[derive(Debug, Clone, PartialEq, Eq)]
1460enum TryFromFloatSecsErrorKind {
1461    // Value is negative.
1462    Negative,
1463    // Value is either too big to be represented as `Duration` or `NaN`.
1464    OverflowOrNan,
1465}
1466
1467macro_rules! try_from_secs {
1468    (
1469        secs = $secs: expr,
1470        mantissa_bits = $mant_bits: literal,
1471        exponent_bits = $exp_bits: literal,
1472        offset = $offset: literal,
1473        bits_ty = $bits_ty:ty,
1474        double_ty = $double_ty:ty,
1475    ) => {{
1476        const MIN_EXP: i16 = 1 - (1i16 << $exp_bits) / 2;
1477        const MANT_MASK: $bits_ty = (1 << $mant_bits) - 1;
1478        const EXP_MASK: $bits_ty = (1 << $exp_bits) - 1;
1479
1480        if $secs < 0.0 {
1481            return Err(TryFromFloatSecsError { kind: TryFromFloatSecsErrorKind::Negative });
1482        }
1483
1484        let bits = $secs.to_bits();
1485        let mant = (bits & MANT_MASK) | (MANT_MASK + 1);
1486        let exp = ((bits >> $mant_bits) & EXP_MASK) as i16 + MIN_EXP;
1487
1488        let (secs, nanos) = if exp < -31 {
1489            // the input represents less than 1ns and can not be rounded to it
1490            (0u64, 0u32)
1491        } else if exp < 0 {
1492            // the input is less than 1 second
1493            let t = <$double_ty>::from(mant) << ($offset + exp);
1494            let nanos_offset = $mant_bits + $offset;
1495            let nanos_tmp = u128::from(NANOS_PER_SEC) * u128::from(t);
1496            let nanos = (nanos_tmp >> nanos_offset) as u32;
1497
1498            let rem_mask = (1 << nanos_offset) - 1;
1499            let rem_msb_mask = 1 << (nanos_offset - 1);
1500            let rem = nanos_tmp & rem_mask;
1501            let is_tie = rem == rem_msb_mask;
1502            let is_even = (nanos & 1) == 0;
1503            let rem_msb = nanos_tmp & rem_msb_mask == 0;
1504            let add_ns = !(rem_msb || (is_even && is_tie));
1505
1506            // f32 does not have enough precision to trigger the second branch
1507            // since it can not represent numbers between 0.999_999_940_395 and 1.0.
1508            let nanos = nanos + add_ns as u32;
1509            if ($mant_bits == 23) || (nanos != NANOS_PER_SEC) { (0, nanos) } else { (1, 0) }
1510        } else if exp < $mant_bits {
1511            let secs = u64::from(mant >> ($mant_bits - exp));
1512            let t = <$double_ty>::from((mant << exp) & MANT_MASK);
1513            let nanos_offset = $mant_bits;
1514            let nanos_tmp = <$double_ty>::from(NANOS_PER_SEC) * t;
1515            let nanos = (nanos_tmp >> nanos_offset) as u32;
1516
1517            let rem_mask = (1 << nanos_offset) - 1;
1518            let rem_msb_mask = 1 << (nanos_offset - 1);
1519            let rem = nanos_tmp & rem_mask;
1520            let is_tie = rem == rem_msb_mask;
1521            let is_even = (nanos & 1) == 0;
1522            let rem_msb = nanos_tmp & rem_msb_mask == 0;
1523            let add_ns = !(rem_msb || (is_even && is_tie));
1524
1525            // f32 does not have enough precision to trigger the second branch.
1526            // For example, it can not represent numbers between 1.999_999_880...
1527            // and 2.0. Bigger values result in even smaller precision of the
1528            // fractional part.
1529            let nanos = nanos + add_ns as u32;
1530            if ($mant_bits == 23) || (nanos != NANOS_PER_SEC) {
1531                (secs, nanos)
1532            } else {
1533                (secs + 1, 0)
1534            }
1535        } else if exp < 64 {
1536            // the input has no fractional part
1537            let secs = u64::from(mant) << (exp - $mant_bits);
1538            (secs, 0)
1539        } else {
1540            return Err(TryFromFloatSecsError { kind: TryFromFloatSecsErrorKind::OverflowOrNan });
1541        };
1542
1543        Ok(Duration::new(secs, nanos))
1544    }};
1545}
1546
1547impl Duration {
1548    /// The checked version of [`from_secs_f32`].
1549    ///
1550    /// [`from_secs_f32`]: Duration::from_secs_f32
1551    ///
1552    /// This constructor will return an `Err` if `secs` is negative, overflows `Duration` or not finite.
1553    ///
1554    /// # Examples
1555    /// ```
1556    /// use std::time::Duration;
1557    ///
1558    /// let res = Duration::try_from_secs_f32(0.0);
1559    /// assert_eq!(res, Ok(Duration::new(0, 0)));
1560    /// let res = Duration::try_from_secs_f32(1e-20);
1561    /// assert_eq!(res, Ok(Duration::new(0, 0)));
1562    /// let res = Duration::try_from_secs_f32(4.2e-7);
1563    /// assert_eq!(res, Ok(Duration::new(0, 420)));
1564    /// let res = Duration::try_from_secs_f32(2.7);
1565    /// assert_eq!(res, Ok(Duration::new(2, 700_000_048)));
1566    /// let res = Duration::try_from_secs_f32(3e10);
1567    /// assert_eq!(res, Ok(Duration::new(30_000_001_024, 0)));
1568    /// // subnormal float:
1569    /// let res = Duration::try_from_secs_f32(f32::from_bits(1));
1570    /// assert_eq!(res, Ok(Duration::new(0, 0)));
1571    ///
1572    /// let res = Duration::try_from_secs_f32(-5.0);
1573    /// assert!(res.is_err());
1574    /// let res = Duration::try_from_secs_f32(f32::NAN);
1575    /// assert!(res.is_err());
1576    /// let res = Duration::try_from_secs_f32(2e19);
1577    /// assert!(res.is_err());
1578    ///
1579    /// // the conversion uses rounding with tie resolution to even
1580    /// let res = Duration::try_from_secs_f32(0.999e-9);
1581    /// assert_eq!(res, Ok(Duration::new(0, 1)));
1582    ///
1583    /// // this float represents exactly 976562.5e-9
1584    /// let val = f32::from_bits(0x3A80_0000);
1585    /// let res = Duration::try_from_secs_f32(val);
1586    /// assert_eq!(res, Ok(Duration::new(0, 976_562)));
1587    ///
1588    /// // this float represents exactly 2929687.5e-9
1589    /// let val = f32::from_bits(0x3B40_0000);
1590    /// let res = Duration::try_from_secs_f32(val);
1591    /// assert_eq!(res, Ok(Duration::new(0, 2_929_688)));
1592    ///
1593    /// // this float represents exactly 1.000_976_562_5
1594    /// let val = f32::from_bits(0x3F802000);
1595    /// let res = Duration::try_from_secs_f32(val);
1596    /// assert_eq!(res, Ok(Duration::new(1, 976_562)));
1597    ///
1598    /// // this float represents exactly 1.002_929_687_5
1599    /// let val = f32::from_bits(0x3F806000);
1600    /// let res = Duration::try_from_secs_f32(val);
1601    /// assert_eq!(res, Ok(Duration::new(1, 2_929_688)));
1602    /// ```
1603    #[stable(feature = "duration_checked_float", since = "1.66.0")]
1604    #[inline]
1605    pub fn try_from_secs_f32(secs: f32) -> Result<Duration, TryFromFloatSecsError> {
1606        try_from_secs!(
1607            secs = secs,
1608            mantissa_bits = 23,
1609            exponent_bits = 8,
1610            offset = 41,
1611            bits_ty = u32,
1612            double_ty = u64,
1613        )
1614    }
1615
1616    /// The checked version of [`from_secs_f64`].
1617    ///
1618    /// [`from_secs_f64`]: Duration::from_secs_f64
1619    ///
1620    /// This constructor will return an `Err` if `secs` is negative, overflows `Duration` or not finite.
1621    ///
1622    /// # Examples
1623    /// ```
1624    /// use std::time::Duration;
1625    ///
1626    /// let res = Duration::try_from_secs_f64(0.0);
1627    /// assert_eq!(res, Ok(Duration::new(0, 0)));
1628    /// let res = Duration::try_from_secs_f64(1e-20);
1629    /// assert_eq!(res, Ok(Duration::new(0, 0)));
1630    /// let res = Duration::try_from_secs_f64(4.2e-7);
1631    /// assert_eq!(res, Ok(Duration::new(0, 420)));
1632    /// let res = Duration::try_from_secs_f64(2.7);
1633    /// assert_eq!(res, Ok(Duration::new(2, 700_000_000)));
1634    /// let res = Duration::try_from_secs_f64(3e10);
1635    /// assert_eq!(res, Ok(Duration::new(30_000_000_000, 0)));
1636    /// // subnormal float
1637    /// let res = Duration::try_from_secs_f64(f64::from_bits(1));
1638    /// assert_eq!(res, Ok(Duration::new(0, 0)));
1639    ///
1640    /// let res = Duration::try_from_secs_f64(-5.0);
1641    /// assert!(res.is_err());
1642    /// let res = Duration::try_from_secs_f64(f64::NAN);
1643    /// assert!(res.is_err());
1644    /// let res = Duration::try_from_secs_f64(2e19);
1645    /// assert!(res.is_err());
1646    ///
1647    /// // the conversion uses rounding with tie resolution to even
1648    /// let res = Duration::try_from_secs_f64(0.999e-9);
1649    /// assert_eq!(res, Ok(Duration::new(0, 1)));
1650    /// let res = Duration::try_from_secs_f64(0.999_999_999_499);
1651    /// assert_eq!(res, Ok(Duration::new(0, 999_999_999)));
1652    /// let res = Duration::try_from_secs_f64(0.999_999_999_501);
1653    /// assert_eq!(res, Ok(Duration::new(1, 0)));
1654    /// let res = Duration::try_from_secs_f64(42.999_999_999_499);
1655    /// assert_eq!(res, Ok(Duration::new(42, 999_999_999)));
1656    /// let res = Duration::try_from_secs_f64(42.999_999_999_501);
1657    /// assert_eq!(res, Ok(Duration::new(43, 0)));
1658    ///
1659    /// // this float represents exactly 976562.5e-9
1660    /// let val = f64::from_bits(0x3F50_0000_0000_0000);
1661    /// let res = Duration::try_from_secs_f64(val);
1662    /// assert_eq!(res, Ok(Duration::new(0, 976_562)));
1663    ///
1664    /// // this float represents exactly 2929687.5e-9
1665    /// let val = f64::from_bits(0x3F68_0000_0000_0000);
1666    /// let res = Duration::try_from_secs_f64(val);
1667    /// assert_eq!(res, Ok(Duration::new(0, 2_929_688)));
1668    ///
1669    /// // this float represents exactly 1.000_976_562_5
1670    /// let val = f64::from_bits(0x3FF0_0400_0000_0000);
1671    /// let res = Duration::try_from_secs_f64(val);
1672    /// assert_eq!(res, Ok(Duration::new(1, 976_562)));
1673    ///
1674    /// // this float represents exactly 1.002_929_687_5
1675    /// let val = f64::from_bits(0x3_FF00_C000_0000_000);
1676    /// let res = Duration::try_from_secs_f64(val);
1677    /// assert_eq!(res, Ok(Duration::new(1, 2_929_688)));
1678    /// ```
1679    #[stable(feature = "duration_checked_float", since = "1.66.0")]
1680    #[inline]
1681    pub fn try_from_secs_f64(secs: f64) -> Result<Duration, TryFromFloatSecsError> {
1682        try_from_secs!(
1683            secs = secs,
1684            mantissa_bits = 52,
1685            exponent_bits = 11,
1686            offset = 44,
1687            bits_ty = u64,
1688            double_ty = u128,
1689        )
1690    }
1691}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy