1#![stable(feature = "duration_core", since = "1.25.0")]
2
3use 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#[stable(feature = "duration", since = "1.3.0")]
79#[derive(#[automatically_derived]
#[stable(feature = "duration", since = "1.3.0")]
impl crate::clone::Clone for Duration {
#[inline]
fn clone(&self) -> Duration {
let _: crate::clone::AssertParamIsClone<u64>;
let _: crate::clone::AssertParamIsClone<Nanoseconds>;
*self
}
}Clone, #[automatically_derived]
#[stable(feature = "duration", since = "1.3.0")]
impl crate::marker::Copy for Duration { }Copy, #[automatically_derived]
#[stable(feature = "duration", since = "1.3.0")]
impl crate::cmp::PartialEq for Duration {
#[inline]
fn eq(&self, other: &Duration) -> bool {
self.secs == other.secs && self.nanos == other.nanos
}
}PartialEq, #[automatically_derived]
#[stable(feature = "duration", since = "1.3.0")]
impl crate::cmp::Eq for Duration {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: crate::cmp::AssertParamIsEq<u64>;
let _: crate::cmp::AssertParamIsEq<Nanoseconds>;
}
}Eq, #[automatically_derived]
#[stable(feature = "duration", since = "1.3.0")]
impl crate::cmp::PartialOrd for Duration {
#[inline]
fn partial_cmp(&self, other: &Duration)
-> crate::option::Option<crate::cmp::Ordering> {
crate::option::Option::Some(crate::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]
#[stable(feature = "duration", since = "1.3.0")]
impl crate::cmp::Ord for Duration {
#[inline]
fn cmp(&self, other: &Duration) -> crate::cmp::Ordering {
match crate::cmp::Ord::cmp(&self.secs, &other.secs) {
crate::cmp::Ordering::Equal =>
crate::cmp::Ord::cmp(&self.nanos, &other.nanos),
cmp => cmp,
}
}
}Ord, #[automatically_derived]
#[stable(feature = "duration", since = "1.3.0")]
impl crate::hash::Hash for Duration {
#[inline]
fn hash<__H: crate::hash::Hasher>(&self, state: &mut __H) {
crate::hash::Hash::hash(&self.secs, state);
crate::hash::Hash::hash(&self.nanos, state)
}
}Hash, #[automatically_derived]
#[stable(feature = "duration", since = "1.3.0")]
impl crate::default::Default for Duration {
#[inline]
fn default() -> Duration {
Duration {
secs: crate::default::Default::default(),
nanos: crate::default::Default::default(),
}
}
}Default)]
80#[rustc_diagnostic_item = "Duration"]
81pub struct Duration {
82 secs: u64,
83 nanos: Nanoseconds, }
85
86impl Duration {
87 #[unstable(feature = "duration_constants", issue = "57391")]
98 pub const SECOND: Duration = Duration::from_secs(1);
99
100 #[unstable(feature = "duration_constants", issue = "57391")]
111 pub const MILLISECOND: Duration = Duration::from_millis(1);
112
113 #[unstable(feature = "duration_constants", issue = "57391")]
124 pub const MICROSECOND: Duration = Duration::from_micros(1);
125
126 #[unstable(feature = "duration_constants", issue = "57391")]
137 pub const NANOSECOND: Duration = Duration::from_nanos(1);
138
139 #[stable(feature = "duration_zero", since = "1.53.0")]
151 pub const ZERO: Duration = Duration::from_nanos(0);
152
153 #[stable(feature = "duration_saturating_ops", since = "1.53.0")]
170 pub const MAX: Duration = Duration::new(u64::MAX, NANOS_PER_SEC - 1);
171
172 #[stable(feature = "duration", since = "1.3.0")]
191 #[inline]
192 #[must_use]
193 #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
194 pub const fn new(secs: u64, nanos: u32) -> Duration {
195 if nanos < NANOS_PER_SEC {
196 Duration { secs, nanos: unsafe { Nanoseconds::new_unchecked(nanos) } }
198 } else {
199 let secs = secs
200 .checked_add((nanos / NANOS_PER_SEC) as u64)
201 .expect("overflow in Duration::new");
202 let nanos = nanos % NANOS_PER_SEC;
203 Duration { secs, nanos: unsafe { Nanoseconds::new_unchecked(nanos) } }
205 }
206 }
207
208 #[stable(feature = "duration", since = "1.3.0")]
221 #[must_use]
222 #[inline]
223 #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
224 pub const fn from_secs(secs: u64) -> Duration {
225 Duration { secs, nanos: Nanoseconds::ZERO }
226 }
227
228 #[stable(feature = "duration", since = "1.3.0")]
241 #[must_use]
242 #[inline]
243 #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
244 pub const fn from_millis(millis: u64) -> Duration {
245 let secs = millis / MILLIS_PER_SEC;
246 let subsec_millis = (millis % MILLIS_PER_SEC) as u32;
247 let subsec_nanos = unsafe { Nanoseconds::new_unchecked(subsec_millis * NANOS_PER_MILLI) };
250
251 Duration { secs, nanos: subsec_nanos }
252 }
253
254 #[stable(feature = "duration_from_micros", since = "1.27.0")]
267 #[must_use]
268 #[inline]
269 #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
270 pub const fn from_micros(micros: u64) -> Duration {
271 let secs = micros / MICROS_PER_SEC;
272 let subsec_micros = (micros % MICROS_PER_SEC) as u32;
273 let subsec_nanos = unsafe { Nanoseconds::new_unchecked(subsec_micros * NANOS_PER_MICRO) };
276
277 Duration { secs, nanos: subsec_nanos }
278 }
279
280 #[stable(feature = "duration_extras", since = "1.27.0")]
298 #[must_use]
299 #[inline]
300 #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
301 pub const fn from_nanos(nanos: u64) -> Duration {
302 const NANOS_PER_SEC: u64 = self::NANOS_PER_SEC as u64;
303 let secs = nanos / NANOS_PER_SEC;
304 let subsec_nanos = (nanos % NANOS_PER_SEC) as u32;
305 let subsec_nanos = unsafe { Nanoseconds::new_unchecked(subsec_nanos) };
307
308 Duration { secs, nanos: subsec_nanos }
309 }
310
311 #[stable(feature = "duration_from_nanos_u128", since = "1.93.0")]
329 #[rustc_const_stable(feature = "duration_from_nanos_u128", since = "1.93.0")]
330 #[must_use]
331 #[inline]
332 #[track_caller]
333 #[rustc_allow_const_fn_unstable(const_trait_impl, const_convert)] pub const fn from_nanos_u128(nanos: u128) -> Duration {
335 const NANOS_PER_SEC: u128 = self::NANOS_PER_SEC as u128;
336 let Ok(secs) = u64::try_from(nanos / NANOS_PER_SEC) else {
337 {
crate::panicking::panic_fmt(format_args!("overflow in `Duration::from_nanos_u128`"));
};panic!("overflow in `Duration::from_nanos_u128`");
338 };
339 let subsec_nanos = (nanos % NANOS_PER_SEC) as u32;
340 let subsec_nanos = unsafe { Nanoseconds::new_unchecked(subsec_nanos) };
342
343 Duration { secs: secs as u64, nanos: subsec_nanos }
344 }
345
346 #[unstable(feature = "duration_constructors", issue = "120301")]
364 #[must_use]
365 #[inline]
366 pub const fn from_weeks(weeks: u64) -> Duration {
367 if weeks > u64::MAX / (SECS_PER_MINUTE * MINS_PER_HOUR * HOURS_PER_DAY * DAYS_PER_WEEK) {
368 {
crate::panicking::panic_fmt(format_args!("overflow in Duration::from_weeks"));
};panic!("overflow in Duration::from_weeks");
369 }
370
371 Duration::from_secs(weeks * MINS_PER_HOUR * SECS_PER_MINUTE * HOURS_PER_DAY * DAYS_PER_WEEK)
372 }
373
374 #[unstable(feature = "duration_constructors", issue = "120301")]
392 #[must_use]
393 #[inline]
394 pub const fn from_days(days: u64) -> Duration {
395 if days > u64::MAX / (SECS_PER_MINUTE * MINS_PER_HOUR * HOURS_PER_DAY) {
396 {
crate::panicking::panic_fmt(format_args!("overflow in Duration::from_days"));
};panic!("overflow in Duration::from_days");
397 }
398
399 Duration::from_secs(days * MINS_PER_HOUR * SECS_PER_MINUTE * HOURS_PER_DAY)
400 }
401
402 #[stable(feature = "duration_constructors_lite", since = "1.91.0")]
419 #[rustc_const_stable(feature = "duration_constructors_lite", since = "1.91.0")]
420 #[must_use]
421 #[inline]
422 pub const fn from_hours(hours: u64) -> Duration {
423 if hours > u64::MAX / (SECS_PER_MINUTE * MINS_PER_HOUR) {
424 {
crate::panicking::panic_fmt(format_args!("overflow in Duration::from_hours"));
};panic!("overflow in Duration::from_hours");
425 }
426
427 Duration::from_secs(hours * MINS_PER_HOUR * SECS_PER_MINUTE)
428 }
429
430 #[stable(feature = "duration_constructors_lite", since = "1.91.0")]
447 #[rustc_const_stable(feature = "duration_constructors_lite", since = "1.91.0")]
448 #[must_use]
449 #[inline]
450 pub const fn from_mins(mins: u64) -> Duration {
451 if mins > u64::MAX / SECS_PER_MINUTE {
452 {
crate::panicking::panic_fmt(format_args!("overflow in Duration::from_mins"));
};panic!("overflow in Duration::from_mins");
453 }
454
455 Duration::from_secs(mins * SECS_PER_MINUTE)
456 }
457
458 #[must_use]
475 #[stable(feature = "duration_zero", since = "1.53.0")]
476 #[rustc_const_stable(feature = "duration_zero", since = "1.53.0")]
477 #[inline]
478 pub const fn is_zero(&self) -> bool {
479 self.secs == 0 && self.nanos.as_inner() == 0
480 }
481
482 #[stable(feature = "duration", since = "1.3.0")]
503 #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
504 #[must_use]
505 #[inline]
506 pub const fn as_secs(&self) -> u64 {
507 self.secs
508 }
509
510 #[stable(feature = "duration_extras", since = "1.27.0")]
526 #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
527 #[must_use]
528 #[inline]
529 pub const fn subsec_millis(&self) -> u32 {
530 self.nanos.as_inner() / NANOS_PER_MILLI
531 }
532
533 #[stable(feature = "duration_extras", since = "1.27.0")]
549 #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
550 #[must_use]
551 #[inline]
552 pub const fn subsec_micros(&self) -> u32 {
553 self.nanos.as_inner() / NANOS_PER_MICRO
554 }
555
556 #[stable(feature = "duration", since = "1.3.0")]
572 #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
573 #[must_use]
574 #[inline]
575 pub const fn subsec_nanos(&self) -> u32 {
576 self.nanos.as_inner()
577 }
578
579 #[stable(feature = "duration_as_u128", since = "1.33.0")]
590 #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
591 #[must_use]
592 #[inline]
593 pub const fn as_millis(&self) -> u128 {
594 self.secs as u128 * MILLIS_PER_SEC as u128
595 + (self.nanos.as_inner() / NANOS_PER_MILLI) as u128
596 }
597
598 #[stable(feature = "duration_as_u128", since = "1.33.0")]
609 #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
610 #[must_use]
611 #[inline]
612 pub const fn as_micros(&self) -> u128 {
613 self.secs as u128 * MICROS_PER_SEC as u128
614 + (self.nanos.as_inner() / NANOS_PER_MICRO) as u128
615 }
616
617 #[stable(feature = "duration_as_u128", since = "1.33.0")]
628 #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
629 #[must_use]
630 #[inline]
631 pub const fn as_nanos(&self) -> u128 {
632 self.secs as u128 * NANOS_PER_SEC as u128 + self.nanos.as_inner() as u128
633 }
634
635 #[stable(feature = "duration_abs_diff", since = "1.81.0")]
646 #[rustc_const_stable(feature = "duration_abs_diff", since = "1.81.0")]
647 #[must_use = "this returns the result of the operation, \
648 without modifying the original"]
649 #[inline]
650 pub const fn abs_diff(self, other: Duration) -> Duration {
651 if let Some(res) = self.checked_sub(other) { res } else { other.checked_sub(self).unwrap() }
652 }
653
654 #[stable(feature = "duration_checked_ops", since = "1.16.0")]
666 #[must_use = "this returns the result of the operation, \
667 without modifying the original"]
668 #[inline]
669 #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
670 pub const fn checked_add(self, rhs: Duration) -> Option<Duration> {
671 if let Some(mut secs) = self.secs.checked_add(rhs.secs) {
672 let mut nanos = self.nanos.as_inner() + rhs.nanos.as_inner();
673 if nanos >= NANOS_PER_SEC {
674 nanos -= NANOS_PER_SEC;
675 let Some(new_secs) = secs.checked_add(1) else {
676 return None;
677 };
678 secs = new_secs;
679 }
680 if true {
if !(nanos < NANOS_PER_SEC) {
crate::panicking::panic("assertion failed: nanos < NANOS_PER_SEC")
};
};debug_assert!(nanos < NANOS_PER_SEC);
681 Some(Duration::new(secs, nanos))
682 } else {
683 None
684 }
685 }
686
687 #[stable(feature = "duration_saturating_ops", since = "1.53.0")]
699 #[must_use = "this returns the result of the operation, \
700 without modifying the original"]
701 #[inline]
702 #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
703 pub const fn saturating_add(self, rhs: Duration) -> Duration {
704 match self.checked_add(rhs) {
705 Some(res) => res,
706 None => Duration::MAX,
707 }
708 }
709
710 #[stable(feature = "duration_checked_ops", since = "1.16.0")]
722 #[must_use = "this returns the result of the operation, \
723 without modifying the original"]
724 #[inline]
725 #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
726 pub const fn checked_sub(self, rhs: Duration) -> Option<Duration> {
727 if let Some(mut secs) = self.secs.checked_sub(rhs.secs) {
728 let nanos = if self.nanos.as_inner() >= rhs.nanos.as_inner() {
729 self.nanos.as_inner() - rhs.nanos.as_inner()
730 } else if let Some(sub_secs) = secs.checked_sub(1) {
731 secs = sub_secs;
732 self.nanos.as_inner() + NANOS_PER_SEC - rhs.nanos.as_inner()
733 } else {
734 return None;
735 };
736 if true {
if !(nanos < NANOS_PER_SEC) {
crate::panicking::panic("assertion failed: nanos < NANOS_PER_SEC")
};
};debug_assert!(nanos < NANOS_PER_SEC);
737 Some(Duration::new(secs, nanos))
738 } else {
739 None
740 }
741 }
742
743 #[stable(feature = "duration_saturating_ops", since = "1.53.0")]
755 #[must_use = "this returns the result of the operation, \
756 without modifying the original"]
757 #[inline]
758 #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
759 pub const fn saturating_sub(self, rhs: Duration) -> Duration {
760 match self.checked_sub(rhs) {
761 Some(res) => res,
762 None => Duration::ZERO,
763 }
764 }
765
766 #[stable(feature = "duration_checked_ops", since = "1.16.0")]
778 #[must_use = "this returns the result of the operation, \
779 without modifying the original"]
780 #[inline]
781 #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
782 pub const fn checked_mul(self, rhs: u32) -> Option<Duration> {
783 let total_nanos = self.nanos.as_inner() as u64 * rhs as u64;
785 let extra_secs = total_nanos / (NANOS_PER_SEC as u64);
786 let nanos = (total_nanos % (NANOS_PER_SEC as u64)) as u32;
787 if let Some(s) = self.secs.checked_mul(rhs as u64) {
789 if let Some(secs) = s.checked_add(extra_secs) {
790 if true {
if !(nanos < NANOS_PER_SEC) {
crate::panicking::panic("assertion failed: nanos < NANOS_PER_SEC")
};
};debug_assert!(nanos < NANOS_PER_SEC);
791 return Some(Duration::new(secs, nanos));
792 }
793 }
794 None
795 }
796
797 #[stable(feature = "duration_saturating_ops", since = "1.53.0")]
809 #[must_use = "this returns the result of the operation, \
810 without modifying the original"]
811 #[inline]
812 #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
813 pub const fn saturating_mul(self, rhs: u32) -> Duration {
814 match self.checked_mul(rhs) {
815 Some(res) => res,
816 None => Duration::MAX,
817 }
818 }
819
820 #[stable(feature = "duration_checked_ops", since = "1.16.0")]
833 #[must_use = "this returns the result of the operation, \
834 without modifying the original"]
835 #[inline]
836 #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
837 pub const fn checked_div(self, rhs: u32) -> Option<Duration> {
838 if rhs != 0 {
839 let (secs, extra_secs) = (self.secs / (rhs as u64), self.secs % (rhs as u64));
840 let (mut nanos, extra_nanos) =
841 (self.nanos.as_inner() / rhs, self.nanos.as_inner() % rhs);
842 nanos +=
843 ((extra_secs * (NANOS_PER_SEC as u64) + extra_nanos as u64) / (rhs as u64)) as u32;
844 if true {
if !(nanos < NANOS_PER_SEC) {
crate::panicking::panic("assertion failed: nanos < NANOS_PER_SEC")
};
};debug_assert!(nanos < NANOS_PER_SEC);
845 Some(Duration::new(secs, nanos))
846 } else {
847 None
848 }
849 }
850
851 #[stable(feature = "duration_float", since = "1.38.0")]
863 #[must_use]
864 #[inline]
865 #[rustc_const_stable(feature = "duration_consts_float", since = "1.83.0")]
866 pub const fn as_secs_f64(&self) -> f64 {
867 (self.secs as f64) + (self.nanos.as_inner() as f64) / (NANOS_PER_SEC as f64)
868 }
869
870 #[stable(feature = "duration_float", since = "1.38.0")]
882 #[must_use]
883 #[inline]
884 #[rustc_const_stable(feature = "duration_consts_float", since = "1.83.0")]
885 pub const fn as_secs_f32(&self) -> f32 {
886 (self.secs as f32) + (self.nanos.as_inner() as f32) / (NANOS_PER_SEC as f32)
887 }
888
889 #[unstable(feature = "duration_millis_float", issue = "122451")]
902 #[must_use]
903 #[inline]
904 pub const fn as_millis_f64(&self) -> f64 {
905 (self.secs as f64) * (MILLIS_PER_SEC as f64)
906 + (self.nanos.as_inner() as f64) / (NANOS_PER_MILLI as f64)
907 }
908
909 #[unstable(feature = "duration_millis_float", issue = "122451")]
922 #[must_use]
923 #[inline]
924 pub const fn as_millis_f32(&self) -> f32 {
925 (self.secs as f32) * (MILLIS_PER_SEC as f32)
926 + (self.nanos.as_inner() as f32) / (NANOS_PER_MILLI as f32)
927 }
928
929 #[stable(feature = "duration_float", since = "1.38.0")]
957 #[must_use]
958 #[inline]
959 pub fn from_secs_f64(secs: f64) -> Duration {
960 match Duration::try_from_secs_f64(secs) {
961 Ok(v) => v,
962 Err(e) => { crate::panicking::panic_fmt(format_args!("{0}", e)); }panic!("{e}"),
963 }
964 }
965
966 #[stable(feature = "duration_float", since = "1.38.0")]
994 #[must_use]
995 #[inline]
996 pub fn from_secs_f32(secs: f32) -> Duration {
997 match Duration::try_from_secs_f32(secs) {
998 Ok(v) => v,
999 Err(e) => { crate::panicking::panic_fmt(format_args!("{0}", e)); }panic!("{e}"),
1000 }
1001 }
1002
1003 #[stable(feature = "duration_float", since = "1.38.0")]
1049 #[must_use = "this returns the result of the operation, \
1050 without modifying the original"]
1051 #[inline]
1052 pub fn mul_f64(self, rhs: f64) -> Duration {
1053 Duration::from_secs_f64(rhs * self.as_secs_f64())
1054 }
1055
1056 #[stable(feature = "duration_float", since = "1.38.0")]
1077 #[must_use = "this returns the result of the operation, \
1078 without modifying the original"]
1079 #[inline]
1080 pub fn mul_f32(self, rhs: f32) -> Duration {
1081 self.mul_f64(rhs.into())
1082 }
1083
1084 #[stable(feature = "duration_float", since = "1.38.0")]
1130 #[must_use = "this returns the result of the operation, \
1131 without modifying the original"]
1132 #[inline]
1133 pub fn div_f64(self, rhs: f64) -> Duration {
1134 Duration::from_secs_f64(self.as_secs_f64() / rhs)
1135 }
1136
1137 #[stable(feature = "duration_float", since = "1.38.0")]
1158 #[must_use = "this returns the result of the operation, \
1159 without modifying the original"]
1160 #[inline]
1161 pub fn div_f32(self, rhs: f32) -> Duration {
1162 self.div_f64(rhs.into())
1163 }
1164
1165 #[stable(feature = "div_duration", since = "1.80.0")]
1176 #[must_use = "this returns the result of the operation, \
1177 without modifying the original"]
1178 #[inline]
1179 #[rustc_const_stable(feature = "duration_consts_float", since = "1.83.0")]
1180 pub const fn div_duration_f64(self, rhs: Duration) -> f64 {
1181 let self_nanos =
1182 (self.secs as f64) * (NANOS_PER_SEC as f64) + (self.nanos.as_inner() as f64);
1183 let rhs_nanos = (rhs.secs as f64) * (NANOS_PER_SEC as f64) + (rhs.nanos.as_inner() as f64);
1184 self_nanos / rhs_nanos
1185 }
1186
1187 #[stable(feature = "div_duration", since = "1.80.0")]
1198 #[must_use = "this returns the result of the operation, \
1199 without modifying the original"]
1200 #[inline]
1201 #[rustc_const_stable(feature = "duration_consts_float", since = "1.83.0")]
1202 pub const fn div_duration_f32(self, rhs: Duration) -> f32 {
1203 let self_nanos =
1204 (self.secs as f32) * (NANOS_PER_SEC as f32) + (self.nanos.as_inner() as f32);
1205 let rhs_nanos = (rhs.secs as f32) * (NANOS_PER_SEC as f32) + (rhs.nanos.as_inner() as f32);
1206 self_nanos / rhs_nanos
1207 }
1208
1209 #[unstable(feature = "duration_integer_division", issue = "149573")]
1222 #[must_use = "this returns the result of the operation, \
1223 without modifying the original"]
1224 #[inline]
1225 pub const fn div_duration_floor(self, rhs: Duration) -> u128 {
1226 self.as_nanos().div_floor(rhs.as_nanos())
1227 }
1228
1229 #[unstable(feature = "duration_integer_division", issue = "149573")]
1242 #[must_use = "this returns the result of the operation, \
1243 without modifying the original"]
1244 #[inline]
1245 pub const fn div_duration_ceil(self, rhs: Duration) -> u128 {
1246 self.as_nanos().div_ceil(rhs.as_nanos())
1247 }
1248}
1249
1250#[stable(feature = "duration", since = "1.3.0")]
1251#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
1252impl const Add for Duration {
1253 type Output = Duration;
1254
1255 #[inline]
1256 fn add(self, rhs: Duration) -> Duration {
1257 self.checked_add(rhs).expect("overflow when adding durations")
1258 }
1259}
1260
1261#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
1262#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
1263impl const AddAssign for Duration {
1264 #[inline]
1265 fn add_assign(&mut self, rhs: Duration) {
1266 *self = *self + rhs;
1267 }
1268}
1269
1270#[stable(feature = "duration", since = "1.3.0")]
1271#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
1272impl const Sub for Duration {
1273 type Output = Duration;
1274
1275 #[inline]
1276 fn sub(self, rhs: Duration) -> Duration {
1277 self.checked_sub(rhs).expect("overflow when subtracting durations")
1278 }
1279}
1280
1281#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
1282#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
1283impl const SubAssign for Duration {
1284 #[inline]
1285 fn sub_assign(&mut self, rhs: Duration) {
1286 *self = *self - rhs;
1287 }
1288}
1289
1290#[stable(feature = "duration", since = "1.3.0")]
1291#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
1292impl const Mul<u32> for Duration {
1293 type Output = Duration;
1294
1295 #[inline]
1296 fn mul(self, rhs: u32) -> Duration {
1297 self.checked_mul(rhs).expect("overflow when multiplying duration by scalar")
1298 }
1299}
1300
1301#[stable(feature = "symmetric_u32_duration_mul", since = "1.31.0")]
1302#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
1303impl const Mul<Duration> for u32 {
1304 type Output = Duration;
1305
1306 #[inline]
1307 fn mul(self, rhs: Duration) -> Duration {
1308 rhs * self
1309 }
1310}
1311
1312#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
1313#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
1314impl const MulAssign<u32> for Duration {
1315 #[inline]
1316 fn mul_assign(&mut self, rhs: u32) {
1317 *self = *self * rhs;
1318 }
1319}
1320
1321#[stable(feature = "duration", since = "1.3.0")]
1322#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
1323impl const Div<u32> for Duration {
1324 type Output = Duration;
1325
1326 #[inline]
1327 #[track_caller]
1328 fn div(self, rhs: u32) -> Duration {
1329 self.checked_div(rhs).expect("divide by zero error when dividing duration by scalar")
1330 }
1331}
1332
1333#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
1334#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
1335impl const DivAssign<u32> for Duration {
1336 #[inline]
1337 #[track_caller]
1338 fn div_assign(&mut self, rhs: u32) {
1339 *self = *self / rhs;
1340 }
1341}
1342
1343macro_rules! sum_durations {
1344 ($iter:expr) => {{
1345 let mut total_secs: u64 = 0;
1346 let mut total_nanos: u64 = 0;
1347
1348 for entry in $iter {
1349 total_secs =
1350 total_secs.checked_add(entry.secs).expect("overflow in iter::sum over durations");
1351 total_nanos = match total_nanos.checked_add(entry.nanos.as_inner() as u64) {
1352 Some(n) => n,
1353 None => {
1354 total_secs = total_secs
1355 .checked_add(total_nanos / NANOS_PER_SEC as u64)
1356 .expect("overflow in iter::sum over durations");
1357 (total_nanos % NANOS_PER_SEC as u64) + entry.nanos.as_inner() as u64
1358 }
1359 };
1360 }
1361 total_secs = total_secs
1362 .checked_add(total_nanos / NANOS_PER_SEC as u64)
1363 .expect("overflow in iter::sum over durations");
1364 total_nanos = total_nanos % NANOS_PER_SEC as u64;
1365 Duration::new(total_secs, total_nanos as u32)
1366 }};
1367}
1368
1369#[stable(feature = "duration_sum", since = "1.16.0")]
1370impl Sum for Duration {
1371 fn sum<I: Iterator<Item = Duration>>(iter: I) -> Duration {
1372 {
let mut total_secs: u64 = 0;
let mut total_nanos: u64 = 0;
for entry in iter {
total_secs =
total_secs.checked_add(entry.secs).expect("overflow in iter::sum over durations");
total_nanos =
match total_nanos.checked_add(entry.nanos.as_inner() as u64) {
Some(n) => n,
None => {
total_secs =
total_secs.checked_add(total_nanos /
NANOS_PER_SEC as
u64).expect("overflow in iter::sum over durations");
(total_nanos % NANOS_PER_SEC as u64) +
entry.nanos.as_inner() as u64
}
};
}
total_secs =
total_secs.checked_add(total_nanos /
NANOS_PER_SEC as
u64).expect("overflow in iter::sum over durations");
total_nanos = total_nanos % NANOS_PER_SEC as u64;
Duration::new(total_secs, total_nanos as u32)
}sum_durations!(iter)
1373 }
1374}
1375
1376#[stable(feature = "duration_sum", since = "1.16.0")]
1377impl<'a> Sum<&'a Duration> for Duration {
1378 fn sum<I: Iterator<Item = &'a Duration>>(iter: I) -> Duration {
1379 {
let mut total_secs: u64 = 0;
let mut total_nanos: u64 = 0;
for entry in iter {
total_secs =
total_secs.checked_add(entry.secs).expect("overflow in iter::sum over durations");
total_nanos =
match total_nanos.checked_add(entry.nanos.as_inner() as u64) {
Some(n) => n,
None => {
total_secs =
total_secs.checked_add(total_nanos /
NANOS_PER_SEC as
u64).expect("overflow in iter::sum over durations");
(total_nanos % NANOS_PER_SEC as u64) +
entry.nanos.as_inner() as u64
}
};
}
total_secs =
total_secs.checked_add(total_nanos /
NANOS_PER_SEC as
u64).expect("overflow in iter::sum over durations");
total_nanos = total_nanos % NANOS_PER_SEC as u64;
Duration::new(total_secs, total_nanos as u32)
}sum_durations!(iter)
1380 }
1381}
1382
1383#[stable(feature = "duration_debug_impl", since = "1.27.0")]
1384impl fmt::Debug for Duration {
1385 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1386 fn fmt_decimal(
1400 f: &mut fmt::Formatter<'_>,
1401 integer_part: u64,
1402 mut fractional_part: u32,
1403 mut divisor: u32,
1404 prefix: &str,
1405 postfix: &str,
1406 ) -> fmt::Result {
1407 let mut buf = [b'0'; 9];
1412
1413 let mut pos = 0;
1415
1416 while fractional_part > 0 && pos < f.precision().unwrap_or(9) {
1419 buf[pos] = b'0' + (fractional_part / divisor) as u8;
1421
1422 fractional_part %= divisor;
1423 divisor /= 10;
1424 pos += 1;
1425 }
1426
1427 let integer_part = if fractional_part > 0 && fractional_part >= divisor * 5 {
1436 let is_tie = fractional_part == divisor * 5;
1438 let last_digit_is_odd = if pos > 0 {
1439 (buf[pos - 1] - b'0') % 2 == 1
1440 } else {
1441 (integer_part % 2) == 1
1443 };
1444
1445 if is_tie && !last_digit_is_odd {
1446 Some(integer_part)
1447 } else {
1448 let mut rev_pos = pos;
1451 let mut carry = true;
1452 while carry && rev_pos > 0 {
1453 rev_pos -= 1;
1454
1455 if buf[rev_pos] < b'9' {
1460 buf[rev_pos] += 1;
1461 carry = false;
1462 } else {
1463 buf[rev_pos] = b'0';
1464 }
1465 }
1466
1467 if carry {
1471 integer_part.checked_add(1)
1477 } else {
1478 Some(integer_part)
1479 }
1480 }
1481 } else {
1482 Some(integer_part)
1483 };
1484
1485 let end = f.precision().map(|p| crate::cmp::min(p, 9)).unwrap_or(pos);
1489
1490 let emit_without_padding = |f: &mut fmt::Formatter<'_>| {
1493 if let Some(integer_part) = integer_part {
1494 f.write_fmt(format_args!("{0}{1}", prefix, integer_part))write!(f, "{}{}", prefix, integer_part)?;
1495 } else {
1496 f.write_fmt(format_args!("{0}18446744073709551616", prefix))write!(f, "{}18446744073709551616", prefix)?;
1498 }
1499
1500 if end > 0 {
1502 let s = unsafe { crate::str::from_utf8_unchecked(&buf[..end]) };
1505
1506 let w = f.precision().unwrap_or(pos);
1508 f.write_fmt(format_args!(".{0:0<1$}", s, w))write!(f, ".{:0<width$}", s, width = w)?;
1509 }
1510
1511 f.write_fmt(format_args!("{0}", postfix))write!(f, "{}", postfix)
1512 };
1513
1514 match f.width() {
1515 None => {
1516 emit_without_padding(f)
1519 }
1520 Some(requested_w) => {
1521 let mut actual_w = prefix.len() + postfix.chars().count();
1527 if let Some(integer_part) = integer_part {
1529 if let Some(log) = integer_part.checked_ilog10() {
1530 actual_w += 1 + log as usize;
1532 } else {
1533 actual_w += 1;
1535 }
1536 } else {
1537 actual_w += 20;
1539 }
1540 if end > 0 {
1542 let frac_part_w = f.precision().unwrap_or(pos);
1543 actual_w += 1 + frac_part_w;
1544 }
1545
1546 if requested_w <= actual_w {
1547 emit_without_padding(f)
1549 } else {
1550 let default_align = fmt::Alignment::Left;
1552 let post_padding =
1553 f.padding((requested_w - actual_w) as u16, default_align)?;
1554 emit_without_padding(f)?;
1555 post_padding.write(f)
1556 }
1557 }
1558 }
1559 }
1560
1561 let prefix = if f.sign_plus() { "+" } else { "" };
1563
1564 if self.secs > 0 {
1565 fmt_decimal(f, self.secs, self.nanos.as_inner(), NANOS_PER_SEC / 10, prefix, "s")
1566 } else if self.nanos.as_inner() >= NANOS_PER_MILLI {
1567 fmt_decimal(
1568 f,
1569 (self.nanos.as_inner() / NANOS_PER_MILLI) as u64,
1570 self.nanos.as_inner() % NANOS_PER_MILLI,
1571 NANOS_PER_MILLI / 10,
1572 prefix,
1573 "ms",
1574 )
1575 } else if self.nanos.as_inner() >= NANOS_PER_MICRO {
1576 fmt_decimal(
1577 f,
1578 (self.nanos.as_inner() / NANOS_PER_MICRO) as u64,
1579 self.nanos.as_inner() % NANOS_PER_MICRO,
1580 NANOS_PER_MICRO / 10,
1581 prefix,
1582 "µs",
1583 )
1584 } else {
1585 fmt_decimal(f, self.nanos.as_inner() as u64, 0, 1, prefix, "ns")
1586 }
1587 }
1588}
1589
1590#[derive(#[automatically_derived]
#[stable(feature = "duration_checked_float", since = "1.66.0")]
impl crate::fmt::Debug for TryFromFloatSecsError {
#[inline]
fn fmt(&self, f: &mut crate::fmt::Formatter) -> crate::fmt::Result {
crate::fmt::Formatter::debug_struct_field1_finish(f,
"TryFromFloatSecsError", "kind", &&self.kind)
}
}Debug, #[automatically_derived]
#[stable(feature = "duration_checked_float", since = "1.66.0")]
impl crate::clone::Clone for TryFromFloatSecsError {
#[inline]
fn clone(&self) -> TryFromFloatSecsError {
TryFromFloatSecsError { kind: crate::clone::Clone::clone(&self.kind) }
}
}Clone, #[automatically_derived]
#[stable(feature = "duration_checked_float", since = "1.66.0")]
impl crate::cmp::PartialEq for TryFromFloatSecsError {
#[inline]
fn eq(&self, other: &TryFromFloatSecsError) -> bool {
self.kind == other.kind
}
}PartialEq, #[automatically_derived]
#[stable(feature = "duration_checked_float", since = "1.66.0")]
impl crate::cmp::Eq for TryFromFloatSecsError {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: crate::cmp::AssertParamIsEq<TryFromFloatSecsErrorKind>;
}
}Eq)]
1606#[stable(feature = "duration_checked_float", since = "1.66.0")]
1607pub struct TryFromFloatSecsError {
1608 kind: TryFromFloatSecsErrorKind,
1609}
1610
1611#[stable(feature = "duration_checked_float", since = "1.66.0")]
1612impl fmt::Display for TryFromFloatSecsError {
1613 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1614 match self.kind {
1615 TryFromFloatSecsErrorKind::Negative => {
1616 "cannot convert float seconds to Duration: value is negative"
1617 }
1618 TryFromFloatSecsErrorKind::OverflowOrNan => {
1619 "cannot convert float seconds to Duration: value is either too big or NaN"
1620 }
1621 }
1622 .fmt(f)
1623 }
1624}
1625
1626#[derive(#[automatically_derived]
impl crate::fmt::Debug for TryFromFloatSecsErrorKind {
#[inline]
fn fmt(&self, f: &mut crate::fmt::Formatter) -> crate::fmt::Result {
crate::fmt::Formatter::write_str(f,
match self {
TryFromFloatSecsErrorKind::Negative => "Negative",
TryFromFloatSecsErrorKind::OverflowOrNan => "OverflowOrNan",
})
}
}Debug, #[automatically_derived]
impl crate::clone::Clone for TryFromFloatSecsErrorKind {
#[inline]
fn clone(&self) -> TryFromFloatSecsErrorKind {
match self {
TryFromFloatSecsErrorKind::Negative =>
TryFromFloatSecsErrorKind::Negative,
TryFromFloatSecsErrorKind::OverflowOrNan =>
TryFromFloatSecsErrorKind::OverflowOrNan,
}
}
}Clone, #[automatically_derived]
impl crate::cmp::PartialEq for TryFromFloatSecsErrorKind {
#[inline]
fn eq(&self, other: &TryFromFloatSecsErrorKind) -> bool {
let __self_discr = crate::intrinsics::discriminant_value(self);
let __arg1_discr = crate::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl crate::cmp::Eq for TryFromFloatSecsErrorKind {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq)]
1627enum TryFromFloatSecsErrorKind {
1628 Negative,
1630 OverflowOrNan,
1632}
1633
1634macro_rules! try_from_secs {
1635 (
1636 secs = $secs: expr,
1637 mantissa_bits = $mant_bits: literal,
1638 exponent_bits = $exp_bits: literal,
1639 offset = $offset: literal,
1640 bits_ty = $bits_ty:ty,
1641 double_ty = $double_ty:ty,
1642 ) => {{
1643 const MIN_EXP: i16 = 1 - (1i16 << $exp_bits) / 2;
1644 const MANT_MASK: $bits_ty = (1 << $mant_bits) - 1;
1645 const EXP_MASK: $bits_ty = (1 << $exp_bits) - 1;
1646
1647 if $secs < 0.0 {
1648 return Err(TryFromFloatSecsError { kind: TryFromFloatSecsErrorKind::Negative });
1649 }
1650
1651 let bits = $secs.to_bits();
1652 let mant = (bits & MANT_MASK) | (MANT_MASK + 1);
1653 let exp = ((bits >> $mant_bits) & EXP_MASK) as i16 + MIN_EXP;
1654
1655 let (secs, nanos) = if exp < -31 {
1656 (0u64, 0u32)
1658 } else if exp < 0 {
1659 let t = <$double_ty>::from(mant) << ($offset + exp);
1661 let nanos_offset = $mant_bits + $offset;
1662 let nanos_tmp = u128::from(NANOS_PER_SEC) * u128::from(t);
1663 let nanos = (nanos_tmp >> nanos_offset) as u32;
1664
1665 let rem_mask = (1 << nanos_offset) - 1;
1666 let rem_msb_mask = 1 << (nanos_offset - 1);
1667 let rem = nanos_tmp & rem_mask;
1668 let is_tie = rem == rem_msb_mask;
1669 let is_even = (nanos & 1) == 0;
1670 let rem_msb = nanos_tmp & rem_msb_mask == 0;
1671 let add_ns = !(rem_msb || (is_even && is_tie));
1672
1673 let nanos = nanos + add_ns as u32;
1676 if ($mant_bits == 23) || (nanos != NANOS_PER_SEC) { (0, nanos) } else { (1, 0) }
1677 } else if exp < $mant_bits {
1678 let secs = u64::from(mant >> ($mant_bits - exp));
1679 let t = <$double_ty>::from((mant << exp) & MANT_MASK);
1680 let nanos_offset = $mant_bits;
1681 let nanos_tmp = <$double_ty>::from(NANOS_PER_SEC) * t;
1682 let nanos = (nanos_tmp >> nanos_offset) as u32;
1683
1684 let rem_mask = (1 << nanos_offset) - 1;
1685 let rem_msb_mask = 1 << (nanos_offset - 1);
1686 let rem = nanos_tmp & rem_mask;
1687 let is_tie = rem == rem_msb_mask;
1688 let is_even = (nanos & 1) == 0;
1689 let rem_msb = nanos_tmp & rem_msb_mask == 0;
1690 let add_ns = !(rem_msb || (is_even && is_tie));
1691
1692 let nanos = nanos + add_ns as u32;
1697 if ($mant_bits == 23) || (nanos != NANOS_PER_SEC) {
1698 (secs, nanos)
1699 } else {
1700 (secs + 1, 0)
1701 }
1702 } else if exp < 64 {
1703 let secs = u64::from(mant) << (exp - $mant_bits);
1705 (secs, 0)
1706 } else {
1707 return Err(TryFromFloatSecsError { kind: TryFromFloatSecsErrorKind::OverflowOrNan });
1708 };
1709
1710 Ok(Duration::new(secs, nanos))
1711 }};
1712}
1713
1714impl Duration {
1715 #[stable(feature = "duration_checked_float", since = "1.66.0")]
1771 #[inline]
1772 pub fn try_from_secs_f32(secs: f32) -> Result<Duration, TryFromFloatSecsError> {
1773 {
const MIN_EXP: i16 = 1 - (1i16 << 8) / 2;
const MANT_MASK: u32 = (1 << 23) - 1;
const EXP_MASK: u32 = (1 << 8) - 1;
if secs < 0.0 {
return Err(TryFromFloatSecsError {
kind: TryFromFloatSecsErrorKind::Negative,
});
}
let bits = secs.to_bits();
let mant = (bits & MANT_MASK) | (MANT_MASK + 1);
let exp = ((bits >> 23) & EXP_MASK) as i16 + MIN_EXP;
let (secs, nanos) =
if exp < -31 {
(0u64, 0u32)
} else if exp < 0 {
let t = <u64>::from(mant) << (41 + exp);
let nanos_offset = 23 + 41;
let nanos_tmp = u128::from(NANOS_PER_SEC) * u128::from(t);
let nanos = (nanos_tmp >> nanos_offset) as u32;
let rem_mask = (1 << nanos_offset) - 1;
let rem_msb_mask = 1 << (nanos_offset - 1);
let rem = nanos_tmp & rem_mask;
let is_tie = rem == rem_msb_mask;
let is_even = (nanos & 1) == 0;
let rem_msb = nanos_tmp & rem_msb_mask == 0;
let add_ns = !(rem_msb || (is_even && is_tie));
let nanos = nanos + add_ns as u32;
if (23 == 23) || (nanos != NANOS_PER_SEC) {
(0, nanos)
} else { (1, 0) }
} else if exp < 23 {
let secs = u64::from(mant >> (23 - exp));
let t = <u64>::from((mant << exp) & MANT_MASK);
let nanos_offset = 23;
let nanos_tmp = <u64>::from(NANOS_PER_SEC) * t;
let nanos = (nanos_tmp >> nanos_offset) as u32;
let rem_mask = (1 << nanos_offset) - 1;
let rem_msb_mask = 1 << (nanos_offset - 1);
let rem = nanos_tmp & rem_mask;
let is_tie = rem == rem_msb_mask;
let is_even = (nanos & 1) == 0;
let rem_msb = nanos_tmp & rem_msb_mask == 0;
let add_ns = !(rem_msb || (is_even && is_tie));
let nanos = nanos + add_ns as u32;
if (23 == 23) || (nanos != NANOS_PER_SEC) {
(secs, nanos)
} else { (secs + 1, 0) }
} else if exp < 64 {
let secs = u64::from(mant) << (exp - 23);
(secs, 0)
} else {
return Err(TryFromFloatSecsError {
kind: TryFromFloatSecsErrorKind::OverflowOrNan,
});
};
Ok(Duration::new(secs, nanos))
}try_from_secs!(
1774 secs = secs,
1775 mantissa_bits = 23,
1776 exponent_bits = 8,
1777 offset = 41,
1778 bits_ty = u32,
1779 double_ty = u64,
1780 )
1781 }
1782
1783 #[stable(feature = "duration_checked_float", since = "1.66.0")]
1847 #[inline]
1848 pub fn try_from_secs_f64(secs: f64) -> Result<Duration, TryFromFloatSecsError> {
1849 {
const MIN_EXP: i16 = 1 - (1i16 << 11) / 2;
const MANT_MASK: u64 = (1 << 52) - 1;
const EXP_MASK: u64 = (1 << 11) - 1;
if secs < 0.0 {
return Err(TryFromFloatSecsError {
kind: TryFromFloatSecsErrorKind::Negative,
});
}
let bits = secs.to_bits();
let mant = (bits & MANT_MASK) | (MANT_MASK + 1);
let exp = ((bits >> 52) & EXP_MASK) as i16 + MIN_EXP;
let (secs, nanos) =
if exp < -31 {
(0u64, 0u32)
} else if exp < 0 {
let t = <u128>::from(mant) << (44 + exp);
let nanos_offset = 52 + 44;
let nanos_tmp = u128::from(NANOS_PER_SEC) * u128::from(t);
let nanos = (nanos_tmp >> nanos_offset) as u32;
let rem_mask = (1 << nanos_offset) - 1;
let rem_msb_mask = 1 << (nanos_offset - 1);
let rem = nanos_tmp & rem_mask;
let is_tie = rem == rem_msb_mask;
let is_even = (nanos & 1) == 0;
let rem_msb = nanos_tmp & rem_msb_mask == 0;
let add_ns = !(rem_msb || (is_even && is_tie));
let nanos = nanos + add_ns as u32;
if (52 == 23) || (nanos != NANOS_PER_SEC) {
(0, nanos)
} else { (1, 0) }
} else if exp < 52 {
let secs = u64::from(mant >> (52 - exp));
let t = <u128>::from((mant << exp) & MANT_MASK);
let nanos_offset = 52;
let nanos_tmp = <u128>::from(NANOS_PER_SEC) * t;
let nanos = (nanos_tmp >> nanos_offset) as u32;
let rem_mask = (1 << nanos_offset) - 1;
let rem_msb_mask = 1 << (nanos_offset - 1);
let rem = nanos_tmp & rem_mask;
let is_tie = rem == rem_msb_mask;
let is_even = (nanos & 1) == 0;
let rem_msb = nanos_tmp & rem_msb_mask == 0;
let add_ns = !(rem_msb || (is_even && is_tie));
let nanos = nanos + add_ns as u32;
if (52 == 23) || (nanos != NANOS_PER_SEC) {
(secs, nanos)
} else { (secs + 1, 0) }
} else if exp < 64 {
let secs = u64::from(mant) << (exp - 52);
(secs, 0)
} else {
return Err(TryFromFloatSecsError {
kind: TryFromFloatSecsErrorKind::OverflowOrNan,
});
};
Ok(Duration::new(secs, nanos))
}try_from_secs!(
1850 secs = secs,
1851 mantissa_bits = 52,
1852 exponent_bits = 11,
1853 offset = 44,
1854 bits_ty = u64,
1855 double_ty = u128,
1856 )
1857 }
1858}