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]
#[doc(hidden)]
#[stable(feature = "duration", since = "1.3.0")]
unsafe impl crate::clone::TrivialClone for Duration { }
#[automatically_derived]
#[stable(feature = "duration", since = "1.3.0")]
impl crate::clone::Clone for Duration {
#[inline]
fn clone(&self) -> Self {
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::marker::StructuralPartialEq for Duration { }
#[automatically_derived]
#[stable(feature = "duration", since = "1.3.0")]
impl crate::cmp::PartialEq for Duration {
#[inline]
fn eq(&self, other: &Self) -> 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: &Self)
-> 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: &Self) -> 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() -> Self {
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 #[unstable(feature = "duration_constants", issue = "57391")]
157 pub const WEEK: Duration = Duration::from_weeks(1);
159
160 #[unstable(feature = "duration_constants", issue = "57391")]
178 pub const DAY: Duration = Duration::from_days(1);
180
181 #[unstable(feature = "duration_constants", issue = "57391")]
198 pub const HOUR: Duration = Duration::from_hours(1);
199
200 #[unstable(feature = "duration_constants", issue = "57391")]
217 pub const MINUTE: Duration = Duration::from_mins(1);
218
219 #[stable(feature = "duration_zero", since = "1.53.0")]
231 pub const ZERO: Duration = Duration::from_nanos(0);
232
233 #[stable(feature = "duration_saturating_ops", since = "1.53.0")]
250 pub const MAX: Duration = Duration::new(u64::MAX, NANOS_PER_SEC - 1);
251
252 #[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 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("adding carry-over seconds from nanoseconds should not exceed u64::MAX");
282 let nanos = nanos % NANOS_PER_SEC;
283 Duration { secs, nanos: unsafe { Nanoseconds::new_unchecked(nanos) } }
285 }
286 }
287
288 #[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 #[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 let subsec_nanos = unsafe { Nanoseconds::new_unchecked(subsec_millis * NANOS_PER_MILLI) };
330
331 Duration { secs, nanos: subsec_nanos }
332 }
333
334 #[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 let subsec_nanos = unsafe { Nanoseconds::new_unchecked(subsec_micros * NANOS_PER_MICRO) };
356
357 Duration { secs, nanos: subsec_nanos }
358 }
359
360 #[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 let subsec_nanos = unsafe { Nanoseconds::new_unchecked(subsec_nanos) };
387
388 Duration { secs, nanos: subsec_nanos }
389 }
390
391 #[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)] 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 {
crate::panicking::panic_fmt(format_args!("overflow in `Duration::from_nanos_u128`"));
};panic!("overflow in `Duration::from_nanos_u128`");
418 };
419 let subsec_nanos = (nanos % NANOS_PER_SEC) as u32;
420 let subsec_nanos = unsafe { Nanoseconds::new_unchecked(subsec_nanos) };
422
423 Duration { secs: secs as u64, nanos: subsec_nanos }
424 }
425
426 #[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 {
crate::panicking::panic_fmt(format_args!("overflow in Duration::from_weeks"));
};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 #[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 {
crate::panicking::panic_fmt(format_args!("overflow in Duration::from_days"));
};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 #[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 {
crate::panicking::panic_fmt(format_args!("overflow in Duration::from_hours"));
};panic!("overflow in Duration::from_hours");
511 }
512
513 Duration::from_secs(hours * MINS_PER_HOUR * SECS_PER_MINUTE)
514 }
515
516 #[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 {
crate::panicking::panic_fmt(format_args!("overflow in Duration::from_mins"));
};panic!("overflow in Duration::from_mins");
541 }
542
543 Duration::from_secs(mins * SECS_PER_MINUTE)
544 }
545
546 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 if true {
if !(nanos < NANOS_PER_SEC) {
crate::panicking::panic("assertion failed: nanos < NANOS_PER_SEC")
};
};debug_assert!(nanos < NANOS_PER_SEC);
769 Some(Duration::new(secs, nanos))
770 } else {
771 None
772 }
773 }
774
775 #[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 #[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 if true {
if !(nanos < NANOS_PER_SEC) {
crate::panicking::panic("assertion failed: nanos < NANOS_PER_SEC")
};
};debug_assert!(nanos < NANOS_PER_SEC);
825 Some(Duration::new(secs, nanos))
826 } else {
827 None
828 }
829 }
830
831 #[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 #[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 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 if let Some(s) = self.secs.checked_mul(rhs as u64) {
877 if let Some(secs) = s.checked_add(extra_secs) {
878 if true {
if !(nanos < NANOS_PER_SEC) {
crate::panicking::panic("assertion failed: nanos < NANOS_PER_SEC")
};
};debug_assert!(nanos < NANOS_PER_SEC);
879 return Some(Duration::new(secs, nanos));
880 }
881 }
882 None
883 }
884
885 #[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 #[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 if true {
if !(nanos < NANOS_PER_SEC) {
crate::panicking::panic("assertion failed: nanos < NANOS_PER_SEC")
};
};debug_assert!(nanos < NANOS_PER_SEC);
933 Some(Duration::new(secs, nanos))
934 } else {
935 None
936 }
937 }
938
939 #[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 #[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 #[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 #[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 #[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) => { crate::panicking::panic_fmt(format_args!("{0}", e)); }panic!("{e}"),
1051 }
1052 }
1053
1054 #[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) => { crate::panicking::panic_fmt(format_args!("{0}", e)); }panic!("{e}"),
1088 }
1089 }
1090
1091 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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("adding durations should not exceed u64::MAX")
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("subtracting durations should not be negative")
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("multiplying duration by scalar should not exceed u64::MAX")
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("divisor should not be zero")
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 = total_secs
1438 .checked_add(entry.secs)
1439 .expect("sum over duration iterator should not overflow u64::MAX");
1440 total_nanos = match total_nanos.checked_add(entry.nanos.as_inner() as u64) {
1441 Some(n) => n,
1442 None => {
1443 total_secs = total_secs
1444 .checked_add(total_nanos / NANOS_PER_SEC as u64)
1445 .expect("sum over duration iterator should not overflow u64::MAX");
1446 (total_nanos % NANOS_PER_SEC as u64) + entry.nanos.as_inner() as u64
1447 }
1448 };
1449 }
1450 total_secs = total_secs
1451 .checked_add(total_nanos / NANOS_PER_SEC as u64)
1452 .expect("sum over duration iterator should not overflow u64::MAX");
1453 total_nanos %= NANOS_PER_SEC as u64;
1454 Duration::new(total_secs, total_nanos as u32)
1455 }};
1456}
1457
1458#[stable(feature = "duration_sum", since = "1.16.0")]
1459impl Sum for Duration {
1460 fn sum<I: Iterator<Item = Duration>>(iter: I) -> Duration {
1461 {
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("sum over duration iterator should not overflow u64::MAX");
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("sum over duration iterator should not overflow u64::MAX");
(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("sum over duration iterator should not overflow u64::MAX");
total_nanos %= NANOS_PER_SEC as u64;
Duration::new(total_secs, total_nanos as u32)
}sum_durations!(iter)
1462 }
1463}
1464
1465#[stable(feature = "duration_sum", since = "1.16.0")]
1466impl<'a> Sum<&'a Duration> for Duration {
1467 fn sum<I: Iterator<Item = &'a Duration>>(iter: I) -> Duration {
1468 {
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("sum over duration iterator should not overflow u64::MAX");
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("sum over duration iterator should not overflow u64::MAX");
(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("sum over duration iterator should not overflow u64::MAX");
total_nanos %= NANOS_PER_SEC as u64;
Duration::new(total_secs, total_nanos as u32)
}sum_durations!(iter)
1469 }
1470}
1471
1472#[stable(feature = "duration_debug_impl", since = "1.27.0")]
1473impl fmt::Debug for Duration {
1474 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1475 fn fmt_decimal(
1489 f: &mut fmt::Formatter<'_>,
1490 integer_part: u64,
1491 mut fractional_part: u32,
1492 mut divisor: u32,
1493 prefix: &str,
1494 postfix: &str,
1495 ) -> fmt::Result {
1496 let mut buf = [b'0'; 9];
1501
1502 let mut pos = 0;
1504
1505 while fractional_part > 0 && pos < f.precision().unwrap_or(9) {
1508 buf[pos] = b'0' + (fractional_part / divisor) as u8;
1510
1511 fractional_part %= divisor;
1512 divisor /= 10;
1513 pos += 1;
1514 }
1515
1516 let integer_part = if fractional_part > 0 && fractional_part >= divisor * 5 {
1525 let is_tie = fractional_part == divisor * 5;
1527 let last_digit_is_odd = if pos > 0 {
1528 (buf[pos - 1] - b'0') % 2 == 1
1529 } else {
1530 (integer_part % 2) == 1
1532 };
1533
1534 if is_tie && !last_digit_is_odd {
1535 Some(integer_part)
1536 } else {
1537 let mut rev_pos = pos;
1540 let mut carry = true;
1541 while carry && rev_pos > 0 {
1542 rev_pos -= 1;
1543
1544 if buf[rev_pos] < b'9' {
1549 buf[rev_pos] += 1;
1550 carry = false;
1551 } else {
1552 buf[rev_pos] = b'0';
1553 }
1554 }
1555
1556 if carry {
1560 integer_part.checked_add(1)
1566 } else {
1567 Some(integer_part)
1568 }
1569 }
1570 } else {
1571 Some(integer_part)
1572 };
1573
1574 let end = f.precision().map(|p| crate::cmp::min(p, 9)).unwrap_or(pos);
1578
1579 let emit_without_padding = |f: &mut fmt::Formatter<'_>| {
1582 if let Some(integer_part) = integer_part {
1583 f.write_fmt(format_args!("{0}{1}", prefix, integer_part))write!(f, "{}{}", prefix, integer_part)?;
1584 } else {
1585 f.write_fmt(format_args!("{0}18446744073709551616", prefix))write!(f, "{}18446744073709551616", prefix)?;
1587 }
1588
1589 if end > 0 {
1591 let s = unsafe { crate::str::from_utf8_unchecked(&buf[..end]) };
1594
1595 let w = f.precision().unwrap_or(pos);
1597 f.write_fmt(format_args!(".{0:0<1$}", s, w))write!(f, ".{:0<width$}", s, width = w)?;
1598 }
1599
1600 f.write_fmt(format_args!("{0}", postfix))write!(f, "{}", postfix)
1601 };
1602
1603 match f.width() {
1604 None => {
1605 emit_without_padding(f)
1608 }
1609 Some(requested_w) => {
1610 let mut actual_w = prefix.len() + postfix.chars().count();
1616 if let Some(integer_part) = integer_part {
1618 if let Some(log) = integer_part.checked_ilog10() {
1619 actual_w += 1 + log as usize;
1621 } else {
1622 actual_w += 1;
1624 }
1625 } else {
1626 actual_w += 20;
1628 }
1629 if end > 0 {
1631 let frac_part_w = f.precision().unwrap_or(pos);
1632 actual_w += 1 + frac_part_w;
1633 }
1634
1635 if requested_w <= actual_w {
1636 emit_without_padding(f)
1638 } else {
1639 let default_align = fmt::Alignment::Left;
1641 let post_padding =
1642 f.padding((requested_w - actual_w) as u16, default_align)?;
1643 emit_without_padding(f)?;
1644 post_padding.write(f)
1645 }
1646 }
1647 }
1648 }
1649
1650 let prefix = if f.sign_plus() { "+" } else { "" };
1652
1653 if self.secs > 0 {
1654 fmt_decimal(f, self.secs, self.nanos.as_inner(), NANOS_PER_SEC / 10, prefix, "s")
1655 } else if self.nanos.as_inner() >= NANOS_PER_MILLI {
1656 fmt_decimal(
1657 f,
1658 (self.nanos.as_inner() / NANOS_PER_MILLI) as u64,
1659 self.nanos.as_inner() % NANOS_PER_MILLI,
1660 NANOS_PER_MILLI / 10,
1661 prefix,
1662 "ms",
1663 )
1664 } else if self.nanos.as_inner() >= NANOS_PER_MICRO {
1665 fmt_decimal(
1666 f,
1667 (self.nanos.as_inner() / NANOS_PER_MICRO) as u64,
1668 self.nanos.as_inner() % NANOS_PER_MICRO,
1669 NANOS_PER_MICRO / 10,
1670 prefix,
1671 "µs",
1672 )
1673 } else {
1674 fmt_decimal(f, self.nanos.as_inner() as u64, 0, 1, prefix, "ns")
1675 }
1676 }
1677}
1678
1679#[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) -> Self {
TryFromFloatSecsError { kind: crate::clone::Clone::clone(&self.kind) }
}
}Clone, #[automatically_derived]
#[stable(feature = "duration_checked_float", since = "1.66.0")]
impl crate::marker::StructuralPartialEq for TryFromFloatSecsError { }
#[automatically_derived]
#[stable(feature = "duration_checked_float", since = "1.66.0")]
impl crate::cmp::PartialEq for TryFromFloatSecsError {
#[inline]
fn eq(&self, other: &Self) -> 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)]
1695#[stable(feature = "duration_checked_float", since = "1.66.0")]
1696pub struct TryFromFloatSecsError {
1697 kind: TryFromFloatSecsErrorKind,
1698}
1699
1700#[stable(feature = "duration_checked_float", since = "1.66.0")]
1701impl fmt::Display for TryFromFloatSecsError {
1702 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1703 match self.kind {
1704 TryFromFloatSecsErrorKind::Negative => {
1705 "cannot convert float seconds to Duration: value is negative"
1706 }
1707 TryFromFloatSecsErrorKind::OverflowOrNan => {
1708 "cannot convert float seconds to Duration: value is either too big or NaN"
1709 }
1710 }
1711 .fmt(f)
1712 }
1713}
1714
1715#[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) -> Self {
match self {
Self::Negative => TryFromFloatSecsErrorKind::Negative,
Self::OverflowOrNan => TryFromFloatSecsErrorKind::OverflowOrNan,
}
}
}Clone, #[automatically_derived]
impl crate::marker::StructuralPartialEq for TryFromFloatSecsErrorKind { }
#[automatically_derived]
impl crate::cmp::PartialEq for TryFromFloatSecsErrorKind {
#[inline]
fn eq(&self, other: &Self) -> bool {
crate::intrinsics::discriminant_value(self) ==
crate::intrinsics::discriminant_value(other)
}
}PartialEq, #[automatically_derived]
impl crate::cmp::Eq for TryFromFloatSecsErrorKind { }Eq)]
1716enum TryFromFloatSecsErrorKind {
1717 Negative,
1719 OverflowOrNan,
1721}
1722
1723macro_rules! try_from_secs {
1724 (
1725 secs = $secs: expr,
1726 mantissa_bits = $mant_bits: literal,
1727 exponent_bits = $exp_bits: literal,
1728 offset = $offset: literal,
1729 bits_ty = $bits_ty:ty,
1730 double_ty = $double_ty:ty,
1731 ) => {{
1732 const MIN_EXP: i16 = 1 - (1i16 << $exp_bits) / 2;
1733 const MANT_MASK: $bits_ty = (1 << $mant_bits) - 1;
1734 const EXP_MASK: $bits_ty = (1 << $exp_bits) - 1;
1735
1736 if $secs < 0.0 {
1737 return Err(TryFromFloatSecsError { kind: TryFromFloatSecsErrorKind::Negative });
1738 }
1739
1740 let bits = $secs.to_bits();
1741 let mant = (bits & MANT_MASK) | (MANT_MASK + 1);
1742 let exp = ((bits >> $mant_bits) & EXP_MASK) as i16 + MIN_EXP;
1743
1744 let (secs, nanos) = if exp < -31 {
1745 (0u64, 0u32)
1747 } else if exp < 0 {
1748 let t = <$double_ty>::from(mant) << ($offset + exp);
1750 let nanos_offset = $mant_bits + $offset;
1751 let nanos_tmp = u128::from(NANOS_PER_SEC) * u128::from(t);
1752 let nanos = (nanos_tmp >> nanos_offset) as u32;
1753
1754 let rem_mask = (1 << nanos_offset) - 1;
1755 let rem_msb_mask = 1 << (nanos_offset - 1);
1756 let rem = nanos_tmp & rem_mask;
1757 let is_tie = rem == rem_msb_mask;
1758 let is_even = (nanos & 1) == 0;
1759 let rem_msb = nanos_tmp & rem_msb_mask == 0;
1760 let add_ns = !(rem_msb || (is_even && is_tie));
1761
1762 let nanos = nanos + add_ns as u32;
1765 if ($mant_bits == 23) || (nanos != NANOS_PER_SEC) { (0, nanos) } else { (1, 0) }
1766 } else if exp < $mant_bits {
1767 let secs = u64::from(mant >> ($mant_bits - exp));
1768 let t = <$double_ty>::from((mant << exp) & MANT_MASK);
1769 let nanos_offset = $mant_bits;
1770 let nanos_tmp = <$double_ty>::from(NANOS_PER_SEC) * t;
1771 let nanos = (nanos_tmp >> nanos_offset) as u32;
1772
1773 let rem_mask = (1 << nanos_offset) - 1;
1774 let rem_msb_mask = 1 << (nanos_offset - 1);
1775 let rem = nanos_tmp & rem_mask;
1776 let is_tie = rem == rem_msb_mask;
1777 let is_even = (nanos & 1) == 0;
1778 let rem_msb = nanos_tmp & rem_msb_mask == 0;
1779 let add_ns = !(rem_msb || (is_even && is_tie));
1780
1781 let nanos = nanos + add_ns as u32;
1786 if ($mant_bits == 23) || (nanos != NANOS_PER_SEC) {
1787 (secs, nanos)
1788 } else {
1789 (secs + 1, 0)
1790 }
1791 } else if exp < 64 {
1792 let secs = u64::from(mant) << (exp - $mant_bits);
1794 (secs, 0)
1795 } else {
1796 return Err(TryFromFloatSecsError { kind: TryFromFloatSecsErrorKind::OverflowOrNan });
1797 };
1798
1799 Ok(Duration::new(secs, nanos))
1800 }};
1801}
1802
1803impl Duration {
1804 #[stable(feature = "duration_checked_float", since = "1.66.0")]
1860 #[inline]
1861 pub fn try_from_secs_f32(secs: f32) -> Result<Duration, TryFromFloatSecsError> {
1862 {
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!(
1863 secs = secs,
1864 mantissa_bits = 23,
1865 exponent_bits = 8,
1866 offset = 41,
1867 bits_ty = u32,
1868 double_ty = u64,
1869 )
1870 }
1871
1872 #[stable(feature = "duration_checked_float", since = "1.66.0")]
1936 #[inline]
1937 pub fn try_from_secs_f64(secs: f64) -> Result<Duration, TryFromFloatSecsError> {
1938 {
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!(
1939 secs = secs,
1940 mantissa_bits = 52,
1941 exponent_bits = 11,
1942 offset = 44,
1943 bits_ty = u64,
1944 double_ty = u128,
1945 )
1946 }
1947}