1use core::fmt;
14use core::ops::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign};
15use core::time::Duration;
16#[cfg(feature = "std")]
17use std::error::Error;
18
19use crate::{expect, try_opt};
20
21#[cfg(any(feature = "rkyv", feature = "rkyv-16", feature = "rkyv-32", feature = "rkyv-64"))]
22use rkyv::{Archive, Deserialize, Serialize};
23
24const NANOS_PER_MICRO: i32 = 1000;
26const NANOS_PER_MILLI: i32 = 1_000_000;
28pub(crate) const NANOS_PER_SEC: i32 = 1_000_000_000;
30const MICROS_PER_SEC: i64 = 1_000_000;
32const MILLIS_PER_SEC: i64 = 1000;
34const SECS_PER_MINUTE: i64 = 60;
36const SECS_PER_HOUR: i64 = 3600;
38const SECS_PER_DAY: i64 = 86_400;
40const SECS_PER_WEEK: i64 = 604_800;
42
43#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
53#[cfg_attr(
54 any(feature = "rkyv", feature = "rkyv-16", feature = "rkyv-32", feature = "rkyv-64"),
55 derive(Archive, Deserialize, Serialize),
56 archive(compare(PartialEq, PartialOrd)),
57 archive_attr(derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash))
58)]
59#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
60pub struct TimeDelta {
61 secs: i64,
62 nanos: i32, }
64
65pub(crate) const MIN: TimeDelta = TimeDelta {
67 secs: -i64::MAX / MILLIS_PER_SEC - 1,
68 nanos: NANOS_PER_SEC + (-i64::MAX % MILLIS_PER_SEC) as i32 * NANOS_PER_MILLI,
69};
70
71pub(crate) const MAX: TimeDelta = TimeDelta {
73 secs: i64::MAX / MILLIS_PER_SEC,
74 nanos: (i64::MAX % MILLIS_PER_SEC) as i32 * NANOS_PER_MILLI,
75};
76
77impl TimeDelta {
78 pub const fn new(secs: i64, nanos: u32) -> Option<TimeDelta> {
84 if secs < MIN.secs
85 || secs > MAX.secs
86 || nanos >= 1_000_000_000
87 || (secs == MAX.secs && nanos > MAX.nanos as u32)
88 || (secs == MIN.secs && nanos < MIN.nanos as u32)
89 {
90 return None;
91 }
92 Some(TimeDelta { secs, nanos: nanos as i32 })
93 }
94
95 #[inline]
104 #[must_use]
105 pub const fn weeks(weeks: i64) -> TimeDelta {
106 expect(TimeDelta::try_weeks(weeks), "TimeDelta::weeks out of bounds")
107 }
108
109 #[inline]
118 pub const fn try_weeks(weeks: i64) -> Option<TimeDelta> {
119 TimeDelta::try_seconds(try_opt!(weeks.checked_mul(SECS_PER_WEEK)))
120 }
121
122 #[inline]
131 #[must_use]
132 pub const fn days(days: i64) -> TimeDelta {
133 expect(TimeDelta::try_days(days), "TimeDelta::days out of bounds")
134 }
135
136 #[inline]
145 pub const fn try_days(days: i64) -> Option<TimeDelta> {
146 TimeDelta::try_seconds(try_opt!(days.checked_mul(SECS_PER_DAY)))
147 }
148
149 #[inline]
157 #[must_use]
158 pub const fn hours(hours: i64) -> TimeDelta {
159 expect(TimeDelta::try_hours(hours), "TimeDelta::hours out of bounds")
160 }
161
162 #[inline]
170 pub const fn try_hours(hours: i64) -> Option<TimeDelta> {
171 TimeDelta::try_seconds(try_opt!(hours.checked_mul(SECS_PER_HOUR)))
172 }
173
174 #[inline]
182 #[must_use]
183 pub const fn minutes(minutes: i64) -> TimeDelta {
184 expect(TimeDelta::try_minutes(minutes), "TimeDelta::minutes out of bounds")
185 }
186
187 #[inline]
195 pub const fn try_minutes(minutes: i64) -> Option<TimeDelta> {
196 TimeDelta::try_seconds(try_opt!(minutes.checked_mul(SECS_PER_MINUTE)))
197 }
198
199 #[inline]
206 #[must_use]
207 pub const fn seconds(seconds: i64) -> TimeDelta {
208 expect(TimeDelta::try_seconds(seconds), "TimeDelta::seconds out of bounds")
209 }
210
211 #[inline]
219 pub const fn try_seconds(seconds: i64) -> Option<TimeDelta> {
220 TimeDelta::new(seconds, 0)
221 }
222
223 #[inline]
230 pub const fn milliseconds(milliseconds: i64) -> TimeDelta {
231 expect(TimeDelta::try_milliseconds(milliseconds), "TimeDelta::milliseconds out of bounds")
232 }
233
234 #[inline]
241 pub const fn try_milliseconds(milliseconds: i64) -> Option<TimeDelta> {
242 if milliseconds < -i64::MAX {
245 return None;
246 }
247 let (secs, millis) = div_mod_floor_64(milliseconds, MILLIS_PER_SEC);
248 let d = TimeDelta { secs, nanos: millis as i32 * NANOS_PER_MILLI };
249 Some(d)
250 }
251
252 #[inline]
259 pub const fn microseconds(microseconds: i64) -> TimeDelta {
260 let (secs, micros) = div_mod_floor_64(microseconds, MICROS_PER_SEC);
261 let nanos = micros as i32 * NANOS_PER_MICRO;
262 TimeDelta { secs, nanos }
263 }
264
265 #[inline]
272 pub const fn nanoseconds(nanos: i64) -> TimeDelta {
273 let (secs, nanos) = div_mod_floor_64(nanos, NANOS_PER_SEC as i64);
274 TimeDelta { secs, nanos: nanos as i32 }
275 }
276
277 #[inline]
279 pub const fn num_weeks(&self) -> i64 {
280 self.num_days() / 7
281 }
282
283 #[inline]
285 pub const fn num_days(&self) -> i64 {
286 self.num_seconds() / SECS_PER_DAY
287 }
288
289 #[inline]
291 pub const fn num_hours(&self) -> i64 {
292 self.num_seconds() / SECS_PER_HOUR
293 }
294
295 #[inline]
297 pub const fn num_minutes(&self) -> i64 {
298 self.num_seconds() / SECS_PER_MINUTE
299 }
300
301 pub const fn num_seconds(&self) -> i64 {
303 if self.secs < 0 && self.nanos > 0 { self.secs + 1 } else { self.secs }
305 }
306
307 pub const fn subsec_nanos(&self) -> i32 {
311 if self.secs < 0 && self.nanos > 0 { self.nanos - NANOS_PER_SEC } else { self.nanos }
312 }
313
314 pub const fn num_milliseconds(&self) -> i64 {
316 let secs_part = self.num_seconds() * MILLIS_PER_SEC;
320 let nanos_part = self.subsec_nanos() / NANOS_PER_MILLI;
321 secs_part + nanos_part as i64
322 }
323
324 pub const fn num_microseconds(&self) -> Option<i64> {
327 let secs_part = try_opt!(self.num_seconds().checked_mul(MICROS_PER_SEC));
328 let nanos_part = self.subsec_nanos() / NANOS_PER_MICRO;
329 secs_part.checked_add(nanos_part as i64)
330 }
331
332 pub const fn num_nanoseconds(&self) -> Option<i64> {
335 let secs_part = try_opt!(self.num_seconds().checked_mul(NANOS_PER_SEC as i64));
336 let nanos_part = self.subsec_nanos();
337 secs_part.checked_add(nanos_part as i64)
338 }
339
340 #[must_use]
342 pub const fn checked_add(&self, rhs: &TimeDelta) -> Option<TimeDelta> {
343 let mut secs = self.secs + rhs.secs;
346 let mut nanos = self.nanos + rhs.nanos;
347 if nanos >= NANOS_PER_SEC {
348 nanos -= NANOS_PER_SEC;
349 secs += 1;
350 }
351 TimeDelta::new(secs, nanos as u32)
352 }
353
354 #[must_use]
356 pub const fn checked_sub(&self, rhs: &TimeDelta) -> Option<TimeDelta> {
357 let mut secs = self.secs - rhs.secs;
360 let mut nanos = self.nanos - rhs.nanos;
361 if nanos < 0 {
362 nanos += NANOS_PER_SEC;
363 secs -= 1;
364 }
365 TimeDelta::new(secs, nanos as u32)
366 }
367
368 #[must_use]
370 pub const fn checked_mul(&self, rhs: i32) -> Option<TimeDelta> {
371 let total_nanos = self.nanos as i64 * rhs as i64;
373 let (extra_secs, nanos) = div_mod_floor_64(total_nanos, NANOS_PER_SEC as i64);
374 let secs: i128 = self.secs as i128 * rhs as i128 + extra_secs as i128;
376 if secs <= i64::MIN as i128 || secs >= i64::MAX as i128 {
377 return None;
378 };
379 Some(TimeDelta { secs: secs as i64, nanos: nanos as i32 })
380 }
381
382 #[must_use]
384 pub const fn checked_div(&self, rhs: i32) -> Option<TimeDelta> {
385 if rhs == 0 {
386 return None;
387 }
388 let secs = self.secs / rhs as i64;
389 let carry = self.secs % rhs as i64;
390 let extra_nanos = carry * NANOS_PER_SEC as i64 / rhs as i64;
391 let nanos = self.nanos / rhs + extra_nanos as i32;
392
393 let (secs, nanos) = match nanos {
394 i32::MIN..=-1 => (secs - 1, nanos + NANOS_PER_SEC),
395 NANOS_PER_SEC..=i32::MAX => (secs + 1, nanos - NANOS_PER_SEC),
396 _ => (secs, nanos),
397 };
398
399 Some(TimeDelta { secs, nanos })
400 }
401
402 #[inline]
404 pub const fn abs(&self) -> TimeDelta {
405 if self.secs < 0 && self.nanos != 0 {
406 TimeDelta { secs: (self.secs + 1).abs(), nanos: NANOS_PER_SEC - self.nanos }
407 } else {
408 TimeDelta { secs: self.secs.abs(), nanos: self.nanos }
409 }
410 }
411
412 #[deprecated(since = "0.4.39", note = "Use `TimeDelta::MIN` instead")]
414 #[inline]
415 pub const fn min_value() -> TimeDelta {
416 MIN
417 }
418
419 #[deprecated(since = "0.4.39", note = "Use `TimeDelta::MAX` instead")]
421 #[inline]
422 pub const fn max_value() -> TimeDelta {
423 MAX
424 }
425
426 #[inline]
428 pub const fn zero() -> TimeDelta {
429 TimeDelta { secs: 0, nanos: 0 }
430 }
431
432 #[inline]
434 pub const fn is_zero(&self) -> bool {
435 self.secs == 0 && self.nanos == 0
436 }
437
438 pub const fn from_std(duration: Duration) -> Result<TimeDelta, OutOfRangeError> {
443 if duration.as_secs() > MAX.secs as u64 {
445 return Err(OutOfRangeError(()));
446 }
447 match TimeDelta::new(duration.as_secs() as i64, duration.subsec_nanos()) {
448 Some(d) => Ok(d),
449 None => Err(OutOfRangeError(())),
450 }
451 }
452
453 pub const fn to_std(&self) -> Result<Duration, OutOfRangeError> {
458 if self.secs < 0 {
459 return Err(OutOfRangeError(()));
460 }
461 Ok(Duration::new(self.secs as u64, self.nanos as u32))
462 }
463
464 pub(crate) const fn neg(self) -> TimeDelta {
466 let (secs_diff, nanos) = match self.nanos {
467 0 => (0, 0),
468 nanos => (1, NANOS_PER_SEC - nanos),
469 };
470 TimeDelta { secs: -self.secs - secs_diff, nanos }
471 }
472
473 pub const MIN: Self = MIN;
475
476 pub const MAX: Self = MAX;
478}
479
480impl Neg for TimeDelta {
481 type Output = TimeDelta;
482
483 #[inline]
484 fn neg(self) -> TimeDelta {
485 let (secs_diff, nanos) = match self.nanos {
486 0 => (0, 0),
487 nanos => (1, NANOS_PER_SEC - nanos),
488 };
489 TimeDelta { secs: -self.secs - secs_diff, nanos }
490 }
491}
492
493impl Add for TimeDelta {
494 type Output = TimeDelta;
495
496 fn add(self, rhs: TimeDelta) -> TimeDelta {
497 self.checked_add(&rhs).expect("`TimeDelta + TimeDelta` overflowed")
498 }
499}
500
501impl Sub for TimeDelta {
502 type Output = TimeDelta;
503
504 fn sub(self, rhs: TimeDelta) -> TimeDelta {
505 self.checked_sub(&rhs).expect("`TimeDelta - TimeDelta` overflowed")
506 }
507}
508
509impl AddAssign for TimeDelta {
510 fn add_assign(&mut self, rhs: TimeDelta) {
511 let new = self.checked_add(&rhs).expect("`TimeDelta + TimeDelta` overflowed");
512 *self = new;
513 }
514}
515
516impl SubAssign for TimeDelta {
517 fn sub_assign(&mut self, rhs: TimeDelta) {
518 let new = self.checked_sub(&rhs).expect("`TimeDelta - TimeDelta` overflowed");
519 *self = new;
520 }
521}
522
523impl Mul<i32> for TimeDelta {
524 type Output = TimeDelta;
525
526 fn mul(self, rhs: i32) -> TimeDelta {
527 self.checked_mul(rhs).expect("`TimeDelta * i32` overflowed")
528 }
529}
530
531impl Div<i32> for TimeDelta {
532 type Output = TimeDelta;
533
534 fn div(self, rhs: i32) -> TimeDelta {
535 self.checked_div(rhs).expect("`i32` is zero")
536 }
537}
538
539impl<'a> core::iter::Sum<&'a TimeDelta> for TimeDelta {
540 fn sum<I: Iterator<Item = &'a TimeDelta>>(iter: I) -> TimeDelta {
541 iter.fold(TimeDelta::zero(), |acc, x| acc + *x)
542 }
543}
544
545impl core::iter::Sum<TimeDelta> for TimeDelta {
546 fn sum<I: Iterator<Item = TimeDelta>>(iter: I) -> TimeDelta {
547 iter.fold(TimeDelta::zero(), |acc, x| acc + x)
548 }
549}
550
551impl fmt::Display for TimeDelta {
552 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
556 let (abs, sign) = if self.secs < 0 { (-*self, "-") } else { (*self, "") };
559
560 write!(f, "{}P", sign)?;
561 if abs.secs == 0 && abs.nanos == 0 {
563 return f.write_str("0D");
564 }
565
566 f.write_fmt(format_args!("T{}", abs.secs))?;
567
568 if abs.nanos > 0 {
569 let mut figures = 9usize;
571 let mut fraction_digits = abs.nanos;
572 loop {
573 let div = fraction_digits / 10;
574 let last_digit = fraction_digits % 10;
575 if last_digit != 0 {
576 break;
577 }
578 fraction_digits = div;
579 figures -= 1;
580 }
581 f.write_fmt(format_args!(".{:01$}", fraction_digits, figures))?;
582 }
583 f.write_str("S")?;
584 Ok(())
585 }
586}
587
588#[derive(Debug, Clone, Copy, PartialEq, Eq)]
595pub struct OutOfRangeError(());
596
597impl fmt::Display for OutOfRangeError {
598 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
599 write!(f, "Source duration value is out of range for the target type")
600 }
601}
602
603#[cfg(feature = "std")]
604impl Error for OutOfRangeError {
605 #[allow(deprecated)]
606 fn description(&self) -> &str {
607 "out of range error"
608 }
609}
610
611#[inline]
612const fn div_mod_floor_64(this: i64, other: i64) -> (i64, i64) {
613 (this.div_euclid(other), this.rem_euclid(other))
614}
615
616#[cfg(all(feature = "arbitrary", feature = "std"))]
617impl arbitrary::Arbitrary<'_> for TimeDelta {
618 fn arbitrary(u: &mut arbitrary::Unstructured) -> arbitrary::Result<TimeDelta> {
619 const MIN_SECS: i64 = -i64::MAX / MILLIS_PER_SEC - 1;
620 const MAX_SECS: i64 = i64::MAX / MILLIS_PER_SEC;
621
622 let secs: i64 = u.int_in_range(MIN_SECS..=MAX_SECS)?;
623 let nanos: i32 = u.int_in_range(0..=(NANOS_PER_SEC - 1))?;
624 let duration = TimeDelta { secs, nanos };
625
626 if duration < MIN || duration > MAX {
627 Err(arbitrary::Error::IncorrectFormat)
628 } else {
629 Ok(duration)
630 }
631 }
632}
633
634#[cfg(feature = "serde")]
635mod serde {
636 use super::TimeDelta;
637 use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error};
638
639 impl Serialize for TimeDelta {
640 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
641 <(i64, i32) as Serialize>::serialize(&(self.secs, self.nanos), serializer)
642 }
643 }
644
645 impl<'de> Deserialize<'de> for TimeDelta {
646 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
647 let (secs, nanos) = <(i64, i32) as Deserialize>::deserialize(deserializer)?;
648 TimeDelta::new(secs, nanos as u32).ok_or(Error::custom("TimeDelta out of bounds"))
649 }
650 }
651
652 #[cfg(test)]
653 mod tests {
654 use super::{super::MAX, TimeDelta};
655
656 #[test]
657 fn test_serde() {
658 let duration = TimeDelta::new(123, 456).unwrap();
659 assert_eq!(
660 serde_json::from_value::<TimeDelta>(serde_json::to_value(duration).unwrap())
661 .unwrap(),
662 duration
663 );
664 }
665
666 #[test]
667 #[should_panic(expected = "TimeDelta out of bounds")]
668 fn test_serde_oob_panic() {
669 let _ =
670 serde_json::from_value::<TimeDelta>(serde_json::json!([MAX.secs + 1, 0])).unwrap();
671 }
672 }
673}
674
675#[cfg(test)]
676mod tests {
677 use super::OutOfRangeError;
678 use super::{MAX, MIN, TimeDelta};
679 use crate::expect;
680 use core::time::Duration;
681
682 #[test]
683 fn test_duration() {
684 let days = |d| TimeDelta::try_days(d).unwrap();
685 let seconds = |s| TimeDelta::try_seconds(s).unwrap();
686
687 assert!(seconds(1) != TimeDelta::zero());
688 assert_eq!(seconds(1) + seconds(2), seconds(3));
689 assert_eq!(seconds(86_399) + seconds(4), days(1) + seconds(3));
690 assert_eq!(days(10) - seconds(1000), seconds(863_000));
691 assert_eq!(days(10) - seconds(1_000_000), seconds(-136_000));
692 assert_eq!(
693 days(2) + seconds(86_399) + TimeDelta::nanoseconds(1_234_567_890),
694 days(3) + TimeDelta::nanoseconds(234_567_890)
695 );
696 assert_eq!(-days(3), days(-3));
697 assert_eq!(-(days(3) + seconds(70)), days(-4) + seconds(86_400 - 70));
698
699 let mut d = TimeDelta::default();
700 d += TimeDelta::try_minutes(1).unwrap();
701 d -= seconds(30);
702 assert_eq!(d, seconds(30));
703 }
704
705 #[test]
706 fn test_duration_num_days() {
707 assert_eq!(TimeDelta::zero().num_days(), 0);
708 assert_eq!(TimeDelta::try_days(1).unwrap().num_days(), 1);
709 assert_eq!(TimeDelta::try_days(-1).unwrap().num_days(), -1);
710 assert_eq!(TimeDelta::try_seconds(86_399).unwrap().num_days(), 0);
711 assert_eq!(TimeDelta::try_seconds(86_401).unwrap().num_days(), 1);
712 assert_eq!(TimeDelta::try_seconds(-86_399).unwrap().num_days(), 0);
713 assert_eq!(TimeDelta::try_seconds(-86_401).unwrap().num_days(), -1);
714 assert_eq!(TimeDelta::try_days(i32::MAX as i64).unwrap().num_days(), i32::MAX as i64);
715 assert_eq!(TimeDelta::try_days(i32::MIN as i64).unwrap().num_days(), i32::MIN as i64);
716 }
717
718 #[test]
719 fn test_duration_num_seconds() {
720 assert_eq!(TimeDelta::zero().num_seconds(), 0);
721 assert_eq!(TimeDelta::try_seconds(1).unwrap().num_seconds(), 1);
722 assert_eq!(TimeDelta::try_seconds(-1).unwrap().num_seconds(), -1);
723 assert_eq!(TimeDelta::try_milliseconds(999).unwrap().num_seconds(), 0);
724 assert_eq!(TimeDelta::try_milliseconds(1001).unwrap().num_seconds(), 1);
725 assert_eq!(TimeDelta::try_milliseconds(-999).unwrap().num_seconds(), 0);
726 assert_eq!(TimeDelta::try_milliseconds(-1001).unwrap().num_seconds(), -1);
727 }
728
729 #[test]
730 fn test_duration_seconds_max_allowed() {
731 let duration = TimeDelta::try_seconds(i64::MAX / 1_000).unwrap();
732 assert_eq!(duration.num_seconds(), i64::MAX / 1_000);
733 assert_eq!(
734 duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
735 i64::MAX as i128 / 1_000 * 1_000_000_000
736 );
737 }
738
739 #[test]
740 fn test_duration_seconds_max_overflow() {
741 assert!(TimeDelta::try_seconds(i64::MAX / 1_000 + 1).is_none());
742 }
743
744 #[test]
745 #[should_panic(expected = "TimeDelta::seconds out of bounds")]
746 fn test_duration_seconds_max_overflow_panic() {
747 let _ = TimeDelta::seconds(i64::MAX / 1_000 + 1);
748 }
749
750 #[test]
751 fn test_duration_seconds_min_allowed() {
752 let duration = TimeDelta::try_seconds(i64::MIN / 1_000).unwrap(); assert_eq!(duration.num_seconds(), i64::MIN / 1_000); assert_eq!(
755 duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
756 -i64::MAX as i128 / 1_000 * 1_000_000_000
757 );
758 }
759
760 #[test]
761 fn test_duration_seconds_min_underflow() {
762 assert!(TimeDelta::try_seconds(-i64::MAX / 1_000 - 1).is_none());
763 }
764
765 #[test]
766 #[should_panic(expected = "TimeDelta::seconds out of bounds")]
767 fn test_duration_seconds_min_underflow_panic() {
768 let _ = TimeDelta::seconds(-i64::MAX / 1_000 - 1);
769 }
770
771 #[test]
772 fn test_duration_num_milliseconds() {
773 assert_eq!(TimeDelta::zero().num_milliseconds(), 0);
774 assert_eq!(TimeDelta::try_milliseconds(1).unwrap().num_milliseconds(), 1);
775 assert_eq!(TimeDelta::try_milliseconds(-1).unwrap().num_milliseconds(), -1);
776 assert_eq!(TimeDelta::microseconds(999).num_milliseconds(), 0);
777 assert_eq!(TimeDelta::microseconds(1001).num_milliseconds(), 1);
778 assert_eq!(TimeDelta::microseconds(-999).num_milliseconds(), 0);
779 assert_eq!(TimeDelta::microseconds(-1001).num_milliseconds(), -1);
780 }
781
782 #[test]
783 fn test_duration_milliseconds_max_allowed() {
784 let duration = TimeDelta::try_milliseconds(i64::MAX).unwrap();
787 assert_eq!(duration.num_milliseconds(), i64::MAX);
788 assert_eq!(
789 duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
790 i64::MAX as i128 * 1_000_000
791 );
792 }
793
794 #[test]
795 fn test_duration_milliseconds_max_overflow() {
796 assert!(
799 TimeDelta::try_milliseconds(i64::MAX)
800 .unwrap()
801 .checked_add(&TimeDelta::try_milliseconds(1).unwrap())
802 .is_none()
803 );
804 }
805
806 #[test]
807 fn test_duration_milliseconds_min_allowed() {
808 let duration = TimeDelta::try_milliseconds(-i64::MAX).unwrap();
812 assert_eq!(duration.num_milliseconds(), -i64::MAX);
813 assert_eq!(
814 duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
815 -i64::MAX as i128 * 1_000_000
816 );
817 }
818
819 #[test]
820 fn test_duration_milliseconds_min_underflow() {
821 assert!(
824 TimeDelta::try_milliseconds(-i64::MAX)
825 .unwrap()
826 .checked_sub(&TimeDelta::try_milliseconds(1).unwrap())
827 .is_none()
828 );
829 }
830
831 #[test]
832 #[should_panic(expected = "TimeDelta::milliseconds out of bounds")]
833 fn test_duration_milliseconds_min_underflow_panic() {
834 let _ = TimeDelta::milliseconds(i64::MIN); }
840
841 #[test]
842 fn test_duration_num_microseconds() {
843 assert_eq!(TimeDelta::zero().num_microseconds(), Some(0));
844 assert_eq!(TimeDelta::microseconds(1).num_microseconds(), Some(1));
845 assert_eq!(TimeDelta::microseconds(-1).num_microseconds(), Some(-1));
846 assert_eq!(TimeDelta::nanoseconds(999).num_microseconds(), Some(0));
847 assert_eq!(TimeDelta::nanoseconds(1001).num_microseconds(), Some(1));
848 assert_eq!(TimeDelta::nanoseconds(-999).num_microseconds(), Some(0));
849 assert_eq!(TimeDelta::nanoseconds(-1001).num_microseconds(), Some(-1));
850
851 const MICROS_PER_DAY: i64 = 86_400_000_000;
853 assert_eq!(
854 TimeDelta::try_days(i64::MAX / MICROS_PER_DAY).unwrap().num_microseconds(),
855 Some(i64::MAX / MICROS_PER_DAY * MICROS_PER_DAY)
856 );
857 assert_eq!(
858 TimeDelta::try_days(-i64::MAX / MICROS_PER_DAY).unwrap().num_microseconds(),
859 Some(-i64::MAX / MICROS_PER_DAY * MICROS_PER_DAY)
860 );
861 assert_eq!(
862 TimeDelta::try_days(i64::MAX / MICROS_PER_DAY + 1).unwrap().num_microseconds(),
863 None
864 );
865 assert_eq!(
866 TimeDelta::try_days(-i64::MAX / MICROS_PER_DAY - 1).unwrap().num_microseconds(),
867 None
868 );
869 }
870 #[test]
871 fn test_duration_microseconds_max_allowed() {
872 let duration = TimeDelta::microseconds(i64::MAX);
876 assert_eq!(duration.num_microseconds(), Some(i64::MAX));
877 assert_eq!(
878 duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
879 i64::MAX as i128 * 1_000
880 );
881 let duration = TimeDelta::try_milliseconds(i64::MAX).unwrap();
886 assert!(duration.num_microseconds().is_none());
887 assert_eq!(
888 duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
889 i64::MAX as i128 * 1_000_000
890 );
891 }
892 #[test]
893 fn test_duration_microseconds_max_overflow() {
894 let duration = TimeDelta::microseconds(i64::MAX) + TimeDelta::microseconds(1);
897 assert!(duration.num_microseconds().is_none());
898 assert_eq!(
899 duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
900 (i64::MAX as i128 + 1) * 1_000
901 );
902 assert!(
905 TimeDelta::try_milliseconds(i64::MAX)
906 .unwrap()
907 .checked_add(&TimeDelta::microseconds(1))
908 .is_none()
909 );
910 }
911 #[test]
912 fn test_duration_microseconds_min_allowed() {
913 let duration = TimeDelta::microseconds(i64::MIN);
917 assert_eq!(duration.num_microseconds(), Some(i64::MIN));
918 assert_eq!(
919 duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
920 i64::MIN as i128 * 1_000
921 );
922 let duration = TimeDelta::try_milliseconds(-i64::MAX).unwrap();
927 assert!(duration.num_microseconds().is_none());
928 assert_eq!(
929 duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
930 -i64::MAX as i128 * 1_000_000
931 );
932 }
933 #[test]
934 fn test_duration_microseconds_min_underflow() {
935 let duration = TimeDelta::microseconds(i64::MIN) - TimeDelta::microseconds(1);
938 assert!(duration.num_microseconds().is_none());
939 assert_eq!(
940 duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
941 (i64::MIN as i128 - 1) * 1_000
942 );
943 assert!(
946 TimeDelta::try_milliseconds(-i64::MAX)
947 .unwrap()
948 .checked_sub(&TimeDelta::microseconds(1))
949 .is_none()
950 );
951 }
952
953 #[test]
954 fn test_duration_num_nanoseconds() {
955 assert_eq!(TimeDelta::zero().num_nanoseconds(), Some(0));
956 assert_eq!(TimeDelta::nanoseconds(1).num_nanoseconds(), Some(1));
957 assert_eq!(TimeDelta::nanoseconds(-1).num_nanoseconds(), Some(-1));
958
959 const NANOS_PER_DAY: i64 = 86_400_000_000_000;
961 assert_eq!(
962 TimeDelta::try_days(i64::MAX / NANOS_PER_DAY).unwrap().num_nanoseconds(),
963 Some(i64::MAX / NANOS_PER_DAY * NANOS_PER_DAY)
964 );
965 assert_eq!(
966 TimeDelta::try_days(-i64::MAX / NANOS_PER_DAY).unwrap().num_nanoseconds(),
967 Some(-i64::MAX / NANOS_PER_DAY * NANOS_PER_DAY)
968 );
969 assert_eq!(
970 TimeDelta::try_days(i64::MAX / NANOS_PER_DAY + 1).unwrap().num_nanoseconds(),
971 None
972 );
973 assert_eq!(
974 TimeDelta::try_days(-i64::MAX / NANOS_PER_DAY - 1).unwrap().num_nanoseconds(),
975 None
976 );
977 }
978 #[test]
979 fn test_duration_nanoseconds_max_allowed() {
980 let duration = TimeDelta::nanoseconds(i64::MAX);
984 assert_eq!(duration.num_nanoseconds(), Some(i64::MAX));
985 assert_eq!(
986 duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
987 i64::MAX as i128
988 );
989 let duration = TimeDelta::try_milliseconds(i64::MAX).unwrap();
993 assert!(duration.num_nanoseconds().is_none());
994 assert_eq!(
995 duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
996 i64::MAX as i128 * 1_000_000
997 );
998 }
999
1000 #[test]
1001 fn test_duration_nanoseconds_max_overflow() {
1002 let duration = TimeDelta::nanoseconds(i64::MAX) + TimeDelta::nanoseconds(1);
1005 assert!(duration.num_nanoseconds().is_none());
1006 assert_eq!(
1007 duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
1008 i64::MAX as i128 + 1
1009 );
1010 assert!(
1013 TimeDelta::try_milliseconds(i64::MAX)
1014 .unwrap()
1015 .checked_add(&TimeDelta::nanoseconds(1))
1016 .is_none()
1017 );
1018 }
1019
1020 #[test]
1021 fn test_duration_nanoseconds_min_allowed() {
1022 let duration = TimeDelta::nanoseconds(i64::MIN);
1026 assert_eq!(duration.num_nanoseconds(), Some(i64::MIN));
1027 assert_eq!(
1028 duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
1029 i64::MIN as i128
1030 );
1031 let duration = TimeDelta::try_milliseconds(-i64::MAX).unwrap();
1035 assert!(duration.num_nanoseconds().is_none());
1036 assert_eq!(
1037 duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
1038 -i64::MAX as i128 * 1_000_000
1039 );
1040 }
1041
1042 #[test]
1043 fn test_duration_nanoseconds_min_underflow() {
1044 let duration = TimeDelta::nanoseconds(i64::MIN) - TimeDelta::nanoseconds(1);
1047 assert!(duration.num_nanoseconds().is_none());
1048 assert_eq!(
1049 duration.secs as i128 * 1_000_000_000 + duration.nanos as i128,
1050 i64::MIN as i128 - 1
1051 );
1052 assert!(
1055 TimeDelta::try_milliseconds(-i64::MAX)
1056 .unwrap()
1057 .checked_sub(&TimeDelta::nanoseconds(1))
1058 .is_none()
1059 );
1060 }
1061
1062 #[test]
1063 fn test_max() {
1064 assert_eq!(
1065 MAX.secs as i128 * 1_000_000_000 + MAX.nanos as i128,
1066 i64::MAX as i128 * 1_000_000
1067 );
1068 assert_eq!(MAX, TimeDelta::try_milliseconds(i64::MAX).unwrap());
1069 assert_eq!(MAX.num_milliseconds(), i64::MAX);
1070 assert_eq!(MAX.num_microseconds(), None);
1071 assert_eq!(MAX.num_nanoseconds(), None);
1072 }
1073
1074 #[test]
1075 fn test_min() {
1076 assert_eq!(
1077 MIN.secs as i128 * 1_000_000_000 + MIN.nanos as i128,
1078 -i64::MAX as i128 * 1_000_000
1079 );
1080 assert_eq!(MIN, TimeDelta::try_milliseconds(-i64::MAX).unwrap());
1081 assert_eq!(MIN.num_milliseconds(), -i64::MAX);
1082 assert_eq!(MIN.num_microseconds(), None);
1083 assert_eq!(MIN.num_nanoseconds(), None);
1084 }
1085
1086 #[test]
1087 fn test_duration_ord() {
1088 let milliseconds = |ms| TimeDelta::try_milliseconds(ms).unwrap();
1089
1090 assert!(milliseconds(1) < milliseconds(2));
1091 assert!(milliseconds(2) > milliseconds(1));
1092 assert!(milliseconds(-1) > milliseconds(-2));
1093 assert!(milliseconds(-2) < milliseconds(-1));
1094 assert!(milliseconds(-1) < milliseconds(1));
1095 assert!(milliseconds(1) > milliseconds(-1));
1096 assert!(milliseconds(0) < milliseconds(1));
1097 assert!(milliseconds(0) > milliseconds(-1));
1098 assert!(milliseconds(1_001) < milliseconds(1_002));
1099 assert!(milliseconds(-1_001) > milliseconds(-1_002));
1100 assert!(TimeDelta::nanoseconds(1_234_567_890) < TimeDelta::nanoseconds(1_234_567_891));
1101 assert!(TimeDelta::nanoseconds(-1_234_567_890) > TimeDelta::nanoseconds(-1_234_567_891));
1102 assert!(milliseconds(i64::MAX) > milliseconds(i64::MAX - 1));
1103 assert!(milliseconds(-i64::MAX) < milliseconds(-i64::MAX + 1));
1104 }
1105
1106 #[test]
1107 fn test_duration_checked_ops() {
1108 let milliseconds = |ms| TimeDelta::try_milliseconds(ms).unwrap();
1109 let seconds = |s| TimeDelta::try_seconds(s).unwrap();
1110
1111 assert_eq!(
1112 milliseconds(i64::MAX).checked_add(&milliseconds(0)),
1113 Some(milliseconds(i64::MAX))
1114 );
1115 assert_eq!(
1116 milliseconds(i64::MAX - 1).checked_add(&TimeDelta::microseconds(999)),
1117 Some(milliseconds(i64::MAX - 2) + TimeDelta::microseconds(1999))
1118 );
1119 assert!(milliseconds(i64::MAX).checked_add(&TimeDelta::microseconds(1000)).is_none());
1120 assert!(milliseconds(i64::MAX).checked_add(&TimeDelta::nanoseconds(1)).is_none());
1121
1122 assert_eq!(
1123 milliseconds(-i64::MAX).checked_sub(&milliseconds(0)),
1124 Some(milliseconds(-i64::MAX))
1125 );
1126 assert_eq!(
1127 milliseconds(-i64::MAX + 1).checked_sub(&TimeDelta::microseconds(999)),
1128 Some(milliseconds(-i64::MAX + 2) - TimeDelta::microseconds(1999))
1129 );
1130 assert!(milliseconds(-i64::MAX).checked_sub(&milliseconds(1)).is_none());
1131 assert!(milliseconds(-i64::MAX).checked_sub(&TimeDelta::nanoseconds(1)).is_none());
1132
1133 assert!(seconds(i64::MAX / 1000).checked_mul(2000).is_none());
1134 assert!(seconds(i64::MIN / 1000).checked_mul(2000).is_none());
1135 assert!(seconds(1).checked_div(0).is_none());
1136 }
1137
1138 #[test]
1139 fn test_duration_abs() {
1140 let milliseconds = |ms| TimeDelta::try_milliseconds(ms).unwrap();
1141
1142 assert_eq!(milliseconds(1300).abs(), milliseconds(1300));
1143 assert_eq!(milliseconds(1000).abs(), milliseconds(1000));
1144 assert_eq!(milliseconds(300).abs(), milliseconds(300));
1145 assert_eq!(milliseconds(0).abs(), milliseconds(0));
1146 assert_eq!(milliseconds(-300).abs(), milliseconds(300));
1147 assert_eq!(milliseconds(-700).abs(), milliseconds(700));
1148 assert_eq!(milliseconds(-1000).abs(), milliseconds(1000));
1149 assert_eq!(milliseconds(-1300).abs(), milliseconds(1300));
1150 assert_eq!(milliseconds(-1700).abs(), milliseconds(1700));
1151 assert_eq!(milliseconds(-i64::MAX).abs(), milliseconds(i64::MAX));
1152 }
1153
1154 #[test]
1155 #[allow(clippy::erasing_op)]
1156 fn test_duration_mul() {
1157 assert_eq!(TimeDelta::zero() * i32::MAX, TimeDelta::zero());
1158 assert_eq!(TimeDelta::zero() * i32::MIN, TimeDelta::zero());
1159 assert_eq!(TimeDelta::nanoseconds(1) * 0, TimeDelta::zero());
1160 assert_eq!(TimeDelta::nanoseconds(1) * 1, TimeDelta::nanoseconds(1));
1161 assert_eq!(TimeDelta::nanoseconds(1) * 1_000_000_000, TimeDelta::try_seconds(1).unwrap());
1162 assert_eq!(TimeDelta::nanoseconds(1) * -1_000_000_000, -TimeDelta::try_seconds(1).unwrap());
1163 assert_eq!(-TimeDelta::nanoseconds(1) * 1_000_000_000, -TimeDelta::try_seconds(1).unwrap());
1164 assert_eq!(
1165 TimeDelta::nanoseconds(30) * 333_333_333,
1166 TimeDelta::try_seconds(10).unwrap() - TimeDelta::nanoseconds(10)
1167 );
1168 assert_eq!(
1169 (TimeDelta::nanoseconds(1)
1170 + TimeDelta::try_seconds(1).unwrap()
1171 + TimeDelta::try_days(1).unwrap())
1172 * 3,
1173 TimeDelta::nanoseconds(3)
1174 + TimeDelta::try_seconds(3).unwrap()
1175 + TimeDelta::try_days(3).unwrap()
1176 );
1177 assert_eq!(
1178 TimeDelta::try_milliseconds(1500).unwrap() * -2,
1179 TimeDelta::try_seconds(-3).unwrap()
1180 );
1181 assert_eq!(
1182 TimeDelta::try_milliseconds(-1500).unwrap() * 2,
1183 TimeDelta::try_seconds(-3).unwrap()
1184 );
1185 }
1186
1187 #[test]
1188 fn test_duration_div() {
1189 assert_eq!(TimeDelta::zero() / i32::MAX, TimeDelta::zero());
1190 assert_eq!(TimeDelta::zero() / i32::MIN, TimeDelta::zero());
1191 assert_eq!(TimeDelta::nanoseconds(123_456_789) / 1, TimeDelta::nanoseconds(123_456_789));
1192 assert_eq!(TimeDelta::nanoseconds(123_456_789) / -1, -TimeDelta::nanoseconds(123_456_789));
1193 assert_eq!(-TimeDelta::nanoseconds(123_456_789) / -1, TimeDelta::nanoseconds(123_456_789));
1194 assert_eq!(-TimeDelta::nanoseconds(123_456_789) / 1, -TimeDelta::nanoseconds(123_456_789));
1195 assert_eq!(TimeDelta::try_seconds(1).unwrap() / 3, TimeDelta::nanoseconds(333_333_333));
1196 assert_eq!(TimeDelta::try_seconds(4).unwrap() / 3, TimeDelta::nanoseconds(1_333_333_333));
1197 assert_eq!(
1198 TimeDelta::try_seconds(-1).unwrap() / 2,
1199 TimeDelta::try_milliseconds(-500).unwrap()
1200 );
1201 assert_eq!(
1202 TimeDelta::try_seconds(1).unwrap() / -2,
1203 TimeDelta::try_milliseconds(-500).unwrap()
1204 );
1205 assert_eq!(
1206 TimeDelta::try_seconds(-1).unwrap() / -2,
1207 TimeDelta::try_milliseconds(500).unwrap()
1208 );
1209 assert_eq!(TimeDelta::try_seconds(-4).unwrap() / 3, TimeDelta::nanoseconds(-1_333_333_333));
1210 assert_eq!(TimeDelta::try_seconds(-4).unwrap() / -3, TimeDelta::nanoseconds(1_333_333_333));
1211 }
1212
1213 #[test]
1214 fn test_duration_sum() {
1215 let duration_list_1 = [TimeDelta::zero(), TimeDelta::try_seconds(1).unwrap()];
1216 let sum_1: TimeDelta = duration_list_1.iter().sum();
1217 assert_eq!(sum_1, TimeDelta::try_seconds(1).unwrap());
1218
1219 let duration_list_2 = [
1220 TimeDelta::zero(),
1221 TimeDelta::try_seconds(1).unwrap(),
1222 TimeDelta::try_seconds(6).unwrap(),
1223 TimeDelta::try_seconds(10).unwrap(),
1224 ];
1225 let sum_2: TimeDelta = duration_list_2.iter().sum();
1226 assert_eq!(sum_2, TimeDelta::try_seconds(17).unwrap());
1227
1228 let duration_arr = [
1229 TimeDelta::zero(),
1230 TimeDelta::try_seconds(1).unwrap(),
1231 TimeDelta::try_seconds(6).unwrap(),
1232 TimeDelta::try_seconds(10).unwrap(),
1233 ];
1234 let sum_3: TimeDelta = duration_arr.into_iter().sum();
1235 assert_eq!(sum_3, TimeDelta::try_seconds(17).unwrap());
1236 }
1237
1238 #[test]
1239 fn test_duration_fmt() {
1240 assert_eq!(TimeDelta::zero().to_string(), "P0D");
1241 assert_eq!(TimeDelta::try_days(42).unwrap().to_string(), "PT3628800S");
1242 assert_eq!(TimeDelta::try_days(-42).unwrap().to_string(), "-PT3628800S");
1243 assert_eq!(TimeDelta::try_seconds(42).unwrap().to_string(), "PT42S");
1244 assert_eq!(TimeDelta::try_milliseconds(42).unwrap().to_string(), "PT0.042S");
1245 assert_eq!(TimeDelta::microseconds(42).to_string(), "PT0.000042S");
1246 assert_eq!(TimeDelta::nanoseconds(42).to_string(), "PT0.000000042S");
1247 assert_eq!(
1248 (TimeDelta::try_days(7).unwrap() + TimeDelta::try_milliseconds(6543).unwrap())
1249 .to_string(),
1250 "PT604806.543S"
1251 );
1252 assert_eq!(TimeDelta::try_seconds(-86_401).unwrap().to_string(), "-PT86401S");
1253 assert_eq!(TimeDelta::nanoseconds(-1).to_string(), "-PT0.000000001S");
1254
1255 assert_eq!(
1257 format!(
1258 "{:30}",
1259 TimeDelta::try_days(1).unwrap() + TimeDelta::try_milliseconds(2345).unwrap()
1260 ),
1261 "PT86402.345S"
1262 );
1263 }
1264
1265 #[test]
1266 fn test_to_std() {
1267 assert_eq!(TimeDelta::try_seconds(1).unwrap().to_std(), Ok(Duration::new(1, 0)));
1268 assert_eq!(TimeDelta::try_seconds(86_401).unwrap().to_std(), Ok(Duration::new(86_401, 0)));
1269 assert_eq!(
1270 TimeDelta::try_milliseconds(123).unwrap().to_std(),
1271 Ok(Duration::new(0, 123_000_000))
1272 );
1273 assert_eq!(
1274 TimeDelta::try_milliseconds(123_765).unwrap().to_std(),
1275 Ok(Duration::new(123, 765_000_000))
1276 );
1277 assert_eq!(TimeDelta::nanoseconds(777).to_std(), Ok(Duration::new(0, 777)));
1278 assert_eq!(MAX.to_std(), Ok(Duration::new(9_223_372_036_854_775, 807_000_000)));
1279 assert_eq!(TimeDelta::try_seconds(-1).unwrap().to_std(), Err(OutOfRangeError(())));
1280 assert_eq!(TimeDelta::try_milliseconds(-1).unwrap().to_std(), Err(OutOfRangeError(())));
1281 }
1282
1283 #[test]
1284 fn test_from_std() {
1285 assert_eq!(
1286 Ok(TimeDelta::try_seconds(1).unwrap()),
1287 TimeDelta::from_std(Duration::new(1, 0))
1288 );
1289 assert_eq!(
1290 Ok(TimeDelta::try_seconds(86_401).unwrap()),
1291 TimeDelta::from_std(Duration::new(86_401, 0))
1292 );
1293 assert_eq!(
1294 Ok(TimeDelta::try_milliseconds(123).unwrap()),
1295 TimeDelta::from_std(Duration::new(0, 123_000_000))
1296 );
1297 assert_eq!(
1298 Ok(TimeDelta::try_milliseconds(123_765).unwrap()),
1299 TimeDelta::from_std(Duration::new(123, 765_000_000))
1300 );
1301 assert_eq!(Ok(TimeDelta::nanoseconds(777)), TimeDelta::from_std(Duration::new(0, 777)));
1302 assert_eq!(Ok(MAX), TimeDelta::from_std(Duration::new(9_223_372_036_854_775, 807_000_000)));
1303 assert_eq!(
1304 TimeDelta::from_std(Duration::new(9_223_372_036_854_776, 0)),
1305 Err(OutOfRangeError(()))
1306 );
1307 assert_eq!(
1308 TimeDelta::from_std(Duration::new(9_223_372_036_854_775, 807_000_001)),
1309 Err(OutOfRangeError(()))
1310 );
1311 }
1312
1313 #[test]
1314 fn test_duration_const() {
1315 const ONE_WEEK: TimeDelta = expect(TimeDelta::try_weeks(1), "");
1316 const ONE_DAY: TimeDelta = expect(TimeDelta::try_days(1), "");
1317 const ONE_HOUR: TimeDelta = expect(TimeDelta::try_hours(1), "");
1318 const ONE_MINUTE: TimeDelta = expect(TimeDelta::try_minutes(1), "");
1319 const ONE_SECOND: TimeDelta = expect(TimeDelta::try_seconds(1), "");
1320 const ONE_MILLI: TimeDelta = expect(TimeDelta::try_milliseconds(1), "");
1321 const ONE_MICRO: TimeDelta = TimeDelta::microseconds(1);
1322 const ONE_NANO: TimeDelta = TimeDelta::nanoseconds(1);
1323 let combo: TimeDelta = ONE_WEEK
1324 + ONE_DAY
1325 + ONE_HOUR
1326 + ONE_MINUTE
1327 + ONE_SECOND
1328 + ONE_MILLI
1329 + ONE_MICRO
1330 + ONE_NANO;
1331
1332 assert!(ONE_WEEK != TimeDelta::zero());
1333 assert!(ONE_DAY != TimeDelta::zero());
1334 assert!(ONE_HOUR != TimeDelta::zero());
1335 assert!(ONE_MINUTE != TimeDelta::zero());
1336 assert!(ONE_SECOND != TimeDelta::zero());
1337 assert!(ONE_MILLI != TimeDelta::zero());
1338 assert!(ONE_MICRO != TimeDelta::zero());
1339 assert!(ONE_NANO != TimeDelta::zero());
1340 assert_eq!(
1341 combo,
1342 TimeDelta::try_seconds(86400 * 7 + 86400 + 3600 + 60 + 1).unwrap()
1343 + TimeDelta::nanoseconds(1 + 1_000 + 1_000_000)
1344 );
1345 }
1346
1347 #[test]
1348 #[cfg(feature = "rkyv-validation")]
1349 fn test_rkyv_validation() {
1350 let duration = TimeDelta::try_seconds(1).unwrap();
1351 let bytes = rkyv::to_bytes::<_, 16>(&duration).unwrap();
1352 assert_eq!(rkyv::from_bytes::<TimeDelta>(&bytes).unwrap(), duration);
1353 }
1354}