apple_quant_algorithmic/timestamp/
utc_ns.rs1use std::{
2 ops::{Add, Sub},
3 time::{SystemTime, UNIX_EPOCH},
4};
5
6use apple_quant_core::{TimeDeltaExt, UnwrapOptionExt, UnwrapResultExt};
7
8use chrono::{Duration, NaiveTime};
9
10use chrono_tz::Tz;
11use time::UtcDateTime;
12
13use super::{Timestamp, TimestampType};
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
16pub struct UtcNs(TimestampType);
17
18impl UtcNs {
19 #[inline]
20 pub(crate) unsafe fn from_utc_date_time(
21 utc_date_time: &UtcDateTime,
22 ) -> Self {
23 unsafe {
24 Self::new_unchecked(utc_date_time.unix_timestamp_nanos())
25 }
26 }
27
28 #[inline]
29 pub(crate) fn new_unchecked(
30 utc_ns: TimestampType,
31 ) -> Self {
32 Self(utc_ns)
33 }
34
35 #[cfg(feature = "timestamp-u64")]
36 #[inline]
37 pub(super) fn now() -> Self {
38 let now = SystemTime::now()
39 .duration_since(UNIX_EPOCH).unwrap_release_unsafe();
40
41 let now = (now.as_secs() * 1_000_000_000) + (now.subsec_nanos() as u64);
42 Self(now)
43 }
44
45 #[cfg(not(feature = "timestamp-u64"))]
46 #[inline]
47 pub(super) fn now() -> Self {
48 let now = unsafe {
49 SystemTime::now()
50 .duration_since(UNIX_EPOCH).unwrap_unchecked_release()
51 };
52
53 let now = now.as_nanos() as i128;
54 Self(now)
55 }
56
57 #[inline]
58 pub fn as_timestamp_type(
59 &self,
60 ) -> &TimestampType {
61 &self.0
62 }
63
64 #[inline]
65 pub fn into_timestamp_type(
66 self,
67 ) -> TimestampType {
68 self.0
69 }
70
71 #[inline]
72 pub fn previous_time(
73 &self,
74 tz: Tz,
75 naive_time: &NaiveTime,
76 ) -> Self {
77 unimplemented!()
78 }
79
80 #[inline]
81 pub fn as_timestamp(
82 &self,
83 ) -> Timestamp {
84 (*self).into()
85 }
86
87 #[inline]
88 pub fn into_timestamp(
89 self,
90 ) -> Timestamp {
91 self.into()
92 }
93}
94
95impl From<Timestamp> for UtcNs {
96 fn from(
97 value: Timestamp,
98 ) -> Self {
99 value.into_utc_ns()
100 }
101}
102
103impl Add<Duration> for UtcNs {
104 type Output = Self;
105
106 #[cfg(feature = "timestamp-u64")]
107 #[inline]
108 fn add(
109 mut self,
110 rhs: Duration,
111 ) -> Self::Output {
112 let duration_ns = (rhs.num_seconds() * 1_000_000_000) as u64 +
113 (rhs.subsec_nanos() as u64);
114
115 self.0 += duration_ns;
116 self
117 }
118
119 #[cfg(not(feature = "timestamp-u64"))]
120 #[inline]
121 fn add(
122 mut self,
123 rhs: Duration,
124 ) -> Self::Output {
125 let duration_ns = (rhs.num_seconds() * 1_000_000_000) as i128 +
126 (rhs.subsec_nanos() as i128);
127
128 self.0 += duration_ns;
129 self
130 }
131}
132
133impl Add<&Duration> for UtcNs {
134 type Output = Self;
135
136 #[inline]
137 fn add(
138 self,
139 rhs: &Duration,
140 ) -> Self::Output {
141 self + *rhs
142 }
143}
144
145impl Sub<Duration> for UtcNs {
146 type Output = Self;
147
148 #[cfg(feature = "timestamp-u64")]
149 #[inline]
150 fn sub(
151 mut self,
152 rhs: Duration,
153 ) -> Self::Output {
154 let duration_ns = (rhs.num_seconds() * 1_000_000_000) as u64 +
155 (rhs.subsec_nanos() as u64);
156
157 self.0 -= duration_ns;
158 self
159 }
160
161 #[cfg(not(feature = "timestamp-u64"))]
162 #[inline]
163 fn sub(
164 mut self,
165 rhs: Duration,
166 ) -> Self::Output {
167 let duration_ns = (rhs.num_seconds() * 1_000_000_000) as i128 +
168 (rhs.subsec_nanos() as i128);
169
170 self.0 -= duration_ns;
171 self
172 }
173}
174
175impl Sub<&Duration> for UtcNs {
176 type Output = Self;
177
178 #[inline]
179 fn sub(
180 self,
181 rhs: &Duration,
182 ) -> Self::Output {
183 self - *rhs
184 }
185}
186
187impl Sub for UtcNs {
188 type Output = Duration;
189
190 fn sub(
191 self,
192 rhs: Self,
193 ) -> Self::Output {
194 let nanoseconds = self.0 - rhs.0;
195
196 unsafe {
197 Duration::nanoseconds_i128(nanoseconds).unwrap_unchecked_release()
198 }
199 }
200}
201
202impl Sub for &UtcNs {
203 type Output = Duration;
204
205 fn sub(
206 self,
207 rhs: Self,
208 ) -> Self::Output {
209 *self - *rhs
210 }
211}