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> {
match crate::cmp::PartialOrd::partial_cmp(&self.secs, &other.secs) {
crate::option::Option::Some(crate::cmp::Ordering::Equal) =>
crate::cmp::PartialOrd::partial_cmp(&self.nanos,
&other.nanos),
cmp => cmp,
}
}
}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")]
1017 #[must_use = "this returns the result of the operation, \
1018 without modifying the original"]
1019 #[inline]
1020 pub fn mul_f64(self, rhs: f64) -> Duration {
1021 Duration::from_secs_f64(rhs * self.as_secs_f64())
1022 }
1023
1024 #[stable(feature = "duration_float", since = "1.38.0")]
1038 #[must_use = "this returns the result of the operation, \
1039 without modifying the original"]
1040 #[inline]
1041 pub fn mul_f32(self, rhs: f32) -> Duration {
1042 Duration::from_secs_f32(rhs * self.as_secs_f32())
1043 }
1044
1045 #[stable(feature = "duration_float", since = "1.38.0")]
1059 #[must_use = "this returns the result of the operation, \
1060 without modifying the original"]
1061 #[inline]
1062 pub fn div_f64(self, rhs: f64) -> Duration {
1063 Duration::from_secs_f64(self.as_secs_f64() / rhs)
1064 }
1065
1066 #[stable(feature = "duration_float", since = "1.38.0")]
1082 #[must_use = "this returns the result of the operation, \
1083 without modifying the original"]
1084 #[inline]
1085 pub fn div_f32(self, rhs: f32) -> Duration {
1086 Duration::from_secs_f32(self.as_secs_f32() / rhs)
1087 }
1088
1089 #[stable(feature = "div_duration", since = "1.80.0")]
1100 #[must_use = "this returns the result of the operation, \
1101 without modifying the original"]
1102 #[inline]
1103 #[rustc_const_stable(feature = "duration_consts_float", since = "1.83.0")]
1104 pub const fn div_duration_f64(self, rhs: Duration) -> f64 {
1105 let self_nanos =
1106 (self.secs as f64) * (NANOS_PER_SEC as f64) + (self.nanos.as_inner() as f64);
1107 let rhs_nanos = (rhs.secs as f64) * (NANOS_PER_SEC as f64) + (rhs.nanos.as_inner() as f64);
1108 self_nanos / rhs_nanos
1109 }
1110
1111 #[stable(feature = "div_duration", since = "1.80.0")]
1122 #[must_use = "this returns the result of the operation, \
1123 without modifying the original"]
1124 #[inline]
1125 #[rustc_const_stable(feature = "duration_consts_float", since = "1.83.0")]
1126 pub const fn div_duration_f32(self, rhs: Duration) -> f32 {
1127 let self_nanos =
1128 (self.secs as f32) * (NANOS_PER_SEC as f32) + (self.nanos.as_inner() as f32);
1129 let rhs_nanos = (rhs.secs as f32) * (NANOS_PER_SEC as f32) + (rhs.nanos.as_inner() as f32);
1130 self_nanos / rhs_nanos
1131 }
1132
1133 #[unstable(feature = "duration_integer_division", issue = "149573")]
1146 #[must_use = "this returns the result of the operation, \
1147 without modifying the original"]
1148 #[inline]
1149 pub const fn div_duration_floor(self, rhs: Duration) -> u128 {
1150 self.as_nanos().div_floor(rhs.as_nanos())
1151 }
1152
1153 #[unstable(feature = "duration_integer_division", issue = "149573")]
1166 #[must_use = "this returns the result of the operation, \
1167 without modifying the original"]
1168 #[inline]
1169 pub const fn div_duration_ceil(self, rhs: Duration) -> u128 {
1170 self.as_nanos().div_ceil(rhs.as_nanos())
1171 }
1172}
1173
1174#[stable(feature = "duration", since = "1.3.0")]
1175#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
1176impl const Add for Duration {
1177 type Output = Duration;
1178
1179 #[inline]
1180 fn add(self, rhs: Duration) -> Duration {
1181 self.checked_add(rhs).expect("overflow when adding durations")
1182 }
1183}
1184
1185#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
1186#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
1187impl const AddAssign for Duration {
1188 #[inline]
1189 fn add_assign(&mut self, rhs: Duration) {
1190 *self = *self + rhs;
1191 }
1192}
1193
1194#[stable(feature = "duration", since = "1.3.0")]
1195#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
1196impl const Sub for Duration {
1197 type Output = Duration;
1198
1199 #[inline]
1200 fn sub(self, rhs: Duration) -> Duration {
1201 self.checked_sub(rhs).expect("overflow when subtracting durations")
1202 }
1203}
1204
1205#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
1206#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
1207impl const SubAssign for Duration {
1208 #[inline]
1209 fn sub_assign(&mut self, rhs: Duration) {
1210 *self = *self - rhs;
1211 }
1212}
1213
1214#[stable(feature = "duration", since = "1.3.0")]
1215#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
1216impl const Mul<u32> for Duration {
1217 type Output = Duration;
1218
1219 #[inline]
1220 fn mul(self, rhs: u32) -> Duration {
1221 self.checked_mul(rhs).expect("overflow when multiplying duration by scalar")
1222 }
1223}
1224
1225#[stable(feature = "symmetric_u32_duration_mul", since = "1.31.0")]
1226#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
1227impl const Mul<Duration> for u32 {
1228 type Output = Duration;
1229
1230 #[inline]
1231 fn mul(self, rhs: Duration) -> Duration {
1232 rhs * self
1233 }
1234}
1235
1236#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
1237#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
1238impl const MulAssign<u32> for Duration {
1239 #[inline]
1240 fn mul_assign(&mut self, rhs: u32) {
1241 *self = *self * rhs;
1242 }
1243}
1244
1245#[stable(feature = "duration", since = "1.3.0")]
1246#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
1247impl const Div<u32> for Duration {
1248 type Output = Duration;
1249
1250 #[inline]
1251 #[track_caller]
1252 fn div(self, rhs: u32) -> Duration {
1253 self.checked_div(rhs).expect("divide by zero error when dividing duration by scalar")
1254 }
1255}
1256
1257#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
1258#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
1259impl const DivAssign<u32> for Duration {
1260 #[inline]
1261 #[track_caller]
1262 fn div_assign(&mut self, rhs: u32) {
1263 *self = *self / rhs;
1264 }
1265}
1266
1267macro_rules! sum_durations {
1268 ($iter:expr) => {{
1269 let mut total_secs: u64 = 0;
1270 let mut total_nanos: u64 = 0;
1271
1272 for entry in $iter {
1273 total_secs =
1274 total_secs.checked_add(entry.secs).expect("overflow in iter::sum over durations");
1275 total_nanos = match total_nanos.checked_add(entry.nanos.as_inner() as u64) {
1276 Some(n) => n,
1277 None => {
1278 total_secs = total_secs
1279 .checked_add(total_nanos / NANOS_PER_SEC as u64)
1280 .expect("overflow in iter::sum over durations");
1281 (total_nanos % NANOS_PER_SEC as u64) + entry.nanos.as_inner() as u64
1282 }
1283 };
1284 }
1285 total_secs = total_secs
1286 .checked_add(total_nanos / NANOS_PER_SEC as u64)
1287 .expect("overflow in iter::sum over durations");
1288 total_nanos = total_nanos % NANOS_PER_SEC as u64;
1289 Duration::new(total_secs, total_nanos as u32)
1290 }};
1291}
1292
1293#[stable(feature = "duration_sum", since = "1.16.0")]
1294impl Sum for Duration {
1295 fn sum<I: Iterator<Item = Duration>>(iter: I) -> Duration {
1296 {
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)
1297 }
1298}
1299
1300#[stable(feature = "duration_sum", since = "1.16.0")]
1301impl<'a> Sum<&'a Duration> for Duration {
1302 fn sum<I: Iterator<Item = &'a Duration>>(iter: I) -> Duration {
1303 {
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)
1304 }
1305}
1306
1307#[stable(feature = "duration_debug_impl", since = "1.27.0")]
1308impl fmt::Debug for Duration {
1309 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1310 fn fmt_decimal(
1324 f: &mut fmt::Formatter<'_>,
1325 integer_part: u64,
1326 mut fractional_part: u32,
1327 mut divisor: u32,
1328 prefix: &str,
1329 postfix: &str,
1330 ) -> fmt::Result {
1331 let mut buf = [b'0'; 9];
1336
1337 let mut pos = 0;
1339
1340 while fractional_part > 0 && pos < f.precision().unwrap_or(9) {
1343 buf[pos] = b'0' + (fractional_part / divisor) as u8;
1345
1346 fractional_part %= divisor;
1347 divisor /= 10;
1348 pos += 1;
1349 }
1350
1351 let integer_part = if fractional_part > 0 && fractional_part >= divisor * 5 {
1360 let is_tie = fractional_part == divisor * 5;
1362 let last_digit_is_odd = if pos > 0 {
1363 (buf[pos - 1] - b'0') % 2 == 1
1364 } else {
1365 (integer_part % 2) == 1
1367 };
1368
1369 if is_tie && !last_digit_is_odd {
1370 Some(integer_part)
1371 } else {
1372 let mut rev_pos = pos;
1375 let mut carry = true;
1376 while carry && rev_pos > 0 {
1377 rev_pos -= 1;
1378
1379 if buf[rev_pos] < b'9' {
1384 buf[rev_pos] += 1;
1385 carry = false;
1386 } else {
1387 buf[rev_pos] = b'0';
1388 }
1389 }
1390
1391 if carry {
1395 integer_part.checked_add(1)
1401 } else {
1402 Some(integer_part)
1403 }
1404 }
1405 } else {
1406 Some(integer_part)
1407 };
1408
1409 let end = f.precision().map(|p| crate::cmp::min(p, 9)).unwrap_or(pos);
1413
1414 let emit_without_padding = |f: &mut fmt::Formatter<'_>| {
1417 if let Some(integer_part) = integer_part {
1418 f.write_fmt(format_args!("{0}{1}", prefix, integer_part))write!(f, "{}{}", prefix, integer_part)?;
1419 } else {
1420 f.write_fmt(format_args!("{0}18446744073709551616", prefix))write!(f, "{}18446744073709551616", prefix)?;
1422 }
1423
1424 if end > 0 {
1426 let s = unsafe { crate::str::from_utf8_unchecked(&buf[..end]) };
1429
1430 let w = f.precision().unwrap_or(pos);
1432 f.write_fmt(format_args!(".{0:0<1$}", s, w))write!(f, ".{:0<width$}", s, width = w)?;
1433 }
1434
1435 f.write_fmt(format_args!("{0}", postfix))write!(f, "{}", postfix)
1436 };
1437
1438 match f.width() {
1439 None => {
1440 emit_without_padding(f)
1443 }
1444 Some(requested_w) => {
1445 let mut actual_w = prefix.len() + postfix.chars().count();
1451 if let Some(integer_part) = integer_part {
1453 if let Some(log) = integer_part.checked_ilog10() {
1454 actual_w += 1 + log as usize;
1456 } else {
1457 actual_w += 1;
1459 }
1460 } else {
1461 actual_w += 20;
1463 }
1464 if end > 0 {
1466 let frac_part_w = f.precision().unwrap_or(pos);
1467 actual_w += 1 + frac_part_w;
1468 }
1469
1470 if requested_w <= actual_w {
1471 emit_without_padding(f)
1473 } else {
1474 let default_align = fmt::Alignment::Left;
1476 let post_padding =
1477 f.padding((requested_w - actual_w) as u16, default_align)?;
1478 emit_without_padding(f)?;
1479 post_padding.write(f)
1480 }
1481 }
1482 }
1483 }
1484
1485 let prefix = if f.sign_plus() { "+" } else { "" };
1487
1488 if self.secs > 0 {
1489 fmt_decimal(f, self.secs, self.nanos.as_inner(), NANOS_PER_SEC / 10, prefix, "s")
1490 } else if self.nanos.as_inner() >= NANOS_PER_MILLI {
1491 fmt_decimal(
1492 f,
1493 (self.nanos.as_inner() / NANOS_PER_MILLI) as u64,
1494 self.nanos.as_inner() % NANOS_PER_MILLI,
1495 NANOS_PER_MILLI / 10,
1496 prefix,
1497 "ms",
1498 )
1499 } else if self.nanos.as_inner() >= NANOS_PER_MICRO {
1500 fmt_decimal(
1501 f,
1502 (self.nanos.as_inner() / NANOS_PER_MICRO) as u64,
1503 self.nanos.as_inner() % NANOS_PER_MICRO,
1504 NANOS_PER_MICRO / 10,
1505 prefix,
1506 "µs",
1507 )
1508 } else {
1509 fmt_decimal(f, self.nanos.as_inner() as u64, 0, 1, prefix, "ns")
1510 }
1511 }
1512}
1513
1514#[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)]
1530#[stable(feature = "duration_checked_float", since = "1.66.0")]
1531pub struct TryFromFloatSecsError {
1532 kind: TryFromFloatSecsErrorKind,
1533}
1534
1535#[stable(feature = "duration_checked_float", since = "1.66.0")]
1536impl fmt::Display for TryFromFloatSecsError {
1537 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1538 match self.kind {
1539 TryFromFloatSecsErrorKind::Negative => {
1540 "cannot convert float seconds to Duration: value is negative"
1541 }
1542 TryFromFloatSecsErrorKind::OverflowOrNan => {
1543 "cannot convert float seconds to Duration: value is either too big or NaN"
1544 }
1545 }
1546 .fmt(f)
1547 }
1548}
1549
1550#[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)]
1551enum TryFromFloatSecsErrorKind {
1552 Negative,
1554 OverflowOrNan,
1556}
1557
1558macro_rules! try_from_secs {
1559 (
1560 secs = $secs: expr,
1561 mantissa_bits = $mant_bits: literal,
1562 exponent_bits = $exp_bits: literal,
1563 offset = $offset: literal,
1564 bits_ty = $bits_ty:ty,
1565 double_ty = $double_ty:ty,
1566 ) => {{
1567 const MIN_EXP: i16 = 1 - (1i16 << $exp_bits) / 2;
1568 const MANT_MASK: $bits_ty = (1 << $mant_bits) - 1;
1569 const EXP_MASK: $bits_ty = (1 << $exp_bits) - 1;
1570
1571 if $secs < 0.0 {
1572 return Err(TryFromFloatSecsError { kind: TryFromFloatSecsErrorKind::Negative });
1573 }
1574
1575 let bits = $secs.to_bits();
1576 let mant = (bits & MANT_MASK) | (MANT_MASK + 1);
1577 let exp = ((bits >> $mant_bits) & EXP_MASK) as i16 + MIN_EXP;
1578
1579 let (secs, nanos) = if exp < -31 {
1580 (0u64, 0u32)
1582 } else if exp < 0 {
1583 let t = <$double_ty>::from(mant) << ($offset + exp);
1585 let nanos_offset = $mant_bits + $offset;
1586 let nanos_tmp = u128::from(NANOS_PER_SEC) * u128::from(t);
1587 let nanos = (nanos_tmp >> nanos_offset) as u32;
1588
1589 let rem_mask = (1 << nanos_offset) - 1;
1590 let rem_msb_mask = 1 << (nanos_offset - 1);
1591 let rem = nanos_tmp & rem_mask;
1592 let is_tie = rem == rem_msb_mask;
1593 let is_even = (nanos & 1) == 0;
1594 let rem_msb = nanos_tmp & rem_msb_mask == 0;
1595 let add_ns = !(rem_msb || (is_even && is_tie));
1596
1597 let nanos = nanos + add_ns as u32;
1600 if ($mant_bits == 23) || (nanos != NANOS_PER_SEC) { (0, nanos) } else { (1, 0) }
1601 } else if exp < $mant_bits {
1602 let secs = u64::from(mant >> ($mant_bits - exp));
1603 let t = <$double_ty>::from((mant << exp) & MANT_MASK);
1604 let nanos_offset = $mant_bits;
1605 let nanos_tmp = <$double_ty>::from(NANOS_PER_SEC) * t;
1606 let nanos = (nanos_tmp >> nanos_offset) as u32;
1607
1608 let rem_mask = (1 << nanos_offset) - 1;
1609 let rem_msb_mask = 1 << (nanos_offset - 1);
1610 let rem = nanos_tmp & rem_mask;
1611 let is_tie = rem == rem_msb_mask;
1612 let is_even = (nanos & 1) == 0;
1613 let rem_msb = nanos_tmp & rem_msb_mask == 0;
1614 let add_ns = !(rem_msb || (is_even && is_tie));
1615
1616 let nanos = nanos + add_ns as u32;
1621 if ($mant_bits == 23) || (nanos != NANOS_PER_SEC) {
1622 (secs, nanos)
1623 } else {
1624 (secs + 1, 0)
1625 }
1626 } else if exp < 64 {
1627 let secs = u64::from(mant) << (exp - $mant_bits);
1629 (secs, 0)
1630 } else {
1631 return Err(TryFromFloatSecsError { kind: TryFromFloatSecsErrorKind::OverflowOrNan });
1632 };
1633
1634 Ok(Duration::new(secs, nanos))
1635 }};
1636}
1637
1638impl Duration {
1639 #[stable(feature = "duration_checked_float", since = "1.66.0")]
1695 #[inline]
1696 pub fn try_from_secs_f32(secs: f32) -> Result<Duration, TryFromFloatSecsError> {
1697 {
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!(
1698 secs = secs,
1699 mantissa_bits = 23,
1700 exponent_bits = 8,
1701 offset = 41,
1702 bits_ty = u32,
1703 double_ty = u64,
1704 )
1705 }
1706
1707 #[stable(feature = "duration_checked_float", since = "1.66.0")]
1771 #[inline]
1772 pub fn try_from_secs_f64(secs: f64) -> Result<Duration, TryFromFloatSecsError> {
1773 {
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!(
1774 secs = secs,
1775 mantissa_bits = 52,
1776 exponent_bits = 11,
1777 offset = 44,
1778 bits_ty = u64,
1779 double_ty = u128,
1780 )
1781 }
1782}