1use crate::builtins::Now;
2use crate::host::HostClock;
3use crate::host::HostHooks;
4use crate::host::HostTimeZone;
5use crate::TemporalResult;
6
7use crate::unix_time::EpochNanoseconds;
8use crate::TemporalError;
9use crate::TimeZone;
10use timezone_provider::provider::TimeZoneProvider;
11use web_time::{SystemTime, UNIX_EPOCH};
12
13pub struct Temporal;
25
26impl Temporal {
27 #[cfg(feature = "sys-local")]
29 #[deprecated(
30 since = "0.1.0",
31 note = "`now` deprecated was not clear about the host system implementation, please use `local_now`"
32 )]
33 pub fn now() -> Now<LocalHostSystem> {
34 Now::new(LocalHostSystem)
35 }
36
37 #[cfg(feature = "sys-local")]
40 pub fn local_now() -> Now<LocalHostSystem> {
41 Now::new(LocalHostSystem)
42 }
43
44 #[cfg(feature = "sys")]
47 pub fn utc_now() -> Now<UtcHostSystem> {
48 Now::new(UtcHostSystem)
49 }
50}
51
52#[cfg(feature = "sys")]
57pub struct UtcHostSystem;
58
59#[cfg(feature = "sys")]
60impl HostHooks for UtcHostSystem {}
61
62#[cfg(feature = "sys")]
63impl HostClock for UtcHostSystem {
64 fn get_host_epoch_nanoseconds(&self) -> TemporalResult<EpochNanoseconds> {
65 get_system_nanoseconds()
66 }
67}
68
69#[cfg(feature = "sys")]
70impl HostTimeZone for UtcHostSystem {
71 fn get_host_time_zone(
72 &self,
73 provider: &(impl TimeZoneProvider + ?Sized),
74 ) -> TemporalResult<TimeZone> {
75 Ok(TimeZone::utc_with_provider(provider))
76 }
77}
78
79#[cfg(feature = "sys-local")]
84pub struct LocalHostSystem;
85
86#[cfg(feature = "sys-local")]
87impl HostHooks for LocalHostSystem {}
88
89#[cfg(feature = "sys-local")]
90impl HostClock for LocalHostSystem {
91 fn get_host_epoch_nanoseconds(&self) -> TemporalResult<EpochNanoseconds> {
92 get_system_nanoseconds()
93 }
94}
95
96#[cfg(feature = "sys-local")]
97impl HostTimeZone for LocalHostSystem {
98 fn get_host_time_zone(
99 &self,
100 provider: &(impl TimeZoneProvider + ?Sized),
101 ) -> TemporalResult<TimeZone> {
102 get_system_timezone(provider)
103 }
104}
105
106#[cfg(feature = "sys-local")]
107#[inline]
108pub(crate) fn get_system_timezone(
109 provider: &(impl TimeZoneProvider + ?Sized),
110) -> TemporalResult<TimeZone> {
111 iana_time_zone::get_timezone()
112 .map(|s| TimeZone::try_from_identifier_str_with_provider(&s, provider))
113 .map_err(|_| TemporalError::general("Error fetching system time"))?
114}
115
116pub(crate) fn get_system_nanoseconds() -> TemporalResult<EpochNanoseconds> {
118 use crate::unix_time::EpochNanoseconds;
119
120 SystemTime::now()
121 .duration_since(UNIX_EPOCH)
122 .map_err(|_| TemporalError::general("Error fetching system time"))
123 .map(|d| EpochNanoseconds::from(d.as_nanos() as i128))
124}