1use crate::fmt::format::Writer;
3use std::fmt;
4use std::time as stdtime;
5use std::time::Instant;
6
7mod datetime;
8
9#[cfg(feature = "time")]
10mod time_crate;
11
12#[cfg(feature = "time")]
13#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
14pub use time_crate::UtcTime;
15
16#[cfg(feature = "local-time")]
17#[cfg_attr(docsrs, doc(cfg(all(unsound_local_offset, feature = "local-time"))))]
18pub use time_crate::LocalTime;
19
20#[cfg(feature = "time")]
21#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
22pub use time_crate::OffsetTime;
23
24#[cfg(feature = "chrono")]
26mod chrono_crate;
27
28#[cfg(feature = "chrono")]
29#[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
30pub use chrono_crate::ChronoLocal;
31
32#[cfg(feature = "chrono")]
33#[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
34pub use chrono_crate::ChronoUtc;
35
36pub trait FormatTime {
49 fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result;
55}
56
57pub trait Clock {
62 type Snapshot;
64 fn now(&self) -> Self::Snapshot;
66}
67
68pub trait TimestampFormatter<Input> {
71 fn format(&self, input: &Input, w: &mut Writer<'_>) -> fmt::Result;
73}
74
75#[derive(Debug, Clone, Copy, Default)]
78pub struct Timer<C, F>(pub C, pub F);
79
80impl<C, F> FormatTime for Timer<C, F>
81where
82 C: Clock,
83 F: TimestampFormatter<C::Snapshot>,
84{
85 fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result {
86 let snap = self.0.now();
87 self.1.format(&snap, w)
88 }
89}
90
91#[derive(Debug, Clone, Copy, Default)]
94pub struct SystemClock;
95
96impl Clock for SystemClock {
97 type Snapshot = stdtime::SystemTime;
98 fn now(&self) -> Self::Snapshot {
99 stdtime::SystemTime::now()
100 }
101}
102
103#[derive(Debug, Clone, Copy, Default)]
105pub struct Rfc3339<const DIGITS: u8, const Z: bool>;
106
107impl<const D: u8, const Z: bool> TimestampFormatter<stdtime::SystemTime> for Rfc3339<D, Z> {
108 fn format(&self, input: &stdtime::SystemTime, w: &mut Writer<'_>) -> fmt::Result {
109 let dt = datetime::DateTime::from(*input);
111 let digits = if D > 9 { 9 } else { D } as u8;
112 dt.fmt_rfc3339_with_subsec_to(w, digits, Z)
113 }
114}
115
116pub fn time() -> SystemTime {
128 SystemTime
129}
130
131pub fn uptime() -> Uptime {
146 Uptime::default()
147}
148
149impl<F> FormatTime for &F
150where
151 F: FormatTime,
152{
153 fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result {
154 (*self).format_time(w)
155 }
156}
157
158impl FormatTime for () {
159 fn format_time(&self, _: &mut Writer<'_>) -> fmt::Result {
160 Ok(())
161 }
162}
163
164impl FormatTime for fn(&mut Writer<'_>) -> fmt::Result {
165 fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result {
166 (*self)(w)
167 }
168}
169
170#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
172pub struct SystemTime;
173
174#[derive(Debug, Clone, Copy, Eq, PartialEq)]
178pub struct Uptime {
179 epoch: Instant,
180}
181
182impl Default for Uptime {
183 fn default() -> Self {
184 Uptime {
185 epoch: Instant::now(),
186 }
187 }
188}
189
190impl From<Instant> for Uptime {
191 fn from(epoch: Instant) -> Self {
192 Uptime { epoch }
193 }
194}
195
196impl FormatTime for SystemTime {
197 fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result {
198 Timer(SystemClock, Rfc3339::<6, true>).format_time(w)
200 }
201}
202
203impl FormatTime for Uptime {
204 fn format_time(&self, w: &mut Writer<'_>) -> fmt::Result {
205 let e = self.epoch.elapsed();
206 write!(w, "{:4}.{:09}s", e.as_secs(), e.subsec_nanos())
207 }
208}
209
210#[derive(Debug, Clone, Copy, Default)]
214pub struct UnixSeconds;
215#[derive(Debug, Clone, Copy, Default)]
217pub struct UnixMillis;
218#[derive(Debug, Clone, Copy, Default)]
220pub struct UnixMicros;
221#[derive(Debug, Clone, Copy, Default)]
223pub struct UnixNanos;
224
225impl TimestampFormatter<stdtime::SystemTime> for UnixSeconds {
226 fn format(&self, input: &stdtime::SystemTime, w: &mut Writer<'_>) -> fmt::Result {
227 let v = unix_units(input, 1_000_000_000, 0);
228 write!(w, "{}", v)
229 }
230}
231impl TimestampFormatter<stdtime::SystemTime> for UnixMillis {
232 fn format(&self, input: &stdtime::SystemTime, w: &mut Writer<'_>) -> fmt::Result {
233 let v = unix_units(input, 1_000_000_000, 1_000_000);
234 write!(w, "{}", v)
235 }
236}
237impl TimestampFormatter<stdtime::SystemTime> for UnixMicros {
238 fn format(&self, input: &stdtime::SystemTime, w: &mut Writer<'_>) -> fmt::Result {
239 let v = unix_units(input, 1_000_000_000, 1_000);
240 write!(w, "{}", v)
241 }
242}
243impl TimestampFormatter<stdtime::SystemTime> for UnixNanos {
244 fn format(&self, input: &stdtime::SystemTime, w: &mut Writer<'_>) -> fmt::Result {
245 let v = unix_units(input, 1_000_000_000, 1);
246 write!(w, "{}", v)
247 }
248}
249
250fn unix_units(ts: &stdtime::SystemTime, base_nanos: u32, unit_div: u32) -> i128 {
251 match ts.duration_since(stdtime::UNIX_EPOCH) {
252 Ok(d) => {
253 let secs = d.as_secs() as i128;
254 let nanos = d.subsec_nanos() as i128;
255 if unit_div == 0 {
256 secs
257 } else {
258 secs * (base_nanos as i128 / unit_div as i128) + nanos / unit_div as i128
259 }
260 }
261 Err(e) => {
262 let d = e.duration();
263 let secs = d.as_secs() as i128;
264 let nanos = d.subsec_nanos() as i128;
265 if unit_div == 0 {
266 -secs - if nanos == 0 { 0 } else { 1 }
268 } else {
269 let unit = base_nanos as i128 / unit_div as i128;
270 let whole = secs * unit;
271 let frac = nanos / unit_div as i128;
272 if frac == 0 {
273 -whole
274 } else {
275 -(whole + frac)
276 }
277 }
278 }
279 }
280}
281
282impl SystemTime {
283 pub const fn rfc3339_seconds() -> Timer<SystemClock, Rfc3339<0, true>> {
285 Timer(SystemClock, Rfc3339)
286 }
287 pub const fn rfc3339_millis() -> Timer<SystemClock, Rfc3339<3, true>> {
289 Timer(SystemClock, Rfc3339)
290 }
291
292 pub const fn rfc3339_nanos() -> Timer<SystemClock, Rfc3339<9, true>> {
294 Timer(SystemClock, Rfc3339)
295 }
296
297 pub const fn unix_seconds() -> Timer<SystemClock, UnixSeconds> {
299 Timer(SystemClock, UnixSeconds)
300 }
301
302 pub const fn unix_millis() -> Timer<SystemClock, UnixMillis> {
304 Timer(SystemClock, UnixMillis)
305 }
306
307 pub const fn unix_micros() -> Timer<SystemClock, UnixMicros> {
309 Timer(SystemClock, UnixMicros)
310 }
311
312 pub const fn unix_nanos() -> Timer<SystemClock, UnixNanos> {
314 Timer(SystemClock, UnixNanos)
315 }
316}
317
318#[doc(hidden)]
320#[derive(Debug, Clone, Copy, Default)]
321pub struct TimeOfDay<const DIGITS: u8>;
322
323impl<const D: u8> TimestampFormatter<stdtime::SystemTime> for TimeOfDay<D> {
324 fn format(&self, input: &stdtime::SystemTime, w: &mut Writer<'_>) -> fmt::Result {
325 let dt = datetime::DateTime::from(*input);
326 let digits = if D > 9 { 9 } else { D } as u8;
327 dt.fmt_time_of_day_to(w, digits, false)
329 }
330}
331
332impl SystemTime {
333 pub const fn time_only_secs() -> Timer<SystemClock, TimeOfDay<0>> {
335 Timer(SystemClock, TimeOfDay)
336 }
337
338 pub const fn time_only_millis() -> Timer<SystemClock, TimeOfDay<3>> {
340 Timer(SystemClock, TimeOfDay)
341 }
342
343 pub const fn time_only_micros() -> Timer<SystemClock, TimeOfDay<6>> {
345 Timer(SystemClock, TimeOfDay)
346 }
347}