]> git.lizzy.rs Git - rust.git/blob - library/core/src/time.rs
Rollup merge of #82372 - RalfJung:unsafe-cell, r=KodrAus
[rust.git] / library / core / src / time.rs
1 #![stable(feature = "duration_core", since = "1.25.0")]
2
3 //! Temporal quantification.
4 //!
5 //! Example:
6 //!
7 //! ```
8 //! use std::time::Duration;
9 //!
10 //! let five_seconds = Duration::new(5, 0);
11 //! // both declarations are equivalent
12 //! assert_eq!(Duration::new(5, 0), Duration::from_secs(5));
13 //! ```
14
15 use crate::fmt;
16 use crate::iter::Sum;
17 use crate::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
18
19 const NANOS_PER_SEC: u32 = 1_000_000_000;
20 const NANOS_PER_MILLI: u32 = 1_000_000;
21 const NANOS_PER_MICRO: u32 = 1_000;
22 const MILLIS_PER_SEC: u64 = 1_000;
23 const MICROS_PER_SEC: u64 = 1_000_000;
24
25 /// A `Duration` type to represent a span of time, typically used for system
26 /// timeouts.
27 ///
28 /// Each `Duration` is composed of a whole number of seconds and a fractional part
29 /// represented in nanoseconds. If the underlying system does not support
30 /// nanosecond-level precision, APIs binding a system timeout will typically round up
31 /// the number of nanoseconds.
32 ///
33 /// [`Duration`]s implement many common traits, including [`Add`], [`Sub`], and other
34 /// [`ops`] traits. It implements [`Default`] by returning a zero-length `Duration`.
35 ///
36 /// [`ops`]: crate::ops
37 ///
38 /// # Examples
39 ///
40 /// ```
41 /// use std::time::Duration;
42 ///
43 /// let five_seconds = Duration::new(5, 0);
44 /// let five_seconds_and_five_nanos = five_seconds + Duration::new(0, 5);
45 ///
46 /// assert_eq!(five_seconds_and_five_nanos.as_secs(), 5);
47 /// assert_eq!(five_seconds_and_five_nanos.subsec_nanos(), 5);
48 ///
49 /// let ten_millis = Duration::from_millis(10);
50 /// ```
51 #[stable(feature = "duration", since = "1.3.0")]
52 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
53 pub struct Duration {
54     secs: u64,
55     nanos: u32, // Always 0 <= nanos < NANOS_PER_SEC
56 }
57
58 impl Duration {
59     /// The duration of one second.
60     ///
61     /// # Examples
62     ///
63     /// ```
64     /// #![feature(duration_constants)]
65     /// use std::time::Duration;
66     ///
67     /// assert_eq!(Duration::SECOND, Duration::from_secs(1));
68     /// ```
69     #[unstable(feature = "duration_constants", issue = "57391")]
70     pub const SECOND: Duration = Duration::from_secs(1);
71
72     /// The duration of one millisecond.
73     ///
74     /// # Examples
75     ///
76     /// ```
77     /// #![feature(duration_constants)]
78     /// use std::time::Duration;
79     ///
80     /// assert_eq!(Duration::MILLISECOND, Duration::from_millis(1));
81     /// ```
82     #[unstable(feature = "duration_constants", issue = "57391")]
83     pub const MILLISECOND: Duration = Duration::from_millis(1);
84
85     /// The duration of one microsecond.
86     ///
87     /// # Examples
88     ///
89     /// ```
90     /// #![feature(duration_constants)]
91     /// use std::time::Duration;
92     ///
93     /// assert_eq!(Duration::MICROSECOND, Duration::from_micros(1));
94     /// ```
95     #[unstable(feature = "duration_constants", issue = "57391")]
96     pub const MICROSECOND: Duration = Duration::from_micros(1);
97
98     /// The duration of one nanosecond.
99     ///
100     /// # Examples
101     ///
102     /// ```
103     /// #![feature(duration_constants)]
104     /// use std::time::Duration;
105     ///
106     /// assert_eq!(Duration::NANOSECOND, Duration::from_nanos(1));
107     /// ```
108     #[unstable(feature = "duration_constants", issue = "57391")]
109     pub const NANOSECOND: Duration = Duration::from_nanos(1);
110
111     /// A duration of zero time.
112     ///
113     /// # Examples
114     ///
115     /// ```
116     /// #![feature(duration_zero)]
117     /// use std::time::Duration;
118     ///
119     /// let duration = Duration::ZERO;
120     /// assert!(duration.is_zero());
121     /// assert_eq!(duration.as_nanos(), 0);
122     /// ```
123     #[unstable(feature = "duration_zero", issue = "73544")]
124     pub const ZERO: Duration = Duration::from_nanos(0);
125
126     /// The maximum duration.
127     ///
128     /// It is roughly equal to a duration of 584,942,417,355 years.
129     ///
130     /// # Examples
131     ///
132     /// ```
133     /// #![feature(duration_constants)]
134     /// use std::time::Duration;
135     ///
136     /// assert_eq!(Duration::MAX, Duration::new(u64::MAX, 1_000_000_000 - 1));
137     /// ```
138     #[unstable(feature = "duration_constants", issue = "57391")]
139     pub const MAX: Duration = Duration::new(u64::MAX, NANOS_PER_SEC - 1);
140
141     /// Creates a new `Duration` from the specified number of whole seconds and
142     /// additional nanoseconds.
143     ///
144     /// If the number of nanoseconds is greater than 1 billion (the number of
145     /// nanoseconds in a second), then it will carry over into the seconds provided.
146     ///
147     /// # Panics
148     ///
149     /// This constructor will panic if the carry from the nanoseconds overflows
150     /// the seconds counter.
151     ///
152     /// # Examples
153     ///
154     /// ```
155     /// use std::time::Duration;
156     ///
157     /// let five_seconds = Duration::new(5, 0);
158     /// ```
159     #[stable(feature = "duration", since = "1.3.0")]
160     #[inline]
161     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
162     pub const fn new(secs: u64, nanos: u32) -> Duration {
163         let secs = match secs.checked_add((nanos / NANOS_PER_SEC) as u64) {
164             Some(secs) => secs,
165             None => panic!("overflow in Duration::new"),
166         };
167         let nanos = nanos % NANOS_PER_SEC;
168         Duration { secs, nanos }
169     }
170
171     /// Creates a new `Duration` from the specified number of whole seconds.
172     ///
173     /// # Examples
174     ///
175     /// ```
176     /// use std::time::Duration;
177     ///
178     /// let duration = Duration::from_secs(5);
179     ///
180     /// assert_eq!(5, duration.as_secs());
181     /// assert_eq!(0, duration.subsec_nanos());
182     /// ```
183     #[stable(feature = "duration", since = "1.3.0")]
184     #[inline]
185     #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
186     pub const fn from_secs(secs: u64) -> Duration {
187         Duration { secs, nanos: 0 }
188     }
189
190     /// Creates a new `Duration` from the specified number of milliseconds.
191     ///
192     /// # Examples
193     ///
194     /// ```
195     /// use std::time::Duration;
196     ///
197     /// let duration = Duration::from_millis(2569);
198     ///
199     /// assert_eq!(2, duration.as_secs());
200     /// assert_eq!(569_000_000, duration.subsec_nanos());
201     /// ```
202     #[stable(feature = "duration", since = "1.3.0")]
203     #[inline]
204     #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
205     pub const fn from_millis(millis: u64) -> Duration {
206         Duration {
207             secs: millis / MILLIS_PER_SEC,
208             nanos: ((millis % MILLIS_PER_SEC) as u32) * NANOS_PER_MILLI,
209         }
210     }
211
212     /// Creates a new `Duration` from the specified number of microseconds.
213     ///
214     /// # Examples
215     ///
216     /// ```
217     /// use std::time::Duration;
218     ///
219     /// let duration = Duration::from_micros(1_000_002);
220     ///
221     /// assert_eq!(1, duration.as_secs());
222     /// assert_eq!(2000, duration.subsec_nanos());
223     /// ```
224     #[stable(feature = "duration_from_micros", since = "1.27.0")]
225     #[inline]
226     #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
227     pub const fn from_micros(micros: u64) -> Duration {
228         Duration {
229             secs: micros / MICROS_PER_SEC,
230             nanos: ((micros % MICROS_PER_SEC) as u32) * NANOS_PER_MICRO,
231         }
232     }
233
234     /// Creates a new `Duration` from the specified number of nanoseconds.
235     ///
236     /// # Examples
237     ///
238     /// ```
239     /// use std::time::Duration;
240     ///
241     /// let duration = Duration::from_nanos(1_000_000_123);
242     ///
243     /// assert_eq!(1, duration.as_secs());
244     /// assert_eq!(123, duration.subsec_nanos());
245     /// ```
246     #[stable(feature = "duration_extras", since = "1.27.0")]
247     #[inline]
248     #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
249     pub const fn from_nanos(nanos: u64) -> Duration {
250         Duration {
251             secs: nanos / (NANOS_PER_SEC as u64),
252             nanos: (nanos % (NANOS_PER_SEC as u64)) as u32,
253         }
254     }
255
256     /// Returns true if this `Duration` spans no time.
257     ///
258     /// # Examples
259     ///
260     /// ```
261     /// #![feature(duration_zero)]
262     /// use std::time::Duration;
263     ///
264     /// assert!(Duration::ZERO.is_zero());
265     /// assert!(Duration::new(0, 0).is_zero());
266     /// assert!(Duration::from_nanos(0).is_zero());
267     /// assert!(Duration::from_secs(0).is_zero());
268     ///
269     /// assert!(!Duration::new(1, 1).is_zero());
270     /// assert!(!Duration::from_nanos(1).is_zero());
271     /// assert!(!Duration::from_secs(1).is_zero());
272     /// ```
273     #[unstable(feature = "duration_zero", issue = "73544")]
274     #[inline]
275     pub const fn is_zero(&self) -> bool {
276         self.secs == 0 && self.nanos == 0
277     }
278
279     /// Returns the number of _whole_ seconds contained by this `Duration`.
280     ///
281     /// The returned value does not include the fractional (nanosecond) part of the
282     /// duration, which can be obtained using [`subsec_nanos`].
283     ///
284     /// # Examples
285     ///
286     /// ```
287     /// use std::time::Duration;
288     ///
289     /// let duration = Duration::new(5, 730023852);
290     /// assert_eq!(duration.as_secs(), 5);
291     /// ```
292     ///
293     /// To determine the total number of seconds represented by the `Duration`,
294     /// use `as_secs` in combination with [`subsec_nanos`]:
295     ///
296     /// ```
297     /// use std::time::Duration;
298     ///
299     /// let duration = Duration::new(5, 730023852);
300     ///
301     /// assert_eq!(5.730023852,
302     ///            duration.as_secs() as f64
303     ///            + duration.subsec_nanos() as f64 * 1e-9);
304     /// ```
305     ///
306     /// [`subsec_nanos`]: Duration::subsec_nanos
307     #[stable(feature = "duration", since = "1.3.0")]
308     #[rustc_const_stable(feature = "duration", since = "1.32.0")]
309     #[inline]
310     pub const fn as_secs(&self) -> u64 {
311         self.secs
312     }
313
314     /// Returns the fractional part of this `Duration`, in whole milliseconds.
315     ///
316     /// This method does **not** return the length of the duration when
317     /// represented by milliseconds. The returned number always represents a
318     /// fractional portion of a second (i.e., it is less than one thousand).
319     ///
320     /// # Examples
321     ///
322     /// ```
323     /// use std::time::Duration;
324     ///
325     /// let duration = Duration::from_millis(5432);
326     /// assert_eq!(duration.as_secs(), 5);
327     /// assert_eq!(duration.subsec_millis(), 432);
328     /// ```
329     #[stable(feature = "duration_extras", since = "1.27.0")]
330     #[rustc_const_stable(feature = "duration_extras", since = "1.32.0")]
331     #[inline]
332     pub const fn subsec_millis(&self) -> u32 {
333         self.nanos / NANOS_PER_MILLI
334     }
335
336     /// Returns the fractional part of this `Duration`, in whole microseconds.
337     ///
338     /// This method does **not** return the length of the duration when
339     /// represented by microseconds. The returned number always represents a
340     /// fractional portion of a second (i.e., it is less than one million).
341     ///
342     /// # Examples
343     ///
344     /// ```
345     /// use std::time::Duration;
346     ///
347     /// let duration = Duration::from_micros(1_234_567);
348     /// assert_eq!(duration.as_secs(), 1);
349     /// assert_eq!(duration.subsec_micros(), 234_567);
350     /// ```
351     #[stable(feature = "duration_extras", since = "1.27.0")]
352     #[rustc_const_stable(feature = "duration_extras", since = "1.32.0")]
353     #[inline]
354     pub const fn subsec_micros(&self) -> u32 {
355         self.nanos / NANOS_PER_MICRO
356     }
357
358     /// Returns the fractional part of this `Duration`, in nanoseconds.
359     ///
360     /// This method does **not** return the length of the duration when
361     /// represented by nanoseconds. The returned number always represents a
362     /// fractional portion of a second (i.e., it is less than one billion).
363     ///
364     /// # Examples
365     ///
366     /// ```
367     /// use std::time::Duration;
368     ///
369     /// let duration = Duration::from_millis(5010);
370     /// assert_eq!(duration.as_secs(), 5);
371     /// assert_eq!(duration.subsec_nanos(), 10_000_000);
372     /// ```
373     #[stable(feature = "duration", since = "1.3.0")]
374     #[rustc_const_stable(feature = "duration", since = "1.32.0")]
375     #[inline]
376     pub const fn subsec_nanos(&self) -> u32 {
377         self.nanos
378     }
379
380     /// Returns the total number of whole milliseconds contained by this `Duration`.
381     ///
382     /// # Examples
383     ///
384     /// ```
385     /// use std::time::Duration;
386     ///
387     /// let duration = Duration::new(5, 730023852);
388     /// assert_eq!(duration.as_millis(), 5730);
389     /// ```
390     #[stable(feature = "duration_as_u128", since = "1.33.0")]
391     #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
392     #[inline]
393     pub const fn as_millis(&self) -> u128 {
394         self.secs as u128 * MILLIS_PER_SEC as u128 + (self.nanos / NANOS_PER_MILLI) as u128
395     }
396
397     /// Returns the total number of whole microseconds contained by this `Duration`.
398     ///
399     /// # Examples
400     ///
401     /// ```
402     /// use std::time::Duration;
403     ///
404     /// let duration = Duration::new(5, 730023852);
405     /// assert_eq!(duration.as_micros(), 5730023);
406     /// ```
407     #[stable(feature = "duration_as_u128", since = "1.33.0")]
408     #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
409     #[inline]
410     pub const fn as_micros(&self) -> u128 {
411         self.secs as u128 * MICROS_PER_SEC as u128 + (self.nanos / NANOS_PER_MICRO) as u128
412     }
413
414     /// Returns the total number of nanoseconds contained by this `Duration`.
415     ///
416     /// # Examples
417     ///
418     /// ```
419     /// use std::time::Duration;
420     ///
421     /// let duration = Duration::new(5, 730023852);
422     /// assert_eq!(duration.as_nanos(), 5730023852);
423     /// ```
424     #[stable(feature = "duration_as_u128", since = "1.33.0")]
425     #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
426     #[inline]
427     pub const fn as_nanos(&self) -> u128 {
428         self.secs as u128 * NANOS_PER_SEC as u128 + self.nanos as u128
429     }
430
431     /// Checked `Duration` addition. Computes `self + other`, returning [`None`]
432     /// if overflow occurred.
433     ///
434     /// # Examples
435     ///
436     /// Basic usage:
437     ///
438     /// ```
439     /// use std::time::Duration;
440     ///
441     /// assert_eq!(Duration::new(0, 0).checked_add(Duration::new(0, 1)), Some(Duration::new(0, 1)));
442     /// assert_eq!(Duration::new(1, 0).checked_add(Duration::new(u64::MAX, 0)), None);
443     /// ```
444     #[stable(feature = "duration_checked_ops", since = "1.16.0")]
445     #[inline]
446     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
447     pub const fn checked_add(self, rhs: Duration) -> Option<Duration> {
448         if let Some(mut secs) = self.secs.checked_add(rhs.secs) {
449             let mut nanos = self.nanos + rhs.nanos;
450             if nanos >= NANOS_PER_SEC {
451                 nanos -= NANOS_PER_SEC;
452                 if let Some(new_secs) = secs.checked_add(1) {
453                     secs = new_secs;
454                 } else {
455                     return None;
456                 }
457             }
458             debug_assert!(nanos < NANOS_PER_SEC);
459             Some(Duration { secs, nanos })
460         } else {
461             None
462         }
463     }
464
465     /// Saturating `Duration` addition. Computes `self + other`, returning [`Duration::MAX`]
466     /// if overflow occurred.
467     ///
468     /// # Examples
469     ///
470     /// ```
471     /// #![feature(duration_saturating_ops)]
472     /// #![feature(duration_constants)]
473     /// use std::time::Duration;
474     ///
475     /// assert_eq!(Duration::new(0, 0).saturating_add(Duration::new(0, 1)), Duration::new(0, 1));
476     /// assert_eq!(Duration::new(1, 0).saturating_add(Duration::new(u64::MAX, 0)), Duration::MAX);
477     /// ```
478     #[unstable(feature = "duration_saturating_ops", issue = "76416")]
479     #[inline]
480     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
481     pub const fn saturating_add(self, rhs: Duration) -> Duration {
482         match self.checked_add(rhs) {
483             Some(res) => res,
484             None => Duration::MAX,
485         }
486     }
487
488     /// Checked `Duration` subtraction. Computes `self - other`, returning [`None`]
489     /// if the result would be negative or if overflow occurred.
490     ///
491     /// # Examples
492     ///
493     /// Basic usage:
494     ///
495     /// ```
496     /// use std::time::Duration;
497     ///
498     /// assert_eq!(Duration::new(0, 1).checked_sub(Duration::new(0, 0)), Some(Duration::new(0, 1)));
499     /// assert_eq!(Duration::new(0, 0).checked_sub(Duration::new(0, 1)), None);
500     /// ```
501     #[stable(feature = "duration_checked_ops", since = "1.16.0")]
502     #[inline]
503     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
504     pub const fn checked_sub(self, rhs: Duration) -> Option<Duration> {
505         if let Some(mut secs) = self.secs.checked_sub(rhs.secs) {
506             let nanos = if self.nanos >= rhs.nanos {
507                 self.nanos - rhs.nanos
508             } else {
509                 if let Some(sub_secs) = secs.checked_sub(1) {
510                     secs = sub_secs;
511                     self.nanos + NANOS_PER_SEC - rhs.nanos
512                 } else {
513                     return None;
514                 }
515             };
516             debug_assert!(nanos < NANOS_PER_SEC);
517             Some(Duration { secs, nanos })
518         } else {
519             None
520         }
521     }
522
523     /// Saturating `Duration` subtraction. Computes `self - other`, returning [`Duration::ZERO`]
524     /// if the result would be negative or if overflow occurred.
525     ///
526     /// # Examples
527     ///
528     /// ```
529     /// #![feature(duration_saturating_ops)]
530     /// #![feature(duration_zero)]
531     /// use std::time::Duration;
532     ///
533     /// assert_eq!(Duration::new(0, 1).saturating_sub(Duration::new(0, 0)), Duration::new(0, 1));
534     /// assert_eq!(Duration::new(0, 0).saturating_sub(Duration::new(0, 1)), Duration::ZERO);
535     /// ```
536     #[unstable(feature = "duration_saturating_ops", issue = "76416")]
537     #[inline]
538     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
539     pub const fn saturating_sub(self, rhs: Duration) -> Duration {
540         match self.checked_sub(rhs) {
541             Some(res) => res,
542             None => Duration::ZERO,
543         }
544     }
545
546     /// Checked `Duration` multiplication. Computes `self * other`, returning
547     /// [`None`] if overflow occurred.
548     ///
549     /// # Examples
550     ///
551     /// Basic usage:
552     ///
553     /// ```
554     /// use std::time::Duration;
555     ///
556     /// assert_eq!(Duration::new(0, 500_000_001).checked_mul(2), Some(Duration::new(1, 2)));
557     /// assert_eq!(Duration::new(u64::MAX - 1, 0).checked_mul(2), None);
558     /// ```
559     #[stable(feature = "duration_checked_ops", since = "1.16.0")]
560     #[inline]
561     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
562     pub const fn checked_mul(self, rhs: u32) -> Option<Duration> {
563         // Multiply nanoseconds as u64, because it cannot overflow that way.
564         let total_nanos = self.nanos as u64 * rhs as u64;
565         let extra_secs = total_nanos / (NANOS_PER_SEC as u64);
566         let nanos = (total_nanos % (NANOS_PER_SEC as u64)) as u32;
567         if let Some(s) = self.secs.checked_mul(rhs as u64) {
568             if let Some(secs) = s.checked_add(extra_secs) {
569                 debug_assert!(nanos < NANOS_PER_SEC);
570                 return Some(Duration { secs, nanos });
571             }
572         }
573         None
574     }
575
576     /// Saturating `Duration` multiplication. Computes `self * other`, returning
577     /// [`Duration::MAX`] if overflow occurred.
578     ///
579     /// # Examples
580     ///
581     /// ```
582     /// #![feature(duration_saturating_ops)]
583     /// #![feature(duration_constants)]
584     /// use std::time::Duration;
585     ///
586     /// assert_eq!(Duration::new(0, 500_000_001).saturating_mul(2), Duration::new(1, 2));
587     /// assert_eq!(Duration::new(u64::MAX - 1, 0).saturating_mul(2), Duration::MAX);
588     /// ```
589     #[unstable(feature = "duration_saturating_ops", issue = "76416")]
590     #[inline]
591     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
592     pub const fn saturating_mul(self, rhs: u32) -> Duration {
593         match self.checked_mul(rhs) {
594             Some(res) => res,
595             None => Duration::MAX,
596         }
597     }
598
599     /// Checked `Duration` division. Computes `self / other`, returning [`None`]
600     /// if `other == 0`.
601     ///
602     /// # Examples
603     ///
604     /// Basic usage:
605     ///
606     /// ```
607     /// use std::time::Duration;
608     ///
609     /// assert_eq!(Duration::new(2, 0).checked_div(2), Some(Duration::new(1, 0)));
610     /// assert_eq!(Duration::new(1, 0).checked_div(2), Some(Duration::new(0, 500_000_000)));
611     /// assert_eq!(Duration::new(2, 0).checked_div(0), None);
612     /// ```
613     #[stable(feature = "duration_checked_ops", since = "1.16.0")]
614     #[inline]
615     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
616     pub const fn checked_div(self, rhs: u32) -> Option<Duration> {
617         if rhs != 0 {
618             let secs = self.secs / (rhs as u64);
619             let carry = self.secs - secs * (rhs as u64);
620             let extra_nanos = carry * (NANOS_PER_SEC as u64) / (rhs as u64);
621             let nanos = self.nanos / rhs + (extra_nanos as u32);
622             debug_assert!(nanos < NANOS_PER_SEC);
623             Some(Duration { secs, nanos })
624         } else {
625             None
626         }
627     }
628
629     /// Returns the number of seconds contained by this `Duration` as `f64`.
630     ///
631     /// The returned value does include the fractional (nanosecond) part of the duration.
632     ///
633     /// # Examples
634     /// ```
635     /// use std::time::Duration;
636     ///
637     /// let dur = Duration::new(2, 700_000_000);
638     /// assert_eq!(dur.as_secs_f64(), 2.7);
639     /// ```
640     #[stable(feature = "duration_float", since = "1.38.0")]
641     #[inline]
642     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
643     pub const fn as_secs_f64(&self) -> f64 {
644         (self.secs as f64) + (self.nanos as f64) / (NANOS_PER_SEC as f64)
645     }
646
647     /// Returns the number of seconds contained by this `Duration` as `f32`.
648     ///
649     /// The returned value does include the fractional (nanosecond) part of the duration.
650     ///
651     /// # Examples
652     /// ```
653     /// use std::time::Duration;
654     ///
655     /// let dur = Duration::new(2, 700_000_000);
656     /// assert_eq!(dur.as_secs_f32(), 2.7);
657     /// ```
658     #[stable(feature = "duration_float", since = "1.38.0")]
659     #[inline]
660     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
661     pub const fn as_secs_f32(&self) -> f32 {
662         (self.secs as f32) + (self.nanos as f32) / (NANOS_PER_SEC as f32)
663     }
664
665     /// Creates a new `Duration` from the specified number of seconds represented
666     /// as `f64`.
667     ///
668     /// # Panics
669     /// This constructor will panic if `secs` is not finite, negative or overflows `Duration`.
670     ///
671     /// # Examples
672     /// ```
673     /// use std::time::Duration;
674     ///
675     /// let dur = Duration::from_secs_f64(2.7);
676     /// assert_eq!(dur, Duration::new(2, 700_000_000));
677     /// ```
678     #[stable(feature = "duration_float", since = "1.38.0")]
679     #[inline]
680     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
681     pub const fn from_secs_f64(secs: f64) -> Duration {
682         const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1) * (NANOS_PER_SEC as u128)) as f64;
683         let nanos = secs * (NANOS_PER_SEC as f64);
684         if !nanos.is_finite() {
685             panic!("got non-finite value when converting float to duration");
686         }
687         if nanos >= MAX_NANOS_F64 {
688             panic!("overflow when converting float to duration");
689         }
690         if nanos < 0.0 {
691             panic!("underflow when converting float to duration");
692         }
693         let nanos = nanos as u128;
694         Duration {
695             secs: (nanos / (NANOS_PER_SEC as u128)) as u64,
696             nanos: (nanos % (NANOS_PER_SEC as u128)) as u32,
697         }
698     }
699
700     /// Creates a new `Duration` from the specified number of seconds represented
701     /// as `f32`.
702     ///
703     /// # Panics
704     /// This constructor will panic if `secs` is not finite, negative or overflows `Duration`.
705     ///
706     /// # Examples
707     /// ```
708     /// use std::time::Duration;
709     ///
710     /// let dur = Duration::from_secs_f32(2.7);
711     /// assert_eq!(dur, Duration::new(2, 700_000_000));
712     /// ```
713     #[stable(feature = "duration_float", since = "1.38.0")]
714     #[inline]
715     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
716     pub const fn from_secs_f32(secs: f32) -> Duration {
717         const MAX_NANOS_F32: f32 = ((u64::MAX as u128 + 1) * (NANOS_PER_SEC as u128)) as f32;
718         let nanos = secs * (NANOS_PER_SEC as f32);
719         if !nanos.is_finite() {
720             panic!("got non-finite value when converting float to duration");
721         }
722         if nanos >= MAX_NANOS_F32 {
723             panic!("overflow when converting float to duration");
724         }
725         if nanos < 0.0 {
726             panic!("underflow when converting float to duration");
727         }
728         let nanos = nanos as u128;
729         Duration {
730             secs: (nanos / (NANOS_PER_SEC as u128)) as u64,
731             nanos: (nanos % (NANOS_PER_SEC as u128)) as u32,
732         }
733     }
734
735     /// Multiplies `Duration` by `f64`.
736     ///
737     /// # Panics
738     /// This method will panic if result is not finite, negative or overflows `Duration`.
739     ///
740     /// # Examples
741     /// ```
742     /// use std::time::Duration;
743     ///
744     /// let dur = Duration::new(2, 700_000_000);
745     /// assert_eq!(dur.mul_f64(3.14), Duration::new(8, 478_000_000));
746     /// assert_eq!(dur.mul_f64(3.14e5), Duration::new(847_800, 0));
747     /// ```
748     #[stable(feature = "duration_float", since = "1.38.0")]
749     #[inline]
750     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
751     pub const fn mul_f64(self, rhs: f64) -> Duration {
752         Duration::from_secs_f64(rhs * self.as_secs_f64())
753     }
754
755     /// Multiplies `Duration` by `f32`.
756     ///
757     /// # Panics
758     /// This method will panic if result is not finite, negative or overflows `Duration`.
759     ///
760     /// # Examples
761     /// ```
762     /// use std::time::Duration;
763     ///
764     /// let dur = Duration::new(2, 700_000_000);
765     /// // note that due to rounding errors result is slightly different
766     /// // from 8.478 and 847800.0
767     /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_640));
768     /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847799, 969_120_256));
769     /// ```
770     #[stable(feature = "duration_float", since = "1.38.0")]
771     #[inline]
772     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
773     pub const fn mul_f32(self, rhs: f32) -> Duration {
774         Duration::from_secs_f32(rhs * self.as_secs_f32())
775     }
776
777     /// Divide `Duration` by `f64`.
778     ///
779     /// # Panics
780     /// This method will panic if result is not finite, negative or overflows `Duration`.
781     ///
782     /// # Examples
783     /// ```
784     /// use std::time::Duration;
785     ///
786     /// let dur = Duration::new(2, 700_000_000);
787     /// assert_eq!(dur.div_f64(3.14), Duration::new(0, 859_872_611));
788     /// // note that truncation is used, not rounding
789     /// assert_eq!(dur.div_f64(3.14e5), Duration::new(0, 8_598));
790     /// ```
791     #[stable(feature = "duration_float", since = "1.38.0")]
792     #[inline]
793     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
794     pub const fn div_f64(self, rhs: f64) -> Duration {
795         Duration::from_secs_f64(self.as_secs_f64() / rhs)
796     }
797
798     /// Divide `Duration` by `f32`.
799     ///
800     /// # Panics
801     /// This method will panic if result is not finite, negative or overflows `Duration`.
802     ///
803     /// # Examples
804     /// ```
805     /// use std::time::Duration;
806     ///
807     /// let dur = Duration::new(2, 700_000_000);
808     /// // note that due to rounding errors result is slightly
809     /// // different from 0.859_872_611
810     /// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_576));
811     /// // note that truncation is used, not rounding
812     /// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_598));
813     /// ```
814     #[stable(feature = "duration_float", since = "1.38.0")]
815     #[inline]
816     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
817     pub const fn div_f32(self, rhs: f32) -> Duration {
818         Duration::from_secs_f32(self.as_secs_f32() / rhs)
819     }
820
821     /// Divide `Duration` by `Duration` and return `f64`.
822     ///
823     /// # Examples
824     /// ```
825     /// #![feature(div_duration)]
826     /// use std::time::Duration;
827     ///
828     /// let dur1 = Duration::new(2, 700_000_000);
829     /// let dur2 = Duration::new(5, 400_000_000);
830     /// assert_eq!(dur1.div_duration_f64(dur2), 0.5);
831     /// ```
832     #[unstable(feature = "div_duration", issue = "63139")]
833     #[inline]
834     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
835     pub const fn div_duration_f64(self, rhs: Duration) -> f64 {
836         self.as_secs_f64() / rhs.as_secs_f64()
837     }
838
839     /// Divide `Duration` by `Duration` and return `f32`.
840     ///
841     /// # Examples
842     /// ```
843     /// #![feature(div_duration)]
844     /// use std::time::Duration;
845     ///
846     /// let dur1 = Duration::new(2, 700_000_000);
847     /// let dur2 = Duration::new(5, 400_000_000);
848     /// assert_eq!(dur1.div_duration_f32(dur2), 0.5);
849     /// ```
850     #[unstable(feature = "div_duration", issue = "63139")]
851     #[inline]
852     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
853     pub const fn div_duration_f32(self, rhs: Duration) -> f32 {
854         self.as_secs_f32() / rhs.as_secs_f32()
855     }
856 }
857
858 #[stable(feature = "duration", since = "1.3.0")]
859 impl Add for Duration {
860     type Output = Duration;
861
862     fn add(self, rhs: Duration) -> Duration {
863         self.checked_add(rhs).expect("overflow when adding durations")
864     }
865 }
866
867 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
868 impl AddAssign for Duration {
869     fn add_assign(&mut self, rhs: Duration) {
870         *self = *self + rhs;
871     }
872 }
873
874 #[stable(feature = "duration", since = "1.3.0")]
875 impl Sub for Duration {
876     type Output = Duration;
877
878     fn sub(self, rhs: Duration) -> Duration {
879         self.checked_sub(rhs).expect("overflow when subtracting durations")
880     }
881 }
882
883 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
884 impl SubAssign for Duration {
885     fn sub_assign(&mut self, rhs: Duration) {
886         *self = *self - rhs;
887     }
888 }
889
890 #[stable(feature = "duration", since = "1.3.0")]
891 impl Mul<u32> for Duration {
892     type Output = Duration;
893
894     fn mul(self, rhs: u32) -> Duration {
895         self.checked_mul(rhs).expect("overflow when multiplying duration by scalar")
896     }
897 }
898
899 #[stable(feature = "symmetric_u32_duration_mul", since = "1.31.0")]
900 impl Mul<Duration> for u32 {
901     type Output = Duration;
902
903     fn mul(self, rhs: Duration) -> Duration {
904         rhs * self
905     }
906 }
907
908 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
909 impl MulAssign<u32> for Duration {
910     fn mul_assign(&mut self, rhs: u32) {
911         *self = *self * rhs;
912     }
913 }
914
915 #[stable(feature = "duration", since = "1.3.0")]
916 impl Div<u32> for Duration {
917     type Output = Duration;
918
919     fn div(self, rhs: u32) -> Duration {
920         self.checked_div(rhs).expect("divide by zero error when dividing duration by scalar")
921     }
922 }
923
924 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
925 impl DivAssign<u32> for Duration {
926     fn div_assign(&mut self, rhs: u32) {
927         *self = *self / rhs;
928     }
929 }
930
931 macro_rules! sum_durations {
932     ($iter:expr) => {{
933         let mut total_secs: u64 = 0;
934         let mut total_nanos: u64 = 0;
935
936         for entry in $iter {
937             total_secs =
938                 total_secs.checked_add(entry.secs).expect("overflow in iter::sum over durations");
939             total_nanos = match total_nanos.checked_add(entry.nanos as u64) {
940                 Some(n) => n,
941                 None => {
942                     total_secs = total_secs
943                         .checked_add(total_nanos / NANOS_PER_SEC as u64)
944                         .expect("overflow in iter::sum over durations");
945                     (total_nanos % NANOS_PER_SEC as u64) + entry.nanos as u64
946                 }
947             };
948         }
949         total_secs = total_secs
950             .checked_add(total_nanos / NANOS_PER_SEC as u64)
951             .expect("overflow in iter::sum over durations");
952         total_nanos = total_nanos % NANOS_PER_SEC as u64;
953         Duration { secs: total_secs, nanos: total_nanos as u32 }
954     }};
955 }
956
957 #[stable(feature = "duration_sum", since = "1.16.0")]
958 impl Sum for Duration {
959     fn sum<I: Iterator<Item = Duration>>(iter: I) -> Duration {
960         sum_durations!(iter)
961     }
962 }
963
964 #[stable(feature = "duration_sum", since = "1.16.0")]
965 impl<'a> Sum<&'a Duration> for Duration {
966     fn sum<I: Iterator<Item = &'a Duration>>(iter: I) -> Duration {
967         sum_durations!(iter)
968     }
969 }
970
971 #[stable(feature = "duration_debug_impl", since = "1.27.0")]
972 impl fmt::Debug for Duration {
973     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
974         /// Formats a floating point number in decimal notation.
975         ///
976         /// The number is given as the `integer_part` and a fractional part.
977         /// The value of the fractional part is `fractional_part / divisor`. So
978         /// `integer_part` = 3, `fractional_part` = 12 and `divisor` = 100
979         /// represents the number `3.012`. Trailing zeros are omitted.
980         ///
981         /// `divisor` must not be above 100_000_000. It also should be a power
982         /// of 10, everything else doesn't make sense. `fractional_part` has
983         /// to be less than `10 * divisor`!
984         fn fmt_decimal(
985             f: &mut fmt::Formatter<'_>,
986             mut integer_part: u64,
987             mut fractional_part: u32,
988             mut divisor: u32,
989         ) -> fmt::Result {
990             // Encode the fractional part into a temporary buffer. The buffer
991             // only need to hold 9 elements, because `fractional_part` has to
992             // be smaller than 10^9. The buffer is prefilled with '0' digits
993             // to simplify the code below.
994             let mut buf = [b'0'; 9];
995
996             // The next digit is written at this position
997             let mut pos = 0;
998
999             // We keep writing digits into the buffer while there are non-zero
1000             // digits left and we haven't written enough digits yet.
1001             while fractional_part > 0 && pos < f.precision().unwrap_or(9) {
1002                 // Write new digit into the buffer
1003                 buf[pos] = b'0' + (fractional_part / divisor) as u8;
1004
1005                 fractional_part %= divisor;
1006                 divisor /= 10;
1007                 pos += 1;
1008             }
1009
1010             // If a precision < 9 was specified, there may be some non-zero
1011             // digits left that weren't written into the buffer. In that case we
1012             // need to perform rounding to match the semantics of printing
1013             // normal floating point numbers. However, we only need to do work
1014             // when rounding up. This happens if the first digit of the
1015             // remaining ones is >= 5.
1016             if fractional_part > 0 && fractional_part >= divisor * 5 {
1017                 // Round up the number contained in the buffer. We go through
1018                 // the buffer backwards and keep track of the carry.
1019                 let mut rev_pos = pos;
1020                 let mut carry = true;
1021                 while carry && rev_pos > 0 {
1022                     rev_pos -= 1;
1023
1024                     // If the digit in the buffer is not '9', we just need to
1025                     // increment it and can stop then (since we don't have a
1026                     // carry anymore). Otherwise, we set it to '0' (overflow)
1027                     // and continue.
1028                     if buf[rev_pos] < b'9' {
1029                         buf[rev_pos] += 1;
1030                         carry = false;
1031                     } else {
1032                         buf[rev_pos] = b'0';
1033                     }
1034                 }
1035
1036                 // If we still have the carry bit set, that means that we set
1037                 // the whole buffer to '0's and need to increment the integer
1038                 // part.
1039                 if carry {
1040                     integer_part += 1;
1041                 }
1042             }
1043
1044             // Determine the end of the buffer: if precision is set, we just
1045             // use as many digits from the buffer (capped to 9). If it isn't
1046             // set, we only use all digits up to the last non-zero one.
1047             let end = f.precision().map(|p| crate::cmp::min(p, 9)).unwrap_or(pos);
1048
1049             // If we haven't emitted a single fractional digit and the precision
1050             // wasn't set to a non-zero value, we don't print the decimal point.
1051             if end == 0 {
1052                 write!(f, "{}", integer_part)
1053             } else {
1054                 // SAFETY: We are only writing ASCII digits into the buffer and it was
1055                 // initialized with '0's, so it contains valid UTF8.
1056                 let s = unsafe { crate::str::from_utf8_unchecked(&buf[..end]) };
1057
1058                 // If the user request a precision > 9, we pad '0's at the end.
1059                 let w = f.precision().unwrap_or(pos);
1060                 write!(f, "{}.{:0<width$}", integer_part, s, width = w)
1061             }
1062         }
1063
1064         // Print leading '+' sign if requested
1065         if f.sign_plus() {
1066             write!(f, "+")?;
1067         }
1068
1069         if self.secs > 0 {
1070             fmt_decimal(f, self.secs, self.nanos, NANOS_PER_SEC / 10)?;
1071             f.write_str("s")
1072         } else if self.nanos >= NANOS_PER_MILLI {
1073             fmt_decimal(
1074                 f,
1075                 (self.nanos / NANOS_PER_MILLI) as u64,
1076                 self.nanos % NANOS_PER_MILLI,
1077                 NANOS_PER_MILLI / 10,
1078             )?;
1079             f.write_str("ms")
1080         } else if self.nanos >= NANOS_PER_MICRO {
1081             fmt_decimal(
1082                 f,
1083                 (self.nanos / NANOS_PER_MICRO) as u64,
1084                 self.nanos % NANOS_PER_MICRO,
1085                 NANOS_PER_MICRO / 10,
1086             )?;
1087             f.write_str("µs")
1088         } else {
1089             fmt_decimal(f, self.nanos as u64, 0, 1)?;
1090             f.write_str("ns")
1091         }
1092     }
1093 }