rust_automata/
timestamp.rs1use chrono::{DateTime, Local, TimeDelta, TimeZone, Utc};
5use core::fmt;
6use std::fmt::Display;
7use std::num::ParseIntError;
8use std::ops::{Add, Sub};
9use std::str::FromStr;
10
11#[derive(
19 Debug,
20 Clone,
21 Copy,
22 PartialEq,
23 Eq,
24 PartialOrd,
25 Ord,
26 Default,
27 serde::Serialize,
28 serde::Deserialize,
29)]
30pub struct Timestamp(i64);
31
32#[derive(
36 Debug,
37 Clone,
38 Copy,
39 PartialEq,
40 Eq,
41 PartialOrd,
42 Ord,
43 Default,
44 serde::Serialize,
45 serde::Deserialize,
46)]
47pub struct TimestampDelta(i64);
48
49impl Timestamp {
50 pub const fn zero() -> Self {
51 Self(0)
52 }
53 pub const fn as_secs(&self) -> i64 {
54 self.0 / 1_000_000_000
55 }
56 pub const fn as_millis(&self) -> i64 {
57 self.0 / 1_000_000
58 }
59 pub const fn as_micros(&self) -> i64 {
60 self.0 / 1_000
61 }
62 pub const fn as_nanos(&self) -> i64 {
63 self.0
64 }
65 pub fn local(&self) -> DateTime<Local> {
66 DateTime::<Local>::from(*self)
67 }
68 pub fn utc(&self) -> DateTime<Utc> {
69 DateTime::<Utc>::from(*self)
70 }
71
72 pub const fn from_hours(hours: i64) -> Self {
74 Self(hours * 60 * 60 * 1_000_000_000)
75 }
76 pub const fn from_minutes(minutes: i64) -> Self {
77 Self(minutes * 60 * 1_000_000_000)
78 }
79 pub const fn from_secs(secs: i64) -> Self {
80 Self(secs * 1_000_000_000)
81 }
82 pub const fn from_millis(millis: i64) -> Self {
83 Self(millis * 1_000_000)
84 }
85 pub const fn from_micros(micros: i64) -> Self {
86 Self(micros * 1_000)
87 }
88 pub const fn from_nanos(nanos: i64) -> Self {
89 Self(nanos)
90 }
91}
92
93impl TimestampDelta {
94 pub const fn zero() -> Self {
95 Self(0)
96 }
97 pub const fn as_secs(&self) -> i64 {
98 self.0 / 1_000_000_000
99 }
100 pub const fn as_millis(&self) -> i64 {
101 self.0 / 1_000_000
102 }
103 pub const fn as_micros(&self) -> i64 {
104 self.0 / 1_000
105 }
106 pub const fn as_nanos(&self) -> i64 {
107 self.0
108 }
109
110 pub const fn from_hours(hours: i64) -> Self {
112 Self(hours * 60 * 60 * 1_000_000_000)
113 }
114 pub const fn from_minutes(minutes: i64) -> Self {
115 Self(minutes * 60 * 1_000_000_000)
116 }
117 pub const fn from_secs(secs: i64) -> Self {
118 Self(secs * 1_000_000_000)
119 }
120 pub const fn from_millis(millis: i64) -> Self {
121 Self(millis * 1_000_000)
122 }
123 pub const fn from_micros(micros: i64) -> Self {
124 Self(micros * 1_000)
125 }
126 pub const fn from_nanos(nanos: i64) -> Self {
127 Self(nanos)
128 }
129}
130
131impl Display for Timestamp {
132 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133 write!(f, "{}", self.0)
134 }
135}
136
137impl From<i64> for Timestamp {
138 fn from(nanos: i64) -> Self {
139 Self(nanos)
140 }
141}
142
143impl Add<TimeDelta> for Timestamp {
144 type Output = Timestamp;
145
146 fn add(self, rhs: TimeDelta) -> Self::Output {
147 Timestamp::from(self.0 + rhs.num_nanoseconds().unwrap())
148 }
149}
150impl Add<Timestamp> for Timestamp {
151 type Output = Timestamp;
152
153 fn add(self, rhs: Timestamp) -> Self::Output {
154 Timestamp::from(self.0 + rhs.0)
155 }
156}
157impl Add<TimestampDelta> for Timestamp {
158 type Output = Timestamp;
159
160 fn add(self, rhs: TimestampDelta) -> Self::Output {
161 Timestamp::from(self.0 + rhs.0)
162 }
163}
164
165impl Sub<TimeDelta> for Timestamp {
166 type Output = TimestampDelta;
167
168 fn sub(self, rhs: TimeDelta) -> Self::Output {
169 TimestampDelta::from(self.0 - rhs.num_nanoseconds().unwrap())
170 }
171}
172impl Sub<Timestamp> for Timestamp {
173 type Output = TimestampDelta;
174
175 fn sub(self, rhs: Timestamp) -> Self::Output {
176 TimestampDelta::from(self.0 - rhs.0)
177 }
178}
179
180impl FromStr for Timestamp {
181 type Err = ParseIntError;
182
183 fn from_str(s: &str) -> Result<Self, Self::Err> {
184 let nanos = i64::from_str(s)?;
185 Ok(Timestamp::from(nanos))
186 }
187}
188
189impl From<DateTime<Utc>> for Timestamp {
190 fn from(dt: DateTime<Utc>) -> Self {
191 Self(dt.timestamp_nanos_opt().unwrap())
192 }
193}
194
195impl From<DateTime<Local>> for Timestamp {
196 fn from(dt: DateTime<Local>) -> Self {
197 Self(dt.with_timezone(&Utc).timestamp_nanos_opt().unwrap())
198 }
199}
200
201impl From<Timestamp> for DateTime<Utc> {
202 fn from(ts: Timestamp) -> Self {
203 Utc.timestamp_nanos(ts.0)
204 }
205}
206
207impl From<Timestamp> for DateTime<Local> {
208 fn from(ts: Timestamp) -> Self {
209 let utc: DateTime<Utc> = ts.into();
210 utc.with_timezone(&Local)
211 }
212}
213
214impl From<Timestamp> for TimeDelta {
215 fn from(ts: Timestamp) -> Self {
216 TimeDelta::nanoseconds(ts.0)
217 }
218}
219
220impl Display for TimestampDelta {
221 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
222 write!(f, "{}", self.0)
223 }
224}
225
226impl From<i64> for TimestampDelta {
227 fn from(nanos: i64) -> Self {
228 Self(nanos)
229 }
230}
231
232impl Add<TimeDelta> for TimestampDelta {
233 type Output = TimestampDelta;
234
235 fn add(self, rhs: TimeDelta) -> Self::Output {
236 TimestampDelta::from(self.0 + rhs.num_nanoseconds().unwrap())
237 }
238}
239impl Add<TimestampDelta> for TimestampDelta {
240 type Output = TimestampDelta;
241
242 fn add(self, rhs: TimestampDelta) -> Self::Output {
243 TimestampDelta::from(self.0 + rhs.0)
244 }
245}
246
247impl Sub<TimeDelta> for TimestampDelta {
248 type Output = TimestampDelta;
249
250 fn sub(self, rhs: TimeDelta) -> Self::Output {
251 TimestampDelta::from(self.0 - rhs.num_nanoseconds().unwrap())
252 }
253}
254impl Sub<TimestampDelta> for TimestampDelta {
255 type Output = TimestampDelta;
256
257 fn sub(self, rhs: TimestampDelta) -> Self::Output {
258 TimestampDelta::from(self.0 - rhs.0)
259 }
260}
261
262impl From<TimeDelta> for TimestampDelta {
263 fn from(delta: TimeDelta) -> Self {
264 TimestampDelta::from(delta.num_nanoseconds().unwrap())
265 }
266}
267
268impl From<TimestampDelta> for TimeDelta {
269 fn from(delta: TimestampDelta) -> Self {
270 TimeDelta::nanoseconds(delta.0)
271 }
272}