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