1use core::fmt;
7use core::time::Duration;
8#[cfg(feature = "std_now")]
9use std::time::{SystemTime, UNIX_EPOCH};
10
11#[cfg(any(feature = "rkyv", feature = "rkyv-16", feature = "rkyv-32", feature = "rkyv-64"))]
12use rkyv::{Archive, Deserialize, Serialize};
13
14use super::{FixedOffset, MappedLocalTime, Offset, TimeZone};
15use crate::naive::{NaiveDate, NaiveDateTime};
16
17#[allow(deprecated)]
18use crate::{Date, DateTime};
19
20#[derive(Copy, Clone, PartialEq, Eq, Hash)]
38#[cfg_attr(
39 any(feature = "rkyv", feature = "rkyv-16", feature = "rkyv-32", feature = "rkyv-64"),
40 derive(Archive, Deserialize, Serialize),
41 archive(compare(PartialEq)),
42 archive_attr(derive(Clone, Copy, PartialEq, Eq, Debug, Hash))
43)]
44#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
45#[cfg_attr(all(feature = "arbitrary", feature = "std"), derive(arbitrary::Arbitrary))]
46pub struct Utc;
47
48pub trait Now {
49 fn now() -> Duration;
50}
51
52#[cfg(feature = "std_now")]
53pub struct StdNow;
54
55#[cfg(feature = "std_now")]
56impl Now for StdNow {
57 fn now() -> Duration {
58 SystemTime::now().duration_since(UNIX_EPOCH).expect("system time before Unix epoch")
59 }
60}
61
62#[cfg(all(
63 feature = "wasm_now",
64 target_arch = "wasm32",
65 not(any(target_os = "emscripten", target_os = "wasi"))
66))]
67pub struct WasmNow;
68
69#[cfg(all(
70 feature = "wasm_now",
71 target_arch = "wasm32",
72 not(any(target_os = "emscripten", target_os = "wasi"))
73))]
74impl Now for WasmNow {
75 fn now() -> Duration {
76 Duration::from_millis(js_sys::Date::now() as u64)
77 }
78}
79
80impl Utc {
81 #[deprecated(
83 since = "0.4.23",
84 note = "use `Utc::now()` instead, potentially with `.date_naive()`"
85 )]
86 #[allow(deprecated)]
87 #[must_use]
88 pub fn today<N: Now>() -> Date<Utc> {
89 Utc::now::<N>().date()
90 }
91
92 #[cfg_attr(
99 feature = "std_now",
100 doc = r#"
101# Example
102
103```rust
104# #![allow(unused_variables)]
105# use ai_chrono::{FixedOffset, Utc, StdNow};
106// Current time in UTC
107let now_utc = Utc::now::<StdNow>();
108
109// Current date in UTC
110let today_utc = now_utc.date_naive();
111
112// Current time in some timezone (let's use +05:00)
113let offset = FixedOffset::east_opt(5 * 60 * 60).unwrap();
114let now_with_offset = Utc::now::<StdNow>().with_timezone(&offset);
115```
116"#
117 )]
118 #[must_use]
119 pub fn now<N: Now>() -> DateTime<Utc> {
120 let now = N::now();
121 DateTime::from_timestamp(now.as_secs() as i64, now.subsec_nanos()).unwrap()
122 }
123}
124
125impl TimeZone for Utc {
126 type Offset = Utc;
127
128 fn from_offset(_state: &Utc) -> Utc {
129 Utc
130 }
131
132 fn offset_from_local_date(&self, _local: &NaiveDate) -> MappedLocalTime<Utc> {
133 MappedLocalTime::Single(Utc)
134 }
135 fn offset_from_local_datetime(&self, _local: &NaiveDateTime) -> MappedLocalTime<Utc> {
136 MappedLocalTime::Single(Utc)
137 }
138
139 fn offset_from_utc_date(&self, _utc: &NaiveDate) -> Utc {
140 Utc
141 }
142 fn offset_from_utc_datetime(&self, _utc: &NaiveDateTime) -> Utc {
143 Utc
144 }
145}
146
147impl Offset for Utc {
148 fn fix(&self) -> FixedOffset {
149 FixedOffset::east_opt(0).unwrap()
150 }
151}
152
153impl fmt::Debug for Utc {
154 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
155 write!(f, "Z")
156 }
157}
158
159impl fmt::Display for Utc {
160 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
161 write!(f, "UTC")
162 }
163}
164
165#[cfg(feature = "defmt")]
166impl defmt::Format for Utc {
167 fn format(&self, fmt: defmt::Formatter) {
168 defmt::write!(fmt, "Z");
169 }
170}