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