unix_ts/
std_duration.rs

1use std::convert::TryInto;
2use std::ops::Add;
3use std::ops::AddAssign;
4use std::ops::Sub;
5use std::ops::SubAssign;
6
7use crate::Timestamp;
8
9impl Add<std::time::Duration> for Timestamp {
10  type Output = Self;
11
12  /// Add the provided duration to the timestamp.
13  fn add(self, other: std::time::Duration) -> Timestamp {
14    let s: i64 = other.as_secs() as i64;
15    Timestamp::new(self.seconds + s, self.nanos + other.subsec_nanos())
16  }
17}
18
19impl AddAssign<std::time::Duration> for Timestamp {
20  /// Add the provided duration to the timestamp, in-place.
21  fn add_assign(&mut self, other: std::time::Duration) {
22    let delta: i64 = other.as_secs() as i64;
23    self.seconds += delta;
24    self.nanos += other.subsec_nanos();
25    while self.nanos >= 1_000_000_000 {
26      self.seconds += 1;
27      self.nanos -= 1_000_000_000;
28    }
29  }
30}
31
32impl Sub<std::time::Duration> for Timestamp {
33  type Output = Self;
34
35  /// Subtract the provided duration from the timestamp.
36  fn sub(self, other: std::time::Duration) -> Timestamp {
37    let other_sec: i64 = other.as_secs().try_into().unwrap();
38    if other.subsec_nanos() > self.nanos {
39      return Timestamp::new(
40        self.seconds - other_sec - 1,
41        self.nanos + 1_000_000_000 - other.subsec_nanos(),
42      );
43    }
44    Timestamp::new(self.seconds - other_sec, self.nanos - other.subsec_nanos())
45  }
46}
47
48impl SubAssign<std::time::Duration> for Timestamp {
49  /// Subtract the provided duration to the timestamp, in-place.
50  fn sub_assign(&mut self, other: std::time::Duration) {
51    let delta: i64 = other.as_secs().try_into().unwrap();
52    self.seconds -= delta;
53    if other.subsec_nanos() > self.nanos {
54      self.seconds -= 1;
55      self.nanos += 1_000_000_000;
56    }
57    self.nanos -= other.subsec_nanos();
58  }
59}
60
61#[cfg(test)]
62mod tests {
63  use super::*;
64
65  #[test]
66  fn test_add() {
67    let ts = Timestamp::new(1335020400, 0);
68    let dur = std::time::Duration::new(86400, 0);
69    assert_eq!(ts + dur, Timestamp::new(1335020400 + 86400, 0));
70  }
71
72  #[test]
73  fn test_add_assign() {
74    let mut ts = Timestamp::new(1335020400, 0);
75    ts += std::time::Duration::new(86400, 0);
76    assert_eq!(ts, Timestamp::new(1335020400 + 86400, 0));
77  }
78
79  #[test]
80  fn test_add_assign_nano_overflow() {
81    let mut ts = Timestamp::new(1335020400, 500_000_000);
82    ts += std::time::Duration::new(0, 750_000_000);
83    assert_eq!(ts.seconds, 1335020401);
84    assert_eq!(ts.nanos, 250_000_000);
85  }
86
87  #[test]
88  fn test_sub() {
89    let ts = Timestamp::new(1335020400, 0);
90    let dur = std::time::Duration::new(86400, 0);
91    assert_eq!(ts - dur, Timestamp::new(1335020400 - 86400, 0));
92  }
93
94  #[test]
95  fn test_sub_nano_overflow() {
96    let ts = Timestamp::new(1335020400, 500_000_000) - std::time::Duration::new(0, 750_000_000);
97    assert_eq!(ts.seconds, 1335020399);
98    assert_eq!(ts.nanos, 750_000_000);
99  }
100
101  #[test]
102  fn test_sub_assign() {
103    let mut ts = Timestamp::new(1335020400, 0);
104    ts -= std::time::Duration::new(86400, 0);
105    assert_eq!(ts.seconds, 1335020400 - 86400);
106    assert_eq!(ts.nanos, 0);
107  }
108
109  #[test]
110  fn test_sub_assign_nano_overflow() {
111    let mut ts = Timestamp::new(1335020400, 500_000_000);
112    ts -= std::time::Duration::new(0, 750_000_000);
113    assert_eq!(ts.seconds, 1335020399);
114    assert_eq!(ts.nanos, 750_000_000);
115  }
116}