1 #![stable(feature = "duration_core", since = "1.25.0")]
3 //! Temporal quantification.
7 //! There are multiple ways to create a new [`Duration`]:
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));
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));
24 use crate::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
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;
32 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
34 #[rustc_layout_scalar_valid_range_start(0)]
35 #[rustc_layout_scalar_valid_range_end(999_999_999)]
36 struct Nanoseconds(u32);
38 impl Default for Nanoseconds {
40 fn default() -> Self {
41 // SAFETY: 0 is within the valid range
42 unsafe { Nanoseconds(0) }
46 /// A `Duration` type to represent a span of time, typically used for system
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.
54 /// [`Duration`]s implement many common traits, including [`Add`], [`Sub`], and other
55 /// [`ops`] traits. It implements [`Default`] by returning a zero-length `Duration`.
57 /// [`ops`]: crate::ops
62 /// use std::time::Duration;
64 /// let five_seconds = Duration::new(5, 0);
65 /// let five_seconds_and_five_nanos = five_seconds + Duration::new(0, 5);
67 /// assert_eq!(five_seconds_and_five_nanos.as_secs(), 5);
68 /// assert_eq!(five_seconds_and_five_nanos.subsec_nanos(), 5);
70 /// let ten_millis = Duration::from_millis(10);
73 /// # Formatting `Duration` values
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.
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
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")]
88 nanos: Nanoseconds, // Always 0 <= nanos < NANOS_PER_SEC
92 /// The duration of one second.
97 /// #![feature(duration_constants)]
98 /// use std::time::Duration;
100 /// assert_eq!(Duration::SECOND, Duration::from_secs(1));
102 #[unstable(feature = "duration_constants", issue = "57391")]
103 pub const SECOND: Duration = Duration::from_secs(1);
105 /// The duration of one millisecond.
110 /// #![feature(duration_constants)]
111 /// use std::time::Duration;
113 /// assert_eq!(Duration::MILLISECOND, Duration::from_millis(1));
115 #[unstable(feature = "duration_constants", issue = "57391")]
116 pub const MILLISECOND: Duration = Duration::from_millis(1);
118 /// The duration of one microsecond.
123 /// #![feature(duration_constants)]
124 /// use std::time::Duration;
126 /// assert_eq!(Duration::MICROSECOND, Duration::from_micros(1));
128 #[unstable(feature = "duration_constants", issue = "57391")]
129 pub const MICROSECOND: Duration = Duration::from_micros(1);
131 /// The duration of one nanosecond.
136 /// #![feature(duration_constants)]
137 /// use std::time::Duration;
139 /// assert_eq!(Duration::NANOSECOND, Duration::from_nanos(1));
141 #[unstable(feature = "duration_constants", issue = "57391")]
142 pub const NANOSECOND: Duration = Duration::from_nanos(1);
144 /// A duration of zero time.
149 /// use std::time::Duration;
151 /// let duration = Duration::ZERO;
152 /// assert!(duration.is_zero());
153 /// assert_eq!(duration.as_nanos(), 0);
155 #[stable(feature = "duration_zero", since = "1.53.0")]
156 pub const ZERO: Duration = Duration::from_nanos(0);
158 /// The maximum duration.
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.
168 /// use std::time::Duration;
170 /// assert_eq!(Duration::MAX, Duration::new(u64::MAX, 1_000_000_000 - 1));
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);
177 /// Creates a new `Duration` from the specified number of whole seconds and
178 /// additional nanoseconds.
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.
185 /// This constructor will panic if the carry from the nanoseconds overflows
186 /// the seconds counter.
191 /// use std::time::Duration;
193 /// let five_seconds = Duration::new(5, 0);
195 #[stable(feature = "duration", since = "1.3.0")]
198 #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
199 pub const fn new(secs: u64, nanos: u32) -> Duration {
200 let secs = match secs.checked_add((nanos / NANOS_PER_SEC) as u64) {
202 None => panic!("overflow in Duration::new"),
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) } }
209 /// Creates a new `Duration` from the specified number of whole seconds.
214 /// use std::time::Duration;
216 /// let duration = Duration::from_secs(5);
218 /// assert_eq!(5, duration.as_secs());
219 /// assert_eq!(0, duration.subsec_nanos());
221 #[stable(feature = "duration", since = "1.3.0")]
224 #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
225 pub const fn from_secs(secs: u64) -> Duration {
226 Duration::new(secs, 0)
229 /// Creates a new `Duration` from the specified number of milliseconds.
234 /// use std::time::Duration;
236 /// let duration = Duration::from_millis(2569);
238 /// assert_eq!(2, duration.as_secs());
239 /// assert_eq!(569_000_000, duration.subsec_nanos());
241 #[stable(feature = "duration", since = "1.3.0")]
244 #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
245 pub const fn from_millis(millis: u64) -> Duration {
246 Duration::new(millis / MILLIS_PER_SEC, ((millis % MILLIS_PER_SEC) as u32) * NANOS_PER_MILLI)
249 /// Creates a new `Duration` from the specified number of microseconds.
254 /// use std::time::Duration;
256 /// let duration = Duration::from_micros(1_000_002);
258 /// assert_eq!(1, duration.as_secs());
259 /// assert_eq!(2000, duration.subsec_nanos());
261 #[stable(feature = "duration_from_micros", since = "1.27.0")]
264 #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
265 pub const fn from_micros(micros: u64) -> Duration {
266 Duration::new(micros / MICROS_PER_SEC, ((micros % MICROS_PER_SEC) as u32) * NANOS_PER_MICRO)
269 /// Creates a new `Duration` from the specified number of nanoseconds.
274 /// use std::time::Duration;
276 /// let duration = Duration::from_nanos(1_000_000_123);
278 /// assert_eq!(1, duration.as_secs());
279 /// assert_eq!(123, duration.subsec_nanos());
281 #[stable(feature = "duration_extras", since = "1.27.0")]
284 #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
285 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)
289 /// Returns true if this `Duration` spans no time.
294 /// use std::time::Duration;
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());
301 /// assert!(!Duration::new(1, 1).is_zero());
302 /// assert!(!Duration::from_nanos(1).is_zero());
303 /// assert!(!Duration::from_secs(1).is_zero());
306 #[stable(feature = "duration_zero", since = "1.53.0")]
307 #[rustc_const_stable(feature = "duration_zero", since = "1.53.0")]
309 pub const fn is_zero(&self) -> bool {
310 self.secs == 0 && self.nanos.0 == 0
313 /// Returns the number of _whole_ seconds contained by this `Duration`.
315 /// The returned value does not include the fractional (nanosecond) part of the
316 /// duration, which can be obtained using [`subsec_nanos`].
321 /// use std::time::Duration;
323 /// let duration = Duration::new(5, 730023852);
324 /// assert_eq!(duration.as_secs(), 5);
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`]
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")]
337 pub const fn as_secs(&self) -> u64 {
341 /// Returns the fractional part of this `Duration`, in whole milliseconds.
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).
350 /// use std::time::Duration;
352 /// let duration = Duration::from_millis(5432);
353 /// assert_eq!(duration.as_secs(), 5);
354 /// assert_eq!(duration.subsec_millis(), 432);
356 #[stable(feature = "duration_extras", since = "1.27.0")]
357 #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
360 pub const fn subsec_millis(&self) -> u32 {
361 self.nanos.0 / NANOS_PER_MILLI
364 /// Returns the fractional part of this `Duration`, in whole microseconds.
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).
373 /// use std::time::Duration;
375 /// let duration = Duration::from_micros(1_234_567);
376 /// assert_eq!(duration.as_secs(), 1);
377 /// assert_eq!(duration.subsec_micros(), 234_567);
379 #[stable(feature = "duration_extras", since = "1.27.0")]
380 #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
383 pub const fn subsec_micros(&self) -> u32 {
384 self.nanos.0 / NANOS_PER_MICRO
387 /// Returns the fractional part of this `Duration`, in nanoseconds.
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).
396 /// use std::time::Duration;
398 /// let duration = Duration::from_millis(5010);
399 /// assert_eq!(duration.as_secs(), 5);
400 /// assert_eq!(duration.subsec_nanos(), 10_000_000);
402 #[stable(feature = "duration", since = "1.3.0")]
403 #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
406 pub const fn subsec_nanos(&self) -> u32 {
410 /// Returns the total number of whole milliseconds contained by this `Duration`.
415 /// use std::time::Duration;
417 /// let duration = Duration::new(5, 730023852);
418 /// assert_eq!(duration.as_millis(), 5730);
420 #[stable(feature = "duration_as_u128", since = "1.33.0")]
421 #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
424 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
428 /// Returns the total number of whole microseconds contained by this `Duration`.
433 /// use std::time::Duration;
435 /// let duration = Duration::new(5, 730023852);
436 /// assert_eq!(duration.as_micros(), 5730023);
438 #[stable(feature = "duration_as_u128", since = "1.33.0")]
439 #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
442 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
446 /// Returns the total number of nanoseconds contained by this `Duration`.
451 /// use std::time::Duration;
453 /// let duration = Duration::new(5, 730023852);
454 /// assert_eq!(duration.as_nanos(), 5730023852);
456 #[stable(feature = "duration_as_u128", since = "1.33.0")]
457 #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
460 pub const fn as_nanos(&self) -> u128 {
461 self.secs as u128 * NANOS_PER_SEC as u128 + self.nanos.0 as u128
464 /// Checked `Duration` addition. Computes `self + other`, returning [`None`]
465 /// if overflow occurred.
472 /// use std::time::Duration;
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);
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"]
481 #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
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) {
493 debug_assert!(nanos < NANOS_PER_SEC);
494 Some(Duration::new(secs, nanos))
500 /// Saturating `Duration` addition. Computes `self + other`, returning [`Duration::MAX`]
501 /// if overflow occurred.
506 /// #![feature(duration_constants)]
507 /// use std::time::Duration;
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);
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"]
516 #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
517 pub const fn saturating_add(self, rhs: Duration) -> Duration {
518 match self.checked_add(rhs) {
520 None => Duration::MAX,
524 /// Checked `Duration` subtraction. Computes `self - other`, returning [`None`]
525 /// if the result would be negative or if overflow occurred.
532 /// use std::time::Duration;
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);
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"]
541 #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
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) {
548 self.nanos.0 + NANOS_PER_SEC - rhs.nanos.0
552 debug_assert!(nanos < NANOS_PER_SEC);
553 Some(Duration::new(secs, nanos))
559 /// Saturating `Duration` subtraction. Computes `self - other`, returning [`Duration::ZERO`]
560 /// if the result would be negative or if overflow occurred.
565 /// use std::time::Duration;
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);
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"]
574 #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
575 pub const fn saturating_sub(self, rhs: Duration) -> Duration {
576 match self.checked_sub(rhs) {
578 None => Duration::ZERO,
582 /// Checked `Duration` multiplication. Computes `self * other`, returning
583 /// [`None`] if overflow occurred.
590 /// use std::time::Duration;
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);
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"]
599 #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
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));
614 /// Saturating `Duration` multiplication. Computes `self * other`, returning
615 /// [`Duration::MAX`] if overflow occurred.
620 /// #![feature(duration_constants)]
621 /// use std::time::Duration;
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);
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"]
630 #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
631 pub const fn saturating_mul(self, rhs: u32) -> Duration {
632 match self.checked_mul(rhs) {
634 None => Duration::MAX,
638 /// Checked `Duration` division. Computes `self / other`, returning [`None`]
646 /// use std::time::Duration;
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);
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"]
656 #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
657 pub const fn checked_div(self, rhs: u32) -> Option<Duration> {
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))
670 /// Returns the number of seconds contained by this `Duration` as `f64`.
672 /// The returned value does include the fractional (nanosecond) part of the duration.
676 /// use std::time::Duration;
678 /// let dur = Duration::new(2, 700_000_000);
679 /// assert_eq!(dur.as_secs_f64(), 2.7);
681 #[stable(feature = "duration_float", since = "1.38.0")]
684 #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")]
685 pub const fn as_secs_f64(&self) -> f64 {
686 (self.secs as f64) + (self.nanos.0 as f64) / (NANOS_PER_SEC as f64)
689 /// Returns the number of seconds contained by this `Duration` as `f32`.
691 /// The returned value does include the fractional (nanosecond) part of the duration.
695 /// use std::time::Duration;
697 /// let dur = Duration::new(2, 700_000_000);
698 /// assert_eq!(dur.as_secs_f32(), 2.7);
700 #[stable(feature = "duration_float", since = "1.38.0")]
703 #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")]
704 pub const fn as_secs_f32(&self) -> f32 {
705 (self.secs as f32) + (self.nanos.0 as f32) / (NANOS_PER_SEC as f32)
708 /// Creates a new `Duration` from the specified number of seconds represented
712 /// This constructor will panic if `secs` is negative, overflows `Duration` or not finite.
716 /// use std::time::Duration;
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));
735 #[stable(feature = "duration_float", since = "1.38.0")]
738 #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")]
739 pub const fn from_secs_f64(secs: f64) -> Duration {
740 match Duration::try_from_secs_f64(secs) {
742 Err(e) => panic!("{}", e.description()),
746 /// Creates a new `Duration` from the specified number of seconds represented
750 /// This constructor will panic if `secs` is negative, overflows `Duration` or not finite.
754 /// use std::time::Duration;
756 /// let res = Duration::from_secs_f32(0.0);
757 /// assert_eq!(res, Duration::new(0, 0));
758 /// let res = Duration::from_secs_f32(1e-20);
759 /// assert_eq!(res, Duration::new(0, 0));
760 /// let res = Duration::from_secs_f32(4.2e-7);
761 /// assert_eq!(res, Duration::new(0, 420));
762 /// let res = Duration::from_secs_f32(2.7);
763 /// assert_eq!(res, Duration::new(2, 700_000_048));
764 /// let res = Duration::from_secs_f32(3e10);
765 /// assert_eq!(res, Duration::new(30_000_001_024, 0));
766 /// // subnormal float
767 /// let res = Duration::from_secs_f32(f32::from_bits(1));
768 /// assert_eq!(res, Duration::new(0, 0));
769 /// // conversion uses rounding
770 /// let res = Duration::from_secs_f32(0.999e-9);
771 /// assert_eq!(res, Duration::new(0, 1));
773 #[stable(feature = "duration_float", since = "1.38.0")]
776 #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")]
777 pub const fn from_secs_f32(secs: f32) -> Duration {
778 match Duration::try_from_secs_f32(secs) {
780 Err(e) => panic!("{}", e.description()),
784 /// Multiplies `Duration` by `f64`.
787 /// This method will panic if result is negative, overflows `Duration` or not finite.
791 /// use std::time::Duration;
793 /// let dur = Duration::new(2, 700_000_000);
794 /// assert_eq!(dur.mul_f64(3.14), Duration::new(8, 478_000_000));
795 /// assert_eq!(dur.mul_f64(3.14e5), Duration::new(847_800, 0));
797 #[stable(feature = "duration_float", since = "1.38.0")]
798 #[must_use = "this returns the result of the operation, \
799 without modifying the original"]
801 #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")]
802 pub const fn mul_f64(self, rhs: f64) -> Duration {
803 Duration::from_secs_f64(rhs * self.as_secs_f64())
806 /// Multiplies `Duration` by `f32`.
809 /// This method will panic if result is negative, overflows `Duration` or not finite.
813 /// use std::time::Duration;
815 /// let dur = Duration::new(2, 700_000_000);
816 /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_641));
817 /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847800, 0));
819 #[stable(feature = "duration_float", since = "1.38.0")]
820 #[must_use = "this returns the result of the operation, \
821 without modifying the original"]
823 #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")]
824 pub const fn mul_f32(self, rhs: f32) -> Duration {
825 Duration::from_secs_f32(rhs * self.as_secs_f32())
828 /// Divide `Duration` by `f64`.
831 /// This method will panic if result is negative, overflows `Duration` or not finite.
835 /// use std::time::Duration;
837 /// let dur = Duration::new(2, 700_000_000);
838 /// assert_eq!(dur.div_f64(3.14), Duration::new(0, 859_872_611));
839 /// assert_eq!(dur.div_f64(3.14e5), Duration::new(0, 8_599));
841 #[stable(feature = "duration_float", since = "1.38.0")]
842 #[must_use = "this returns the result of the operation, \
843 without modifying the original"]
845 #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")]
846 pub const fn div_f64(self, rhs: f64) -> Duration {
847 Duration::from_secs_f64(self.as_secs_f64() / rhs)
850 /// Divide `Duration` by `f32`.
853 /// This method will panic if result is negative, overflows `Duration` or not finite.
857 /// use std::time::Duration;
859 /// let dur = Duration::new(2, 700_000_000);
860 /// // note that due to rounding errors result is slightly
861 /// // different from 0.859_872_611
862 /// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_580));
863 /// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_599));
865 #[stable(feature = "duration_float", since = "1.38.0")]
866 #[must_use = "this returns the result of the operation, \
867 without modifying the original"]
869 #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")]
870 pub const fn div_f32(self, rhs: f32) -> Duration {
871 Duration::from_secs_f32(self.as_secs_f32() / rhs)
874 /// Divide `Duration` by `Duration` and return `f64`.
878 /// #![feature(div_duration)]
879 /// use std::time::Duration;
881 /// let dur1 = Duration::new(2, 700_000_000);
882 /// let dur2 = Duration::new(5, 400_000_000);
883 /// assert_eq!(dur1.div_duration_f64(dur2), 0.5);
885 #[unstable(feature = "div_duration", issue = "63139")]
886 #[must_use = "this returns the result of the operation, \
887 without modifying the original"]
889 #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")]
890 pub const fn div_duration_f64(self, rhs: Duration) -> f64 {
891 self.as_secs_f64() / rhs.as_secs_f64()
894 /// Divide `Duration` by `Duration` and return `f32`.
898 /// #![feature(div_duration)]
899 /// use std::time::Duration;
901 /// let dur1 = Duration::new(2, 700_000_000);
902 /// let dur2 = Duration::new(5, 400_000_000);
903 /// assert_eq!(dur1.div_duration_f32(dur2), 0.5);
905 #[unstable(feature = "div_duration", issue = "63139")]
906 #[must_use = "this returns the result of the operation, \
907 without modifying the original"]
909 #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")]
910 pub const fn div_duration_f32(self, rhs: Duration) -> f32 {
911 self.as_secs_f32() / rhs.as_secs_f32()
915 #[stable(feature = "duration", since = "1.3.0")]
916 impl Add for Duration {
917 type Output = Duration;
919 fn add(self, rhs: Duration) -> Duration {
920 self.checked_add(rhs).expect("overflow when adding durations")
924 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
925 impl AddAssign for Duration {
926 fn add_assign(&mut self, rhs: Duration) {
931 #[stable(feature = "duration", since = "1.3.0")]
932 impl Sub for Duration {
933 type Output = Duration;
935 fn sub(self, rhs: Duration) -> Duration {
936 self.checked_sub(rhs).expect("overflow when subtracting durations")
940 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
941 impl SubAssign for Duration {
942 fn sub_assign(&mut self, rhs: Duration) {
947 #[stable(feature = "duration", since = "1.3.0")]
948 impl Mul<u32> for Duration {
949 type Output = Duration;
951 fn mul(self, rhs: u32) -> Duration {
952 self.checked_mul(rhs).expect("overflow when multiplying duration by scalar")
956 #[stable(feature = "symmetric_u32_duration_mul", since = "1.31.0")]
957 impl Mul<Duration> for u32 {
958 type Output = Duration;
960 fn mul(self, rhs: Duration) -> Duration {
965 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
966 impl MulAssign<u32> for Duration {
967 fn mul_assign(&mut self, rhs: u32) {
972 #[stable(feature = "duration", since = "1.3.0")]
973 impl Div<u32> for Duration {
974 type Output = Duration;
976 fn div(self, rhs: u32) -> Duration {
977 self.checked_div(rhs).expect("divide by zero error when dividing duration by scalar")
981 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
982 impl DivAssign<u32> for Duration {
983 fn div_assign(&mut self, rhs: u32) {
988 macro_rules! sum_durations {
990 let mut total_secs: u64 = 0;
991 let mut total_nanos: u64 = 0;
995 total_secs.checked_add(entry.secs).expect("overflow in iter::sum over durations");
996 total_nanos = match total_nanos.checked_add(entry.nanos.0 as u64) {
999 total_secs = total_secs
1000 .checked_add(total_nanos / NANOS_PER_SEC as u64)
1001 .expect("overflow in iter::sum over durations");
1002 (total_nanos % NANOS_PER_SEC as u64) + entry.nanos.0 as u64
1006 total_secs = total_secs
1007 .checked_add(total_nanos / NANOS_PER_SEC as u64)
1008 .expect("overflow in iter::sum over durations");
1009 total_nanos = total_nanos % NANOS_PER_SEC as u64;
1010 Duration::new(total_secs, total_nanos as u32)
1014 #[stable(feature = "duration_sum", since = "1.16.0")]
1015 impl Sum for Duration {
1016 fn sum<I: Iterator<Item = Duration>>(iter: I) -> Duration {
1017 sum_durations!(iter)
1021 #[stable(feature = "duration_sum", since = "1.16.0")]
1022 impl<'a> Sum<&'a Duration> for Duration {
1023 fn sum<I: Iterator<Item = &'a Duration>>(iter: I) -> Duration {
1024 sum_durations!(iter)
1028 #[stable(feature = "duration_debug_impl", since = "1.27.0")]
1029 impl fmt::Debug for Duration {
1030 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1031 /// Formats a floating point number in decimal notation.
1033 /// The number is given as the `integer_part` and a fractional part.
1034 /// The value of the fractional part is `fractional_part / divisor`. So
1035 /// `integer_part` = 3, `fractional_part` = 12 and `divisor` = 100
1036 /// represents the number `3.012`. Trailing zeros are omitted.
1038 /// `divisor` must not be above 100_000_000. It also should be a power
1039 /// of 10, everything else doesn't make sense. `fractional_part` has
1040 /// to be less than `10 * divisor`!
1042 /// A prefix and postfix may be added. The whole thing is padded
1043 /// to the formatter's `width`, if specified.
1045 f: &mut fmt::Formatter<'_>,
1047 mut fractional_part: u32,
1052 // Encode the fractional part into a temporary buffer. The buffer
1053 // only need to hold 9 elements, because `fractional_part` has to
1054 // be smaller than 10^9. The buffer is prefilled with '0' digits
1055 // to simplify the code below.
1056 let mut buf = [b'0'; 9];
1058 // The next digit is written at this position
1061 // We keep writing digits into the buffer while there are non-zero
1062 // digits left and we haven't written enough digits yet.
1063 while fractional_part > 0 && pos < f.precision().unwrap_or(9) {
1064 // Write new digit into the buffer
1065 buf[pos] = b'0' + (fractional_part / divisor) as u8;
1067 fractional_part %= divisor;
1072 // If a precision < 9 was specified, there may be some non-zero
1073 // digits left that weren't written into the buffer. In that case we
1074 // need to perform rounding to match the semantics of printing
1075 // normal floating point numbers. However, we only need to do work
1076 // when rounding up. This happens if the first digit of the
1077 // remaining ones is >= 5.
1078 let integer_part = if fractional_part > 0 && fractional_part >= divisor * 5 {
1079 // Round up the number contained in the buffer. We go through
1080 // the buffer backwards and keep track of the carry.
1081 let mut rev_pos = pos;
1082 let mut carry = true;
1083 while carry && rev_pos > 0 {
1086 // If the digit in the buffer is not '9', we just need to
1087 // increment it and can stop then (since we don't have a
1088 // carry anymore). Otherwise, we set it to '0' (overflow)
1090 if buf[rev_pos] < b'9' {
1094 buf[rev_pos] = b'0';
1098 // If we still have the carry bit set, that means that we set
1099 // the whole buffer to '0's and need to increment the integer
1102 // If `integer_part == u64::MAX` and precision < 9, any
1103 // carry of the overflow during rounding of the
1104 // `fractional_part` into the `integer_part` will cause the
1105 // `integer_part` itself to overflow. Avoid this by using an
1106 // `Option<u64>`, with `None` representing `u64::MAX + 1`.
1107 integer_part.checked_add(1)
1115 // Determine the end of the buffer: if precision is set, we just
1116 // use as many digits from the buffer (capped to 9). If it isn't
1117 // set, we only use all digits up to the last non-zero one.
1118 let end = f.precision().map(|p| crate::cmp::min(p, 9)).unwrap_or(pos);
1120 // This closure emits the formatted duration without emitting any
1121 // padding (padding is calculated below).
1122 let emit_without_padding = |f: &mut fmt::Formatter<'_>| {
1123 if let Some(integer_part) = integer_part {
1124 write!(f, "{}{}", prefix, integer_part)?;
1126 // u64::MAX + 1 == 18446744073709551616
1127 write!(f, "{}18446744073709551616", prefix)?;
1130 // Write the decimal point and the fractional part (if any).
1132 // SAFETY: We are only writing ASCII digits into the buffer and
1133 // it was initialized with '0's, so it contains valid UTF8.
1134 let s = unsafe { crate::str::from_utf8_unchecked(&buf[..end]) };
1136 // If the user request a precision > 9, we pad '0's at the end.
1137 let w = f.precision().unwrap_or(pos);
1138 write!(f, ".{:0<width$}", s, width = w)?;
1141 write!(f, "{}", postfix)
1146 // No `width` specified. There's no need to calculate the
1147 // length of the output in this case, just emit it.
1148 emit_without_padding(f)
1150 Some(requested_w) => {
1151 // A `width` was specified. Calculate the actual width of
1152 // the output in order to calculate the required padding.
1153 // It consists of 4 parts:
1154 // 1. The prefix: is either "+" or "", so we can just use len().
1155 // 2. The postfix: can be "µs" so we have to count UTF8 characters.
1156 let mut actual_w = prefix.len() + postfix.chars().count();
1157 // 3. The integer part:
1158 if let Some(integer_part) = integer_part {
1159 if let Some(log) = integer_part.checked_ilog10() {
1160 // integer_part is > 0, so has length log10(x)+1
1161 actual_w += 1 + log as usize;
1163 // integer_part is 0, so has length 1.
1167 // integer_part is u64::MAX + 1, so has length 20
1170 // 4. The fractional part (if any):
1172 let frac_part_w = f.precision().unwrap_or(pos);
1173 actual_w += 1 + frac_part_w;
1176 if requested_w <= actual_w {
1177 // Output is already longer than `width`, so don't pad.
1178 emit_without_padding(f)
1180 // We need to add padding. Use the `Formatter::padding` helper function.
1181 let default_align = crate::fmt::rt::v1::Alignment::Left;
1182 let post_padding = f.padding(requested_w - actual_w, default_align)?;
1183 emit_without_padding(f)?;
1184 post_padding.write(f)
1190 // Print leading '+' sign if requested
1191 let prefix = if f.sign_plus() { "+" } else { "" };
1194 fmt_decimal(f, self.secs, self.nanos.0, NANOS_PER_SEC / 10, prefix, "s")
1195 } else if self.nanos.0 >= NANOS_PER_MILLI {
1198 (self.nanos.0 / NANOS_PER_MILLI) as u64,
1199 self.nanos.0 % NANOS_PER_MILLI,
1200 NANOS_PER_MILLI / 10,
1204 } else if self.nanos.0 >= NANOS_PER_MICRO {
1207 (self.nanos.0 / NANOS_PER_MICRO) as u64,
1208 self.nanos.0 % NANOS_PER_MICRO,
1209 NANOS_PER_MICRO / 10,
1214 fmt_decimal(f, self.nanos.0 as u64, 0, 1, prefix, "ns")
1219 /// An error which can be returned when converting a floating-point value of seconds
1220 /// into a [`Duration`].
1222 /// This error is used as the error type for [`Duration::try_from_secs_f32`] and
1223 /// [`Duration::try_from_secs_f64`].
1228 /// #![feature(duration_checked_float)]
1229 /// use std::time::Duration;
1231 /// if let Err(e) = Duration::try_from_secs_f32(-1.0) {
1232 /// println!("Failed conversion to Duration: {e}");
1235 #[derive(Debug, Clone, PartialEq, Eq)]
1236 #[unstable(feature = "duration_checked_float", issue = "83400")]
1237 pub struct FromFloatSecsError {
1238 kind: FromFloatSecsErrorKind,
1241 impl FromFloatSecsError {
1242 const fn description(&self) -> &'static str {
1244 FromFloatSecsErrorKind::Negative => {
1245 "can not convert float seconds to Duration: value is negative"
1247 FromFloatSecsErrorKind::OverflowOrNan => {
1248 "can not convert float seconds to Duration: value is either too big or NaN"
1254 #[unstable(feature = "duration_checked_float", issue = "83400")]
1255 impl fmt::Display for FromFloatSecsError {
1256 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1257 self.description().fmt(f)
1261 #[derive(Debug, Clone, PartialEq, Eq)]
1262 enum FromFloatSecsErrorKind {
1263 // Value is negative.
1265 // Value is either too big to be represented as `Duration` or `NaN`.
1269 macro_rules! try_from_secs {
1272 mantissa_bits = $mant_bits: literal,
1273 exponent_bits = $exp_bits: literal,
1274 offset = $offset: literal,
1275 bits_ty = $bits_ty:ty,
1276 double_ty = $double_ty:ty,
1278 const MIN_EXP: i16 = 1 - (1i16 << $exp_bits) / 2;
1279 const MANT_MASK: $bits_ty = (1 << $mant_bits) - 1;
1280 const EXP_MASK: $bits_ty = (1 << $exp_bits) - 1;
1282 if $secs.is_sign_negative() {
1283 return Err(FromFloatSecsError { kind: FromFloatSecsErrorKind::Negative });
1286 let bits = $secs.to_bits();
1287 let mant = (bits & MANT_MASK) | (MANT_MASK + 1);
1288 let exp = ((bits >> $mant_bits) & EXP_MASK) as i16 + MIN_EXP;
1290 let (secs, nanos) = if exp < -31 {
1291 // the input represents less than 1ns and can not be rounded to it
1294 // the input is less than 1 second
1295 let t = <$double_ty>::from(mant) << ($offset + exp);
1296 let nanos_offset = $mant_bits + $offset;
1297 let nanos_tmp = u128::from(NANOS_PER_SEC) * u128::from(t);
1298 let nanos = (nanos_tmp >> nanos_offset) as u32;
1300 let rem_mask = (1 << nanos_offset) - 1;
1301 let rem_msb_mask = 1 << (nanos_offset - 1);
1302 let rem = nanos_tmp & rem_mask;
1303 let is_tie = rem == rem_msb_mask;
1304 let is_even = (nanos & 1) == 0;
1305 let rem_msb = nanos_tmp & rem_msb_mask == 0;
1306 let add_ns = !(rem_msb || (is_even && is_tie));
1308 // f32 does not have enough precision to trigger the second branch
1309 // since it can not represent numbers between 0.999_999_940_395 and 1.0.
1310 let nanos = nanos + add_ns as u32;
1311 if ($mant_bits == 23) || (nanos != NANOS_PER_SEC) { (0, nanos) } else { (1, 0) }
1312 } else if exp < $mant_bits {
1313 let secs = u64::from(mant >> ($mant_bits - exp));
1314 let t = <$double_ty>::from((mant << exp) & MANT_MASK);
1315 let nanos_offset = $mant_bits;
1316 let nanos_tmp = <$double_ty>::from(NANOS_PER_SEC) * t;
1317 let nanos = (nanos_tmp >> nanos_offset) as u32;
1319 let rem_mask = (1 << nanos_offset) - 1;
1320 let rem_msb_mask = 1 << (nanos_offset - 1);
1321 let rem = nanos_tmp & rem_mask;
1322 let is_tie = rem == rem_msb_mask;
1323 let is_even = (nanos & 1) == 0;
1324 let rem_msb = nanos_tmp & rem_msb_mask == 0;
1325 let add_ns = !(rem_msb || (is_even && is_tie));
1327 // f32 does not have enough precision to trigger the second branch.
1328 // For example, it can not represent numbers between 1.999_999_880...
1329 // and 2.0. Bigger values result in even smaller precision of the
1331 let nanos = nanos + add_ns as u32;
1332 if ($mant_bits == 23) || (nanos != NANOS_PER_SEC) {
1337 } else if exp < 64 {
1338 // the input has no fractional part
1339 let secs = u64::from(mant) << (exp - $mant_bits);
1342 return Err(FromFloatSecsError { kind: FromFloatSecsErrorKind::OverflowOrNan });
1345 Ok(Duration::new(secs, nanos))
1350 /// The checked version of [`from_secs_f32`].
1352 /// [`from_secs_f32`]: Duration::from_secs_f32
1354 /// This constructor will return an `Err` if `secs` is negative, overflows `Duration` or not finite.
1358 /// #![feature(duration_checked_float)]
1360 /// use std::time::Duration;
1362 /// let res = Duration::try_from_secs_f32(0.0);
1363 /// assert_eq!(res, Ok(Duration::new(0, 0)));
1364 /// let res = Duration::try_from_secs_f32(1e-20);
1365 /// assert_eq!(res, Ok(Duration::new(0, 0)));
1366 /// let res = Duration::try_from_secs_f32(4.2e-7);
1367 /// assert_eq!(res, Ok(Duration::new(0, 420)));
1368 /// let res = Duration::try_from_secs_f32(2.7);
1369 /// assert_eq!(res, Ok(Duration::new(2, 700_000_048)));
1370 /// let res = Duration::try_from_secs_f32(3e10);
1371 /// assert_eq!(res, Ok(Duration::new(30_000_001_024, 0)));
1372 /// // subnormal float:
1373 /// let res = Duration::try_from_secs_f32(f32::from_bits(1));
1374 /// assert_eq!(res, Ok(Duration::new(0, 0)));
1376 /// let res = Duration::try_from_secs_f32(-5.0);
1377 /// assert!(res.is_err());
1378 /// let res = Duration::try_from_secs_f32(f32::NAN);
1379 /// assert!(res.is_err());
1380 /// let res = Duration::try_from_secs_f32(2e19);
1381 /// assert!(res.is_err());
1383 /// // the conversion uses rounding with tie resolution to even
1384 /// let res = Duration::try_from_secs_f32(0.999e-9);
1385 /// assert_eq!(res, Ok(Duration::new(0, 1)));
1387 /// // this float represents exactly 976562.5e-9
1388 /// let val = f32::from_bits(0x3A80_0000);
1389 /// let res = Duration::try_from_secs_f32(val);
1390 /// assert_eq!(res, Ok(Duration::new(0, 976_562)));
1392 /// // this float represents exactly 2929687.5e-9
1393 /// let val = f32::from_bits(0x3B40_0000);
1394 /// let res = Duration::try_from_secs_f32(val);
1395 /// assert_eq!(res, Ok(Duration::new(0, 2_929_688)));
1397 /// // this float represents exactly 1.000_976_562_5
1398 /// let val = f32::from_bits(0x3F802000);
1399 /// let res = Duration::try_from_secs_f32(val);
1400 /// assert_eq!(res, Ok(Duration::new(1, 976_562)));
1402 /// // this float represents exactly 1.002_929_687_5
1403 /// let val = f32::from_bits(0x3F806000);
1404 /// let res = Duration::try_from_secs_f32(val);
1405 /// assert_eq!(res, Ok(Duration::new(1, 2_929_688)));
1407 #[unstable(feature = "duration_checked_float", issue = "83400")]
1409 pub const fn try_from_secs_f32(secs: f32) -> Result<Duration, FromFloatSecsError> {
1420 /// The checked version of [`from_secs_f64`].
1422 /// [`from_secs_f64`]: Duration::from_secs_f64
1424 /// This constructor will return an `Err` if `secs` is negative, overflows `Duration` or not finite.
1428 /// #![feature(duration_checked_float)]
1430 /// use std::time::Duration;
1432 /// let res = Duration::try_from_secs_f64(0.0);
1433 /// assert_eq!(res, Ok(Duration::new(0, 0)));
1434 /// let res = Duration::try_from_secs_f64(1e-20);
1435 /// assert_eq!(res, Ok(Duration::new(0, 0)));
1436 /// let res = Duration::try_from_secs_f64(4.2e-7);
1437 /// assert_eq!(res, Ok(Duration::new(0, 420)));
1438 /// let res = Duration::try_from_secs_f64(2.7);
1439 /// assert_eq!(res, Ok(Duration::new(2, 700_000_000)));
1440 /// let res = Duration::try_from_secs_f64(3e10);
1441 /// assert_eq!(res, Ok(Duration::new(30_000_000_000, 0)));
1442 /// // subnormal float
1443 /// let res = Duration::try_from_secs_f64(f64::from_bits(1));
1444 /// assert_eq!(res, Ok(Duration::new(0, 0)));
1446 /// let res = Duration::try_from_secs_f64(-5.0);
1447 /// assert!(res.is_err());
1448 /// let res = Duration::try_from_secs_f64(f64::NAN);
1449 /// assert!(res.is_err());
1450 /// let res = Duration::try_from_secs_f64(2e19);
1451 /// assert!(res.is_err());
1453 /// // the conversion uses rounding with tie resolution to even
1454 /// let res = Duration::try_from_secs_f64(0.999e-9);
1455 /// assert_eq!(res, Ok(Duration::new(0, 1)));
1456 /// let res = Duration::try_from_secs_f64(0.999_999_999_499);
1457 /// assert_eq!(res, Ok(Duration::new(0, 999_999_999)));
1458 /// let res = Duration::try_from_secs_f64(0.999_999_999_501);
1459 /// assert_eq!(res, Ok(Duration::new(1, 0)));
1460 /// let res = Duration::try_from_secs_f64(42.999_999_999_499);
1461 /// assert_eq!(res, Ok(Duration::new(42, 999_999_999)));
1462 /// let res = Duration::try_from_secs_f64(42.999_999_999_501);
1463 /// assert_eq!(res, Ok(Duration::new(43, 0)));
1465 /// // this float represents exactly 976562.5e-9
1466 /// let val = f64::from_bits(0x3F50_0000_0000_0000);
1467 /// let res = Duration::try_from_secs_f64(val);
1468 /// assert_eq!(res, Ok(Duration::new(0, 976_562)));
1470 /// // this float represents exactly 2929687.5e-9
1471 /// let val = f64::from_bits(0x3F68_0000_0000_0000);
1472 /// let res = Duration::try_from_secs_f64(val);
1473 /// assert_eq!(res, Ok(Duration::new(0, 2_929_688)));
1475 /// // this float represents exactly 1.000_976_562_5
1476 /// let val = f64::from_bits(0x3FF0_0400_0000_0000);
1477 /// let res = Duration::try_from_secs_f64(val);
1478 /// assert_eq!(res, Ok(Duration::new(1, 976_562)));
1480 /// // this float represents exactly 1.002_929_687_5
1481 /// let val = f64::from_bits(0x3_FF00_C000_0000_000);
1482 /// let res = Duration::try_from_secs_f64(val);
1483 /// assert_eq!(res, Ok(Duration::new(1, 2_929_688)));
1485 #[unstable(feature = "duration_checked_float", issue = "83400")]
1487 pub const fn try_from_secs_f64(secs: f64) -> Result<Duration, FromFloatSecsError> {