1use core::ops::{Add, AddAssign, Sub, SubAssign};
8
9use time::OffsetDateTime;
10
11use super::{FILE_TIMES_PER_SEC, FileTime};
12
13impl FileTime {
14 #[must_use]
36 #[inline]
37 pub fn checked_add(self, rhs: core::time::Duration) -> Option<Self> {
38 let duration = u64::try_from(rhs.as_nanos() / 100).ok()?;
39 self.to_raw().checked_add(duration).map(Self::new)
40 }
41
42 #[must_use]
68 #[inline]
69 pub fn checked_sub(self, rhs: core::time::Duration) -> Option<Self> {
70 let duration = u64::try_from(rhs.as_nanos() / 100).ok()?;
71 self.to_raw().checked_sub(duration).map(Self::new)
72 }
73
74 #[must_use]
99 #[inline]
100 pub fn saturating_add(self, rhs: core::time::Duration) -> Self {
101 self.checked_add(rhs).unwrap_or(Self::MAX)
102 }
103
104 #[must_use]
130 #[inline]
131 pub fn saturating_sub(self, rhs: core::time::Duration) -> Self {
132 self.checked_sub(rhs).unwrap_or_default()
133 }
134}
135
136impl Add<core::time::Duration> for FileTime {
137 type Output = Self;
138
139 #[inline]
140 fn add(self, rhs: core::time::Duration) -> Self::Output {
141 self.checked_add(rhs)
142 .expect("overflow when adding duration to date and time")
143 }
144}
145
146impl Add<time::Duration> for FileTime {
147 type Output = Self;
148
149 #[inline]
150 fn add(self, rhs: time::Duration) -> Self::Output {
151 if rhs.is_positive() {
152 self + rhs.unsigned_abs()
153 } else {
154 self - rhs.unsigned_abs()
155 }
156 }
157}
158
159#[cfg(feature = "chrono")]
160impl Add<chrono::TimeDelta> for FileTime {
161 type Output = Self;
162
163 #[inline]
164 fn add(self, rhs: chrono::TimeDelta) -> Self::Output {
165 use chrono::TimeDelta;
166
167 if rhs > TimeDelta::zero() {
168 self + rhs.abs().to_std().expect("duration is less than zero")
169 } else {
170 self - rhs.abs().to_std().expect("duration is less than zero")
171 }
172 }
173}
174
175impl AddAssign<core::time::Duration> for FileTime {
176 #[inline]
177 fn add_assign(&mut self, rhs: core::time::Duration) {
178 *self = *self + rhs;
179 }
180}
181
182impl AddAssign<time::Duration> for FileTime {
183 #[inline]
184 fn add_assign(&mut self, rhs: time::Duration) {
185 *self = *self + rhs;
186 }
187}
188
189#[cfg(feature = "chrono")]
190impl AddAssign<chrono::TimeDelta> for FileTime {
191 #[inline]
192 fn add_assign(&mut self, rhs: chrono::TimeDelta) {
193 *self = *self + rhs;
194 }
195}
196
197impl Sub for FileTime {
198 type Output = core::time::Duration;
199
200 #[inline]
201 fn sub(self, rhs: Self) -> Self::Output {
202 let duration = self.to_raw() - rhs.to_raw();
203 Self::Output::new(
204 duration / FILE_TIMES_PER_SEC,
205 u32::try_from((duration % FILE_TIMES_PER_SEC) * 100)
206 .expect("the number of nanoseconds should be in the range of `u32`"),
207 )
208 }
209}
210
211impl Sub<core::time::Duration> for FileTime {
212 type Output = Self;
213
214 #[inline]
215 fn sub(self, rhs: core::time::Duration) -> Self::Output {
216 self.checked_sub(rhs)
217 .expect("overflow when subtracting duration from date and time")
218 }
219}
220
221impl Sub<time::Duration> for FileTime {
222 type Output = Self;
223
224 #[inline]
225 fn sub(self, rhs: time::Duration) -> Self::Output {
226 if rhs.is_positive() {
227 self - rhs.unsigned_abs()
228 } else {
229 self + rhs.unsigned_abs()
230 }
231 }
232}
233
234#[cfg(feature = "chrono")]
235impl Sub<chrono::TimeDelta> for FileTime {
236 type Output = Self;
237
238 #[inline]
239 fn sub(self, rhs: chrono::TimeDelta) -> Self::Output {
240 use chrono::TimeDelta;
241
242 if rhs > TimeDelta::zero() {
243 self - rhs.abs().to_std().expect("duration is less than zero")
244 } else {
245 self + rhs.abs().to_std().expect("duration is less than zero")
246 }
247 }
248}
249
250#[cfg(feature = "std")]
251impl Sub<FileTime> for std::time::SystemTime {
252 type Output = std::time::Duration;
253
254 #[inline]
255 fn sub(self, rhs: FileTime) -> Self::Output {
256 self.duration_since(rhs.into())
257 .expect("RHS provided is later than LHS")
258 }
259}
260
261#[cfg(feature = "std")]
262impl Sub<std::time::SystemTime> for FileTime {
263 type Output = std::time::Duration;
264
265 #[inline]
266 fn sub(self, rhs: std::time::SystemTime) -> Self::Output {
267 use std::time::SystemTime;
268
269 SystemTime::from(self)
270 .duration_since(rhs)
271 .expect("RHS provided is later than LHS")
272 }
273}
274
275impl Sub<FileTime> for OffsetDateTime {
276 type Output = time::Duration;
277
278 #[inline]
279 fn sub(self, rhs: FileTime) -> Self::Output {
280 self - Self::try_from(rhs).expect("RHS is out of range for `OffsetDateTime`")
281 }
282}
283
284impl Sub<OffsetDateTime> for FileTime {
285 type Output = time::Duration;
286
287 #[inline]
288 fn sub(self, rhs: OffsetDateTime) -> Self::Output {
289 OffsetDateTime::try_from(self).expect("LHS is out of range for `OffsetDateTime`") - rhs
290 }
291}
292
293#[cfg(feature = "chrono")]
294impl Sub<FileTime> for chrono::DateTime<chrono::Utc> {
295 type Output = chrono::TimeDelta;
296
297 #[inline]
298 fn sub(self, rhs: FileTime) -> Self::Output {
299 self - Self::from(rhs)
300 }
301}
302
303#[cfg(feature = "chrono")]
304impl Sub<chrono::DateTime<chrono::Utc>> for FileTime {
305 type Output = chrono::TimeDelta;
306
307 #[inline]
308 fn sub(self, rhs: chrono::DateTime<chrono::Utc>) -> Self::Output {
309 use chrono::{DateTime, Utc};
310
311 DateTime::<Utc>::from(self) - rhs
312 }
313}
314
315impl SubAssign<core::time::Duration> for FileTime {
316 #[inline]
317 fn sub_assign(&mut self, rhs: core::time::Duration) {
318 *self = *self - rhs;
319 }
320}
321
322impl SubAssign<time::Duration> for FileTime {
323 #[inline]
324 fn sub_assign(&mut self, rhs: time::Duration) {
325 *self = *self - rhs;
326 }
327}
328
329#[cfg(feature = "chrono")]
330impl SubAssign<chrono::TimeDelta> for FileTime {
331 #[inline]
332 fn sub_assign(&mut self, rhs: chrono::TimeDelta) {
333 *self = *self - rhs;
334 }
335}
336
337#[cfg(test)]
338mod tests {
339 use time::macros::datetime;
340
341 use super::*;
342
343 #[test]
344 fn checked_add() {
345 use core::time::Duration;
346
347 assert_eq!(
348 FileTime::NT_TIME_EPOCH.checked_add(Duration::ZERO),
349 Some(FileTime::NT_TIME_EPOCH)
350 );
351 assert_eq!(
352 FileTime::NT_TIME_EPOCH.checked_add(Duration::from_nanos(1)),
353 Some(FileTime::NT_TIME_EPOCH)
354 );
355 assert_eq!(
356 FileTime::NT_TIME_EPOCH.checked_add(Duration::from_nanos(99)),
357 Some(FileTime::NT_TIME_EPOCH)
358 );
359 assert_eq!(
360 FileTime::NT_TIME_EPOCH.checked_add(Duration::from_nanos(100)),
361 Some(FileTime::new(1))
362 );
363
364 assert_eq!(
365 FileTime::MAX.checked_add(Duration::ZERO),
366 Some(FileTime::MAX)
367 );
368 assert_eq!(
369 FileTime::MAX.checked_add(Duration::from_nanos(1)),
370 Some(FileTime::MAX)
371 );
372 assert_eq!(
373 FileTime::MAX.checked_add(Duration::from_nanos(99)),
374 Some(FileTime::MAX)
375 );
376 assert_eq!(FileTime::MAX.checked_add(Duration::from_nanos(100)), None);
377 }
378
379 #[cfg(feature = "std")]
380 #[test_strategy::proptest]
381 fn checked_add_roundtrip(dur: std::time::Duration) {
382 use std::time::Duration;
383
384 use proptest::prop_assert;
385
386 if dur <= Duration::new(1_844_674_407_370, 955_161_500) {
387 prop_assert!(FileTime::NT_TIME_EPOCH.checked_add(dur).is_some());
388 } else {
389 prop_assert!(FileTime::NT_TIME_EPOCH.checked_add(dur).is_none());
390 }
391 }
392
393 #[test]
394 fn checked_sub() {
395 use core::time::Duration;
396
397 assert_eq!(
398 FileTime::MAX.checked_sub(Duration::ZERO),
399 Some(FileTime::MAX)
400 );
401 assert_eq!(
402 FileTime::MAX.checked_sub(Duration::from_nanos(1)),
403 Some(FileTime::MAX)
404 );
405 assert_eq!(
406 FileTime::MAX.checked_sub(Duration::from_nanos(99)),
407 Some(FileTime::MAX)
408 );
409 assert_eq!(
410 FileTime::MAX.checked_sub(Duration::from_nanos(100)),
411 Some(FileTime::new(u64::MAX - 1))
412 );
413
414 assert_eq!(
415 FileTime::NT_TIME_EPOCH.checked_sub(Duration::ZERO),
416 Some(FileTime::NT_TIME_EPOCH)
417 );
418 assert_eq!(
419 FileTime::NT_TIME_EPOCH.checked_sub(Duration::from_nanos(1)),
420 Some(FileTime::NT_TIME_EPOCH)
421 );
422 assert_eq!(
423 FileTime::NT_TIME_EPOCH.checked_sub(Duration::from_nanos(99)),
424 Some(FileTime::NT_TIME_EPOCH)
425 );
426 assert_eq!(
427 FileTime::NT_TIME_EPOCH.checked_sub(Duration::from_nanos(100)),
428 None
429 );
430 }
431
432 #[cfg(feature = "std")]
433 #[test_strategy::proptest]
434 fn checked_sub_roundtrip(dur: std::time::Duration) {
435 use std::time::Duration;
436
437 use proptest::prop_assert;
438
439 if dur <= Duration::new(1_844_674_407_370, 955_161_500) {
440 prop_assert!(FileTime::MAX.checked_add(dur).is_some());
441 } else {
442 prop_assert!(FileTime::MAX.checked_add(dur).is_none());
443 }
444 }
445
446 #[test]
447 fn saturating_add() {
448 use core::time::Duration;
449
450 assert_eq!(
451 FileTime::NT_TIME_EPOCH.saturating_add(Duration::ZERO),
452 FileTime::NT_TIME_EPOCH
453 );
454 assert_eq!(
455 FileTime::NT_TIME_EPOCH.saturating_add(Duration::from_nanos(1)),
456 FileTime::NT_TIME_EPOCH
457 );
458 assert_eq!(
459 FileTime::NT_TIME_EPOCH.saturating_add(Duration::from_nanos(99)),
460 FileTime::NT_TIME_EPOCH
461 );
462 assert_eq!(
463 FileTime::NT_TIME_EPOCH.saturating_add(Duration::from_nanos(100)),
464 FileTime::new(1)
465 );
466
467 assert_eq!(FileTime::MAX.saturating_add(Duration::ZERO), FileTime::MAX);
468 assert_eq!(
469 FileTime::MAX.saturating_add(Duration::from_nanos(1)),
470 FileTime::MAX
471 );
472 assert_eq!(
473 FileTime::MAX.saturating_add(Duration::from_nanos(99)),
474 FileTime::MAX
475 );
476 assert_eq!(
477 FileTime::MAX.saturating_add(Duration::from_nanos(100)),
478 FileTime::MAX
479 );
480 }
481
482 #[cfg(feature = "std")]
483 #[test_strategy::proptest]
484 fn saturating_add_roundtrip(dur: std::time::Duration) {
485 use std::time::Duration;
486
487 use proptest::{prop_assert_eq, prop_assert_ne};
488
489 if dur <= Duration::new(1_844_674_407_370, 955_161_400) {
490 prop_assert_ne!(FileTime::NT_TIME_EPOCH.saturating_add(dur), FileTime::MAX);
491 } else {
492 prop_assert_eq!(FileTime::NT_TIME_EPOCH.saturating_add(dur), FileTime::MAX);
493 }
494 }
495
496 #[test]
497 fn saturating_sub() {
498 use core::time::Duration;
499
500 assert_eq!(FileTime::MAX.saturating_sub(Duration::ZERO), FileTime::MAX);
501 assert_eq!(
502 FileTime::MAX.saturating_sub(Duration::from_nanos(1)),
503 FileTime::MAX
504 );
505 assert_eq!(
506 FileTime::MAX.saturating_sub(Duration::from_nanos(99)),
507 FileTime::MAX
508 );
509 assert_eq!(
510 FileTime::MAX.saturating_sub(Duration::from_nanos(100)),
511 FileTime::new(u64::MAX - 1)
512 );
513
514 assert_eq!(
515 FileTime::NT_TIME_EPOCH.saturating_sub(Duration::ZERO),
516 FileTime::NT_TIME_EPOCH
517 );
518 assert_eq!(
519 FileTime::NT_TIME_EPOCH.saturating_sub(Duration::from_nanos(1)),
520 FileTime::NT_TIME_EPOCH
521 );
522 assert_eq!(
523 FileTime::NT_TIME_EPOCH.saturating_sub(Duration::from_nanos(99)),
524 FileTime::NT_TIME_EPOCH
525 );
526 assert_eq!(
527 FileTime::NT_TIME_EPOCH.saturating_sub(Duration::from_nanos(100)),
528 FileTime::NT_TIME_EPOCH
529 );
530 }
531
532 #[cfg(feature = "std")]
533 #[test_strategy::proptest]
534 fn saturating_sub_roundtrip(dur: std::time::Duration) {
535 use std::time::Duration;
536
537 use proptest::{prop_assert_eq, prop_assert_ne};
538
539 if dur <= Duration::new(1_844_674_407_370, 955_161_400) {
540 prop_assert_ne!(FileTime::MAX.saturating_sub(dur), FileTime::NT_TIME_EPOCH);
541 } else {
542 prop_assert_eq!(FileTime::MAX.saturating_sub(dur), FileTime::NT_TIME_EPOCH);
543 }
544 }
545
546 #[test]
547 fn add_std_duration() {
548 use core::time::Duration;
549
550 assert_eq!(
551 FileTime::NT_TIME_EPOCH + Duration::ZERO,
552 FileTime::NT_TIME_EPOCH
553 );
554 assert_eq!(
555 FileTime::NT_TIME_EPOCH + Duration::from_nanos(1),
556 FileTime::NT_TIME_EPOCH
557 );
558 assert_eq!(
559 FileTime::NT_TIME_EPOCH + Duration::from_nanos(99),
560 FileTime::NT_TIME_EPOCH
561 );
562 assert_eq!(
563 FileTime::NT_TIME_EPOCH + Duration::from_nanos(100),
564 FileTime::new(1)
565 );
566
567 assert_eq!(FileTime::MAX + Duration::ZERO, FileTime::MAX);
568 assert_eq!(FileTime::MAX + Duration::from_nanos(1), FileTime::MAX);
569 assert_eq!(FileTime::MAX + Duration::from_nanos(99), FileTime::MAX);
570 }
571
572 #[test]
573 #[should_panic(expected = "overflow when adding duration to date and time")]
574 fn add_std_duration_with_overflow() {
575 use core::time::Duration;
576
577 let _ = FileTime::MAX + Duration::from_nanos(100);
578 }
579
580 #[test]
581 fn add_positive_time_duration() {
582 use time::Duration;
583
584 assert_eq!(
585 FileTime::NT_TIME_EPOCH + Duration::ZERO,
586 FileTime::NT_TIME_EPOCH
587 );
588 assert_eq!(
589 FileTime::NT_TIME_EPOCH + Duration::NANOSECOND,
590 FileTime::NT_TIME_EPOCH
591 );
592 assert_eq!(
593 FileTime::NT_TIME_EPOCH + Duration::nanoseconds(99),
594 FileTime::NT_TIME_EPOCH
595 );
596 assert_eq!(
597 FileTime::NT_TIME_EPOCH + Duration::nanoseconds(100),
598 FileTime::new(1)
599 );
600
601 assert_eq!(FileTime::MAX + Duration::ZERO, FileTime::MAX);
602 assert_eq!(FileTime::MAX + Duration::NANOSECOND, FileTime::MAX);
603 assert_eq!(FileTime::MAX + Duration::nanoseconds(99), FileTime::MAX);
604 }
605
606 #[test]
607 #[should_panic(expected = "overflow when adding duration to date and time")]
608 fn add_positive_time_duration_with_overflow() {
609 use time::Duration;
610
611 let _ = FileTime::MAX + Duration::nanoseconds(100);
612 }
613
614 #[test]
615 fn add_negative_time_duration() {
616 use time::Duration;
617
618 assert_eq!(FileTime::MAX + -Duration::ZERO, FileTime::MAX);
619 assert_eq!(FileTime::MAX + -Duration::NANOSECOND, FileTime::MAX);
620 assert_eq!(FileTime::MAX + Duration::nanoseconds(-99), FileTime::MAX);
621 assert_eq!(
622 FileTime::MAX + Duration::nanoseconds(-100),
623 FileTime::new(u64::MAX - 1)
624 );
625
626 assert_eq!(
627 FileTime::NT_TIME_EPOCH + -Duration::ZERO,
628 FileTime::NT_TIME_EPOCH
629 );
630 assert_eq!(
631 FileTime::NT_TIME_EPOCH + -Duration::NANOSECOND,
632 FileTime::NT_TIME_EPOCH
633 );
634 assert_eq!(
635 FileTime::NT_TIME_EPOCH + Duration::nanoseconds(-99),
636 FileTime::NT_TIME_EPOCH
637 );
638 }
639
640 #[test]
641 #[should_panic(expected = "overflow when subtracting duration from date and time")]
642 fn add_negative_time_duration_with_overflow() {
643 use time::Duration;
644
645 let _ = FileTime::NT_TIME_EPOCH + Duration::nanoseconds(-100);
646 }
647
648 #[cfg(feature = "chrono")]
649 #[test]
650 fn add_positive_chrono_time_delta() {
651 use chrono::TimeDelta;
652
653 assert_eq!(
654 FileTime::NT_TIME_EPOCH + TimeDelta::zero(),
655 FileTime::NT_TIME_EPOCH
656 );
657 assert_eq!(
658 FileTime::NT_TIME_EPOCH + TimeDelta::nanoseconds(1),
659 FileTime::NT_TIME_EPOCH
660 );
661 assert_eq!(
662 FileTime::NT_TIME_EPOCH + TimeDelta::nanoseconds(99),
663 FileTime::NT_TIME_EPOCH
664 );
665 assert_eq!(
666 FileTime::NT_TIME_EPOCH + TimeDelta::nanoseconds(100),
667 FileTime::new(1)
668 );
669
670 assert_eq!(FileTime::MAX + TimeDelta::zero(), FileTime::MAX);
671 assert_eq!(FileTime::MAX + TimeDelta::nanoseconds(1), FileTime::MAX);
672 assert_eq!(FileTime::MAX + TimeDelta::nanoseconds(99), FileTime::MAX);
673 }
674
675 #[cfg(feature = "chrono")]
676 #[test]
677 #[should_panic(expected = "overflow when adding duration to date and time")]
678 fn add_positive_chrono_time_delta_with_overflow() {
679 use chrono::TimeDelta;
680
681 let _ = FileTime::MAX + TimeDelta::nanoseconds(100);
682 }
683
684 #[cfg(feature = "chrono")]
685 #[test]
686 fn add_negative_chrono_time_delta() {
687 use chrono::TimeDelta;
688
689 assert_eq!(FileTime::MAX + -TimeDelta::zero(), FileTime::MAX);
690 assert_eq!(FileTime::MAX + -TimeDelta::nanoseconds(1), FileTime::MAX);
691 assert_eq!(FileTime::MAX + TimeDelta::nanoseconds(-99), FileTime::MAX);
692 assert_eq!(
693 FileTime::MAX + TimeDelta::nanoseconds(-100),
694 FileTime::new(u64::MAX - 1)
695 );
696
697 assert_eq!(
698 FileTime::NT_TIME_EPOCH + -TimeDelta::zero(),
699 FileTime::NT_TIME_EPOCH
700 );
701 assert_eq!(
702 FileTime::NT_TIME_EPOCH + -TimeDelta::nanoseconds(1),
703 FileTime::NT_TIME_EPOCH
704 );
705 assert_eq!(
706 FileTime::NT_TIME_EPOCH + TimeDelta::nanoseconds(-99),
707 FileTime::NT_TIME_EPOCH
708 );
709 }
710
711 #[cfg(feature = "chrono")]
712 #[test]
713 #[should_panic(expected = "overflow when subtracting duration from date and time")]
714 fn add_negative_chrono_time_delta_with_overflow() {
715 use chrono::TimeDelta;
716
717 let _ = FileTime::NT_TIME_EPOCH + TimeDelta::nanoseconds(-100);
718 }
719
720 #[test]
721 fn add_assign_std_duration() {
722 use core::time::Duration;
723
724 {
725 let mut ft = FileTime::NT_TIME_EPOCH;
726 ft += Duration::ZERO;
727 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
728 }
729 {
730 let mut ft = FileTime::NT_TIME_EPOCH;
731 ft += Duration::from_nanos(1);
732 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
733 }
734 {
735 let mut ft = FileTime::NT_TIME_EPOCH;
736 ft += Duration::from_nanos(99);
737 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
738 }
739 {
740 let mut ft = FileTime::NT_TIME_EPOCH;
741 ft += Duration::from_nanos(100);
742 assert_eq!(ft, FileTime::new(1));
743 }
744
745 {
746 let mut ft = FileTime::MAX;
747 ft += Duration::ZERO;
748 assert_eq!(ft, FileTime::MAX);
749 }
750 {
751 let mut ft = FileTime::MAX;
752 ft += Duration::from_nanos(1);
753 assert_eq!(ft, FileTime::MAX);
754 }
755 {
756 let mut ft = FileTime::MAX;
757 ft += Duration::from_nanos(99);
758 assert_eq!(ft, FileTime::MAX);
759 }
760 }
761
762 #[test]
763 #[should_panic(expected = "overflow when adding duration to date and time")]
764 fn add_assign_std_duration_with_overflow() {
765 use core::time::Duration;
766
767 let mut ft = FileTime::MAX;
768 ft += Duration::from_nanos(100);
769 }
770
771 #[test]
772 fn add_assign_positive_time_duration() {
773 use time::Duration;
774
775 {
776 let mut ft = FileTime::NT_TIME_EPOCH;
777 ft += Duration::ZERO;
778 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
779 }
780 {
781 let mut ft = FileTime::NT_TIME_EPOCH;
782 ft += Duration::NANOSECOND;
783 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
784 }
785 {
786 let mut ft = FileTime::NT_TIME_EPOCH;
787 ft += Duration::nanoseconds(99);
788 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
789 }
790 {
791 let mut ft = FileTime::NT_TIME_EPOCH;
792 ft += Duration::nanoseconds(100);
793 assert_eq!(ft, FileTime::new(1));
794 }
795
796 {
797 let mut ft = FileTime::MAX;
798 ft += Duration::ZERO;
799 assert_eq!(ft, FileTime::MAX);
800 }
801 {
802 let mut ft = FileTime::MAX;
803 ft += Duration::NANOSECOND;
804 assert_eq!(ft, FileTime::MAX);
805 }
806 {
807 let mut ft = FileTime::MAX;
808 ft += Duration::nanoseconds(99);
809 assert_eq!(ft, FileTime::MAX);
810 }
811 }
812
813 #[test]
814 #[should_panic(expected = "overflow when adding duration to date and time")]
815 fn add_assign_positive_time_duration_with_overflow() {
816 use time::Duration;
817
818 let mut ft = FileTime::MAX;
819 ft += Duration::nanoseconds(100);
820 }
821
822 #[test]
823 fn add_assign_negative_time_duration() {
824 use time::Duration;
825
826 {
827 let mut ft = FileTime::MAX;
828 ft += -Duration::ZERO;
829 assert_eq!(ft, FileTime::MAX);
830 }
831 {
832 let mut ft = FileTime::MAX;
833 ft += -Duration::NANOSECOND;
834 assert_eq!(ft, FileTime::MAX);
835 }
836 {
837 let mut ft = FileTime::MAX;
838 ft += Duration::nanoseconds(-99);
839 assert_eq!(ft, FileTime::MAX);
840 }
841 {
842 let mut ft = FileTime::MAX;
843 ft += Duration::nanoseconds(-100);
844 assert_eq!(ft, FileTime::new(u64::MAX - 1));
845 }
846
847 {
848 let mut ft = FileTime::NT_TIME_EPOCH;
849 ft += -Duration::ZERO;
850 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
851 }
852 {
853 let mut ft = FileTime::NT_TIME_EPOCH;
854 ft += -Duration::NANOSECOND;
855 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
856 }
857 {
858 let mut ft = FileTime::NT_TIME_EPOCH;
859 ft += Duration::nanoseconds(-99);
860 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
861 }
862 }
863
864 #[test]
865 #[should_panic(expected = "overflow when subtracting duration from date and time")]
866 fn add_assign_negative_time_duration_with_overflow() {
867 use time::Duration;
868
869 let mut ft = FileTime::NT_TIME_EPOCH;
870 ft += Duration::nanoseconds(-100);
871 }
872
873 #[cfg(feature = "chrono")]
874 #[test]
875 fn add_assign_positive_chrono_time_delta() {
876 use chrono::TimeDelta;
877
878 {
879 let mut ft = FileTime::NT_TIME_EPOCH;
880 ft += TimeDelta::zero();
881 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
882 }
883 {
884 let mut ft = FileTime::NT_TIME_EPOCH;
885 ft += TimeDelta::nanoseconds(1);
886 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
887 }
888 {
889 let mut ft = FileTime::NT_TIME_EPOCH;
890 ft += TimeDelta::nanoseconds(99);
891 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
892 }
893 {
894 let mut ft = FileTime::NT_TIME_EPOCH;
895 ft += TimeDelta::nanoseconds(100);
896 assert_eq!(ft, FileTime::new(1));
897 }
898
899 {
900 let mut ft = FileTime::MAX;
901 ft += TimeDelta::zero();
902 assert_eq!(ft, FileTime::MAX);
903 }
904 {
905 let mut ft = FileTime::MAX;
906 ft += TimeDelta::nanoseconds(1);
907 assert_eq!(ft, FileTime::MAX);
908 }
909 {
910 let mut ft = FileTime::MAX;
911 ft += TimeDelta::nanoseconds(99);
912 assert_eq!(ft, FileTime::MAX);
913 }
914 }
915
916 #[cfg(feature = "chrono")]
917 #[test]
918 #[should_panic(expected = "overflow when adding duration to date and time")]
919 fn add_assign_positive_chrono_time_delta_with_overflow() {
920 use chrono::TimeDelta;
921
922 let mut ft = FileTime::MAX;
923 ft += TimeDelta::nanoseconds(100);
924 }
925
926 #[cfg(feature = "chrono")]
927 #[test]
928 fn add_assign_negative_chrono_time_delta() {
929 use chrono::TimeDelta;
930
931 {
932 let mut ft = FileTime::MAX;
933 ft += -TimeDelta::zero();
934 assert_eq!(ft, FileTime::MAX);
935 }
936 {
937 let mut ft = FileTime::MAX;
938 ft += -TimeDelta::nanoseconds(1);
939 assert_eq!(ft, FileTime::MAX);
940 }
941 {
942 let mut ft = FileTime::MAX;
943 ft += TimeDelta::nanoseconds(-99);
944 assert_eq!(ft, FileTime::MAX);
945 }
946 {
947 let mut ft = FileTime::MAX;
948 ft += TimeDelta::nanoseconds(-100);
949 assert_eq!(ft, FileTime::new(u64::MAX - 1));
950 }
951
952 {
953 let mut ft = FileTime::NT_TIME_EPOCH;
954 ft += -TimeDelta::zero();
955 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
956 }
957 {
958 let mut ft = FileTime::NT_TIME_EPOCH;
959 ft += -TimeDelta::nanoseconds(1);
960 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
961 }
962 {
963 let mut ft = FileTime::NT_TIME_EPOCH;
964 ft += TimeDelta::nanoseconds(-99);
965 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
966 }
967 }
968
969 #[cfg(feature = "chrono")]
970 #[test]
971 #[should_panic(expected = "overflow when subtracting duration from date and time")]
972 fn add_assign_negative_chrono_time_delta_with_overflow() {
973 use chrono::TimeDelta;
974
975 let mut ft = FileTime::NT_TIME_EPOCH;
976 ft += TimeDelta::nanoseconds(-100);
977 }
978
979 #[test]
980 fn sub_file_time() {
981 use core::time::Duration;
982
983 assert_eq!(FileTime::MAX - FileTime::MAX, Duration::ZERO);
984 assert_eq!(
985 FileTime::MAX - (FileTime::MAX - Duration::from_nanos(100)),
986 Duration::from_nanos(100)
987 );
988 assert_eq!(
989 FileTime::MAX - FileTime::NT_TIME_EPOCH,
990 Duration::new(1_844_674_407_370, 955_161_500)
991 );
992 }
993
994 #[test]
995 #[should_panic(expected = "attempt to subtract with overflow")]
996 fn sub_file_time_with_overflow() {
997 use core::time::Duration;
998
999 let _ = (FileTime::MAX - Duration::from_nanos(100)) - FileTime::MAX;
1000 }
1001
1002 #[test]
1003 fn sub_std_duration() {
1004 use core::time::Duration;
1005
1006 assert_eq!(FileTime::MAX - Duration::ZERO, FileTime::MAX);
1007 assert_eq!(FileTime::MAX - Duration::from_nanos(1), FileTime::MAX);
1008 assert_eq!(FileTime::MAX - Duration::from_nanos(99), FileTime::MAX);
1009 assert_eq!(
1010 FileTime::MAX - Duration::from_nanos(100),
1011 FileTime::new(u64::MAX - 1)
1012 );
1013
1014 assert_eq!(
1015 FileTime::NT_TIME_EPOCH - Duration::ZERO,
1016 FileTime::NT_TIME_EPOCH
1017 );
1018 assert_eq!(
1019 FileTime::NT_TIME_EPOCH - Duration::from_nanos(1),
1020 FileTime::NT_TIME_EPOCH
1021 );
1022 assert_eq!(
1023 FileTime::NT_TIME_EPOCH - Duration::from_nanos(99),
1024 FileTime::NT_TIME_EPOCH
1025 );
1026 }
1027
1028 #[test]
1029 #[should_panic(expected = "overflow when subtracting duration from date and time")]
1030 fn sub_std_duration_with_overflow() {
1031 use core::time::Duration;
1032
1033 let _ = FileTime::NT_TIME_EPOCH - Duration::from_nanos(100);
1034 }
1035
1036 #[test]
1037 fn sub_positive_time_duration() {
1038 use time::Duration;
1039
1040 assert_eq!(FileTime::MAX - Duration::ZERO, FileTime::MAX);
1041 assert_eq!(FileTime::MAX - Duration::NANOSECOND, FileTime::MAX);
1042 assert_eq!(FileTime::MAX - Duration::nanoseconds(99), FileTime::MAX);
1043 assert_eq!(
1044 FileTime::MAX - Duration::nanoseconds(100),
1045 FileTime::new(u64::MAX - 1)
1046 );
1047
1048 assert_eq!(
1049 FileTime::NT_TIME_EPOCH - Duration::ZERO,
1050 FileTime::NT_TIME_EPOCH
1051 );
1052 assert_eq!(
1053 FileTime::NT_TIME_EPOCH - Duration::NANOSECOND,
1054 FileTime::NT_TIME_EPOCH
1055 );
1056 assert_eq!(
1057 FileTime::NT_TIME_EPOCH - Duration::nanoseconds(99),
1058 FileTime::NT_TIME_EPOCH
1059 );
1060 }
1061
1062 #[test]
1063 #[should_panic(expected = "overflow when subtracting duration from date and time")]
1064 fn sub_positive_time_duration_with_overflow() {
1065 use time::Duration;
1066
1067 let _ = FileTime::NT_TIME_EPOCH - Duration::nanoseconds(100);
1068 }
1069
1070 #[test]
1071 fn sub_negative_time_duration() {
1072 use time::Duration;
1073
1074 assert_eq!(
1075 FileTime::NT_TIME_EPOCH - -Duration::ZERO,
1076 FileTime::NT_TIME_EPOCH
1077 );
1078 assert_eq!(
1079 FileTime::NT_TIME_EPOCH - -Duration::NANOSECOND,
1080 FileTime::NT_TIME_EPOCH
1081 );
1082 assert_eq!(
1083 FileTime::NT_TIME_EPOCH - Duration::nanoseconds(-99),
1084 FileTime::NT_TIME_EPOCH
1085 );
1086 assert_eq!(
1087 FileTime::NT_TIME_EPOCH - Duration::nanoseconds(-100),
1088 FileTime::new(1)
1089 );
1090
1091 assert_eq!(FileTime::MAX - -Duration::ZERO, FileTime::MAX);
1092 assert_eq!(FileTime::MAX - -Duration::NANOSECOND, FileTime::MAX);
1093 assert_eq!(FileTime::MAX - Duration::nanoseconds(-99), FileTime::MAX);
1094 }
1095
1096 #[test]
1097 #[should_panic(expected = "overflow when adding duration to date and time")]
1098 fn sub_negative_time_duration_with_overflow() {
1099 use time::Duration;
1100
1101 let _ = FileTime::MAX - Duration::nanoseconds(-100);
1102 }
1103
1104 #[cfg(feature = "chrono")]
1105 #[test]
1106 fn sub_positive_chrono_time_delta() {
1107 use chrono::TimeDelta;
1108
1109 assert_eq!(FileTime::MAX - TimeDelta::zero(), FileTime::MAX);
1110 assert_eq!(FileTime::MAX - TimeDelta::nanoseconds(1), FileTime::MAX);
1111 assert_eq!(FileTime::MAX - TimeDelta::nanoseconds(99), FileTime::MAX);
1112 assert_eq!(
1113 FileTime::MAX - TimeDelta::nanoseconds(100),
1114 FileTime::new(u64::MAX - 1)
1115 );
1116
1117 assert_eq!(
1118 FileTime::NT_TIME_EPOCH - TimeDelta::zero(),
1119 FileTime::NT_TIME_EPOCH
1120 );
1121 assert_eq!(
1122 FileTime::NT_TIME_EPOCH - TimeDelta::nanoseconds(1),
1123 FileTime::NT_TIME_EPOCH
1124 );
1125 assert_eq!(
1126 FileTime::NT_TIME_EPOCH - TimeDelta::nanoseconds(99),
1127 FileTime::NT_TIME_EPOCH
1128 );
1129 }
1130
1131 #[cfg(feature = "chrono")]
1132 #[test]
1133 #[should_panic(expected = "overflow when subtracting duration from date and time")]
1134 fn sub_positive_chrono_time_delta_with_overflow() {
1135 use chrono::TimeDelta;
1136
1137 let _ = FileTime::NT_TIME_EPOCH - TimeDelta::nanoseconds(100);
1138 }
1139
1140 #[cfg(feature = "chrono")]
1141 #[test]
1142 fn sub_negative_chrono_time_delta() {
1143 use chrono::TimeDelta;
1144
1145 assert_eq!(
1146 FileTime::NT_TIME_EPOCH - -TimeDelta::zero(),
1147 FileTime::NT_TIME_EPOCH
1148 );
1149 assert_eq!(
1150 FileTime::NT_TIME_EPOCH - -TimeDelta::nanoseconds(1),
1151 FileTime::NT_TIME_EPOCH
1152 );
1153 assert_eq!(
1154 FileTime::NT_TIME_EPOCH - TimeDelta::nanoseconds(-99),
1155 FileTime::NT_TIME_EPOCH
1156 );
1157 assert_eq!(
1158 FileTime::NT_TIME_EPOCH - TimeDelta::nanoseconds(-100),
1159 FileTime::new(1)
1160 );
1161
1162 assert_eq!(FileTime::MAX - -TimeDelta::zero(), FileTime::MAX);
1163 assert_eq!(FileTime::MAX - -TimeDelta::nanoseconds(1), FileTime::MAX);
1164 assert_eq!(FileTime::MAX - TimeDelta::nanoseconds(-99), FileTime::MAX);
1165 }
1166
1167 #[cfg(feature = "chrono")]
1168 #[test]
1169 #[should_panic(expected = "overflow when adding duration to date and time")]
1170 fn sub_negative_chrono_time_delta_with_overflow() {
1171 use chrono::TimeDelta;
1172
1173 let _ = FileTime::MAX - TimeDelta::nanoseconds(-100);
1174 }
1175
1176 #[cfg(feature = "std")]
1177 #[test]
1178 fn sub_file_time_from_system_time() {
1179 use std::time::{Duration, SystemTime};
1180
1181 assert_eq!(
1182 (SystemTime::UNIX_EPOCH + Duration::new(910_692_730_085, 477_580_700))
1183 - FileTime::new(9_223_372_036_854_775_807),
1184 Duration::ZERO
1185 );
1186 assert_eq!(
1187 (SystemTime::UNIX_EPOCH + Duration::new(910_692_730_085, 477_580_700))
1188 - FileTime::new(9_223_372_036_854_775_806),
1189 Duration::from_nanos(100)
1190 );
1191 assert_eq!(
1192 (SystemTime::UNIX_EPOCH + Duration::new(910_692_730_085, 477_580_700))
1193 - FileTime::UNIX_EPOCH,
1194 Duration::new(910_692_730_085, 477_580_700)
1195 );
1196 }
1197
1198 #[cfg(feature = "std")]
1199 #[test]
1200 #[should_panic(expected = "RHS provided is later than LHS")]
1201 fn sub_file_time_from_system_time_with_overflow() {
1202 use std::time::{Duration, SystemTime};
1203
1204 let _ = FileTime::new(9_223_372_036_854_775_806)
1205 - (SystemTime::UNIX_EPOCH + Duration::new(910_692_730_085, 477_580_700));
1206 }
1207
1208 #[cfg(feature = "std")]
1209 #[test]
1210 fn sub_system_time_from_file_time() {
1211 use std::time::{Duration, SystemTime};
1212
1213 assert_eq!(
1214 FileTime::new(9_223_372_036_854_775_807)
1215 - (SystemTime::UNIX_EPOCH + Duration::new(910_692_730_085, 477_580_700)),
1216 Duration::ZERO
1217 );
1218 assert_eq!(
1219 FileTime::new(9_223_372_036_854_775_807)
1220 - (SystemTime::UNIX_EPOCH + Duration::new(910_692_730_085, 477_580_699)),
1221 Duration::from_nanos(if cfg!(windows) { 100 } else { 1 })
1222 );
1223 assert_eq!(
1224 FileTime::new(9_223_372_036_854_775_807)
1225 - (SystemTime::UNIX_EPOCH + Duration::new(910_692_730_085, 477_580_601)),
1226 Duration::from_nanos(if cfg!(windows) { 100 } else { 99 })
1227 );
1228 assert_eq!(
1229 FileTime::new(9_223_372_036_854_775_807)
1230 - (SystemTime::UNIX_EPOCH + Duration::new(910_692_730_085, 477_580_600)),
1231 Duration::from_nanos(100)
1232 );
1233 assert_eq!(
1234 FileTime::new(9_223_372_036_854_775_807) - SystemTime::UNIX_EPOCH,
1235 Duration::new(910_692_730_085, 477_580_700)
1236 );
1237 }
1238
1239 #[cfg(feature = "std")]
1240 #[test]
1241 #[should_panic(expected = "RHS provided is later than LHS")]
1242 fn sub_system_time_from_file_time_with_overflow() {
1243 use std::time::{Duration, SystemTime};
1244
1245 let _ = (SystemTime::UNIX_EPOCH + Duration::new(910_692_730_085, 477_580_600))
1246 - FileTime::new(9_223_372_036_854_775_807);
1247 }
1248
1249 #[test]
1250 fn sub_file_time_from_offset_date_time() {
1251 use time::Duration;
1252
1253 assert_eq!(
1254 datetime!(9999-12-31 23:59:59.999_999_900 UTC)
1255 - FileTime::new(2_650_467_743_999_999_999),
1256 Duration::ZERO
1257 );
1258 assert_eq!(
1259 datetime!(9999-12-31 23:59:59.999_999_900 UTC)
1260 - (FileTime::new(2_650_467_743_999_999_999) - Duration::nanoseconds(100)),
1261 Duration::nanoseconds(100)
1262 );
1263 assert_eq!(
1264 datetime!(9999-12-31 23:59:59.999_999_900 UTC) - FileTime::NT_TIME_EPOCH,
1265 Duration::new(265_046_774_399, 999_999_900)
1266 );
1267 }
1268
1269 #[test]
1270 fn sub_offset_date_time_from_file_time() {
1271 use time::Duration;
1272
1273 assert_eq!(
1274 FileTime::new(2_650_467_743_999_999_999)
1275 - datetime!(9999-12-31 23:59:59.999_999_900 UTC),
1276 Duration::ZERO
1277 );
1278 assert_eq!(
1279 FileTime::new(2_650_467_743_999_999_999)
1280 - (datetime!(9999-12-31 23:59:59.999_999_900 UTC) - Duration::nanoseconds(1)),
1281 Duration::nanoseconds(1)
1282 );
1283 assert_eq!(
1284 FileTime::new(2_650_467_743_999_999_999)
1285 - (datetime!(9999-12-31 23:59:59.999_999_900 UTC) - Duration::nanoseconds(99)),
1286 Duration::nanoseconds(99)
1287 );
1288 assert_eq!(
1289 FileTime::new(2_650_467_743_999_999_999)
1290 - (datetime!(9999-12-31 23:59:59.999_999_900 UTC) - Duration::nanoseconds(100)),
1291 Duration::nanoseconds(100)
1292 );
1293 assert_eq!(
1294 FileTime::new(2_650_467_743_999_999_999) - datetime!(1601-01-01 00:00 UTC),
1295 Duration::new(265_046_774_399, 999_999_900)
1296 );
1297 }
1298
1299 #[cfg(feature = "chrono")]
1300 #[test]
1301 fn sub_file_time_from_chrono_date_time() {
1302 use core::time::Duration;
1303
1304 use chrono::{DateTime, TimeDelta, Utc};
1305
1306 assert_eq!(
1307 "+60056-05-28 05:36:10.955161500 UTC"
1308 .parse::<DateTime<Utc>>()
1309 .unwrap()
1310 - FileTime::MAX,
1311 TimeDelta::zero()
1312 );
1313 assert_eq!(
1314 "+60056-05-28 05:36:10.955161500 UTC"
1315 .parse::<DateTime<Utc>>()
1316 .unwrap()
1317 - (FileTime::MAX - Duration::from_nanos(100)),
1318 TimeDelta::nanoseconds(100)
1319 );
1320 assert_eq!(
1321 "+60056-05-28 05:36:10.955161500 UTC"
1322 .parse::<DateTime<Utc>>()
1323 .unwrap()
1324 - FileTime::NT_TIME_EPOCH,
1325 TimeDelta::new(1_844_674_407_370, 955_161_500).unwrap()
1326 );
1327 }
1328
1329 #[cfg(feature = "chrono")]
1330 #[test]
1331 fn sub_chrono_date_time_from_file_time() {
1332 use chrono::{DateTime, TimeDelta, Utc};
1333
1334 assert_eq!(
1335 FileTime::MAX
1336 - "+60056-05-28 05:36:10.955161500 UTC"
1337 .parse::<DateTime<Utc>>()
1338 .unwrap(),
1339 TimeDelta::zero()
1340 );
1341 assert_eq!(
1342 FileTime::MAX
1343 - ("+60056-05-28 05:36:10.955161500 UTC"
1344 .parse::<DateTime<Utc>>()
1345 .unwrap()
1346 - TimeDelta::nanoseconds(1)),
1347 TimeDelta::nanoseconds(1)
1348 );
1349 assert_eq!(
1350 FileTime::MAX
1351 - ("+60056-05-28 05:36:10.955161500 UTC"
1352 .parse::<DateTime<Utc>>()
1353 .unwrap()
1354 - TimeDelta::nanoseconds(99)),
1355 TimeDelta::nanoseconds(99)
1356 );
1357 assert_eq!(
1358 FileTime::MAX
1359 - ("+60056-05-28 05:36:10.955161500 UTC"
1360 .parse::<DateTime<Utc>>()
1361 .unwrap()
1362 - TimeDelta::nanoseconds(100)),
1363 TimeDelta::nanoseconds(100)
1364 );
1365 assert_eq!(
1366 FileTime::MAX - "1601-01-01 00:00:00 UTC".parse::<DateTime<Utc>>().unwrap(),
1367 TimeDelta::new(1_844_674_407_370, 955_161_500).unwrap()
1368 );
1369 }
1370
1371 #[test]
1372 fn sub_assign_std_duration() {
1373 use core::time::Duration;
1374
1375 {
1376 let mut ft = FileTime::MAX;
1377 ft -= Duration::ZERO;
1378 assert_eq!(ft, FileTime::MAX);
1379 }
1380 {
1381 let mut ft = FileTime::MAX;
1382 ft -= Duration::from_nanos(1);
1383 assert_eq!(ft, FileTime::MAX);
1384 }
1385 {
1386 let mut ft = FileTime::MAX;
1387 ft -= Duration::from_nanos(99);
1388 assert_eq!(ft, FileTime::MAX);
1389 }
1390 {
1391 let mut ft = FileTime::MAX;
1392 ft -= Duration::from_nanos(100);
1393 assert_eq!(ft, FileTime::new(u64::MAX - 1));
1394 }
1395
1396 {
1397 let mut ft = FileTime::NT_TIME_EPOCH;
1398 ft -= Duration::ZERO;
1399 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
1400 }
1401 {
1402 let mut ft = FileTime::NT_TIME_EPOCH;
1403 ft -= Duration::from_nanos(1);
1404 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
1405 }
1406 {
1407 let mut ft = FileTime::NT_TIME_EPOCH;
1408 ft -= Duration::from_nanos(99);
1409 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
1410 }
1411 }
1412
1413 #[test]
1414 #[should_panic(expected = "overflow when subtracting duration from date and time")]
1415 fn sub_assign_std_duration_with_overflow() {
1416 use core::time::Duration;
1417
1418 let mut ft = FileTime::NT_TIME_EPOCH;
1419 ft -= Duration::from_nanos(100);
1420 }
1421
1422 #[test]
1423 fn sub_assign_positive_time_duration() {
1424 use time::Duration;
1425
1426 {
1427 let mut ft = FileTime::MAX;
1428 ft -= Duration::ZERO;
1429 assert_eq!(ft, FileTime::MAX);
1430 }
1431 {
1432 let mut ft = FileTime::MAX;
1433 ft -= Duration::NANOSECOND;
1434 assert_eq!(ft, FileTime::MAX);
1435 }
1436 {
1437 let mut ft = FileTime::MAX;
1438 ft -= Duration::nanoseconds(99);
1439 assert_eq!(ft, FileTime::MAX);
1440 }
1441 {
1442 let mut ft = FileTime::MAX;
1443 ft -= Duration::nanoseconds(100);
1444 assert_eq!(ft, FileTime::new(u64::MAX - 1));
1445 }
1446
1447 {
1448 let mut ft = FileTime::NT_TIME_EPOCH;
1449 ft -= Duration::ZERO;
1450 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
1451 }
1452 {
1453 let mut ft = FileTime::NT_TIME_EPOCH;
1454 ft -= Duration::NANOSECOND;
1455 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
1456 }
1457 {
1458 let mut ft = FileTime::NT_TIME_EPOCH;
1459 ft -= Duration::nanoseconds(99);
1460 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
1461 }
1462 }
1463
1464 #[test]
1465 #[should_panic(expected = "overflow when subtracting duration from date and time")]
1466 fn sub_assign_positive_time_duration_with_overflow() {
1467 use time::Duration;
1468
1469 let mut ft = FileTime::NT_TIME_EPOCH;
1470 ft -= Duration::nanoseconds(100);
1471 }
1472
1473 #[test]
1474 fn sub_assign_negative_time_duration() {
1475 use time::Duration;
1476
1477 {
1478 let mut ft = FileTime::NT_TIME_EPOCH;
1479 ft -= -Duration::ZERO;
1480 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
1481 }
1482 {
1483 let mut ft = FileTime::NT_TIME_EPOCH;
1484 ft -= -Duration::NANOSECOND;
1485 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
1486 }
1487 {
1488 let mut ft = FileTime::NT_TIME_EPOCH;
1489 ft -= Duration::nanoseconds(-99);
1490 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
1491 }
1492 {
1493 let mut ft = FileTime::NT_TIME_EPOCH;
1494 ft -= Duration::nanoseconds(-100);
1495 assert_eq!(ft, FileTime::new(1));
1496 }
1497
1498 {
1499 let mut ft = FileTime::MAX;
1500 ft -= -Duration::ZERO;
1501 assert_eq!(ft, FileTime::MAX);
1502 }
1503 {
1504 let mut ft = FileTime::MAX;
1505 ft -= -Duration::NANOSECOND;
1506 assert_eq!(ft, FileTime::MAX);
1507 }
1508 {
1509 let mut ft = FileTime::MAX;
1510 ft -= Duration::nanoseconds(-99);
1511 assert_eq!(ft, FileTime::MAX);
1512 }
1513 }
1514
1515 #[test]
1516 #[should_panic(expected = "overflow when adding duration to date and time")]
1517 fn sub_assign_negative_time_duration_with_overflow() {
1518 use time::Duration;
1519
1520 let mut ft = FileTime::MAX;
1521 ft -= Duration::nanoseconds(-100);
1522 }
1523
1524 #[cfg(feature = "chrono")]
1525 #[test]
1526 fn sub_assign_positive_chrono_time_delta() {
1527 use chrono::TimeDelta;
1528
1529 {
1530 let mut ft = FileTime::MAX;
1531 ft -= TimeDelta::zero();
1532 assert_eq!(ft, FileTime::MAX);
1533 }
1534 {
1535 let mut ft = FileTime::MAX;
1536 ft -= TimeDelta::nanoseconds(1);
1537 assert_eq!(ft, FileTime::MAX);
1538 }
1539 {
1540 let mut ft = FileTime::MAX;
1541 ft -= TimeDelta::nanoseconds(99);
1542 assert_eq!(ft, FileTime::MAX);
1543 }
1544 {
1545 let mut ft = FileTime::MAX;
1546 ft -= TimeDelta::nanoseconds(100);
1547 assert_eq!(ft, FileTime::new(u64::MAX - 1));
1548 }
1549
1550 {
1551 let mut ft = FileTime::NT_TIME_EPOCH;
1552 ft -= TimeDelta::zero();
1553 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
1554 }
1555 {
1556 let mut ft = FileTime::NT_TIME_EPOCH;
1557 ft -= TimeDelta::nanoseconds(1);
1558 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
1559 }
1560 {
1561 let mut ft = FileTime::NT_TIME_EPOCH;
1562 ft -= TimeDelta::nanoseconds(99);
1563 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
1564 }
1565 }
1566
1567 #[cfg(feature = "chrono")]
1568 #[test]
1569 #[should_panic(expected = "overflow when subtracting duration from date and time")]
1570 fn sub_assign_positive_chrono_time_delta_with_overflow() {
1571 use chrono::TimeDelta;
1572
1573 let mut ft = FileTime::NT_TIME_EPOCH;
1574 ft -= TimeDelta::nanoseconds(100);
1575 }
1576
1577 #[cfg(feature = "chrono")]
1578 #[test]
1579 fn sub_assign_negative_chrono_time_delta() {
1580 use chrono::TimeDelta;
1581
1582 {
1583 let mut ft = FileTime::NT_TIME_EPOCH;
1584 ft -= -TimeDelta::zero();
1585 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
1586 }
1587 {
1588 let mut ft = FileTime::NT_TIME_EPOCH;
1589 ft -= -TimeDelta::nanoseconds(1);
1590 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
1591 }
1592 {
1593 let mut ft = FileTime::NT_TIME_EPOCH;
1594 ft -= TimeDelta::nanoseconds(-99);
1595 assert_eq!(ft, FileTime::NT_TIME_EPOCH);
1596 }
1597 {
1598 let mut ft = FileTime::NT_TIME_EPOCH;
1599 ft -= TimeDelta::nanoseconds(-100);
1600 assert_eq!(ft, FileTime::new(1));
1601 }
1602
1603 {
1604 let mut ft = FileTime::MAX;
1605 ft -= -TimeDelta::zero();
1606 assert_eq!(ft, FileTime::MAX);
1607 }
1608 {
1609 let mut ft = FileTime::MAX;
1610 ft -= -TimeDelta::nanoseconds(1);
1611 assert_eq!(ft, FileTime::MAX);
1612 }
1613 {
1614 let mut ft = FileTime::MAX;
1615 ft -= TimeDelta::nanoseconds(-99);
1616 assert_eq!(ft, FileTime::MAX);
1617 }
1618 }
1619
1620 #[cfg(feature = "chrono")]
1621 #[test]
1622 #[should_panic(expected = "overflow when adding duration to date and time")]
1623 fn sub_assign_negative_chrono_time_delta_with_overflow() {
1624 use chrono::TimeDelta;
1625
1626 let mut ft = FileTime::MAX;
1627 ft -= TimeDelta::nanoseconds(-100);
1628 }
1629}