Skip to main content

ai_chrono/offset/
utc.rs

1// This is a part of Chrono.
2// See README.md and LICENSE.txt for details.
3
4//! The UTC (Coordinated Universal Time) time zone.
5
6use 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/// The UTC time zone. This is the most efficient time zone when you don't need the local time.
21/// It is also used as an offset (which is also a dummy type).
22///
23/// Using the [`TimeZone`](./trait.TimeZone.html) methods
24/// on the UTC struct is the preferred way to construct `DateTime<Utc>`
25/// instances.
26///
27/// # Example
28///
29/// ```
30/// use ai_chrono::{DateTime, TimeZone, Utc};
31///
32/// let dt = DateTime::from_timestamp(61, 0).unwrap();
33///
34/// assert_eq!(Utc.timestamp_opt(61, 0).unwrap(), dt);
35/// assert_eq!(Utc.with_ymd_and_hms(1970, 1, 1, 0, 1, 1).unwrap(), dt);
36/// ```
37#[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    /// Returns a `Date` which corresponds to the current date.
82    #[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    /// Returns a `DateTime<Utc>` which corresponds to the current date and time in UTC.
93    ///
94    /// See also the similar [`Local::now()`] which returns `DateTime<Local>`, i.e. the local date
95    /// and time including offset from UTC.
96    ///
97    /// [`Local::now()`]: crate::Local::now
98    #[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}