use time::Duration; use time::OffsetDateTime; #[cfg(target_arch = "wasm32")] pub fn now_utc() -> OffsetDateTime { return OffsetDateTime::from_unix_timestamp_nanos((js_sys::Date::now() * 1_000_000f64) as i128) .expect("current time outside supported range"); } #[cfg(not(target_arch = "wasm32"))] #[inline(always)] pub fn now_utc() -> OffsetDateTime { return OffsetDateTime::now_utc(); } #[cfg(target_arch = "wasm32")] type InnerInstant = Duration; #[cfg(not(target_arch = "wasm32"))] type InnerInstant = time::Instant; /// On wasm32, represented as a [`Duration`] from an arbitrary epoch. On other architectures, /// represented as [`time::Instant`]. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pub struct Instant(InnerInstant); impl Instant { #[cfg(target_arch = "wasm32")] pub fn now() -> Instant { let stamp = web_sys::window() .expect("cannot get window") .performance() .expect("cannot get performance") .now(); return Instant(Duration::seconds_f64(stamp / 1_000f64)); } #[cfg(not(target_arch = "wasm32"))] #[inline(always)] pub fn now() -> Instant { return Instant(time::Instant::now()); } #[inline(always)] pub fn elapsed(self) -> Duration { Self::now() - self } } impl std::ops::Sub for Instant { type Output = Duration; #[inline(always)] fn sub(self, rhs: Self) -> Self::Output { self.0 - rhs.0 } } #[cfg(feature = "local-offset")] #[cfg(target_arch = "wasm32")] pub fn current_local_offset() -> Result { // The value returned by `getTimezoneOffset()` is inverted. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset#negative_values_and_positive_values. time::UtcOffset::from_whole_seconds( (-js_sys::Date::new_0().get_timezone_offset() * 60f64) as i32, ) .map_err(|_| time::error::IndeterminateOffset) } #[cfg(feature = "local-offset")] #[cfg(not(target_arch = "wasm32"))] #[inline(always)] pub fn current_local_offset() -> Result { time::UtcOffset::current_local_offset() }