Skip to content

Commit

Permalink
WASM support (#491)
Browse files Browse the repository at this point in the history
Co-authored-by: tmpfs <muji@tmpfs.org>
  • Loading branch information
xy2i and tmpfs committed Jul 29, 2022
1 parent eb70b0e commit ab17a66
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ time-macros = { version = "=0.2.4", path = "time-macros", optional = true }
libc = "0.2.98"
num_threads = "0.1.2"

[target.'cfg(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi"))))'.dependencies]
js-sys = "0.3.58"

[dev-dependencies]
rand = { version = "0.8.4", default-features = false }
serde = { version = "1.0.126", default-features = false, features = ["derive"] }
Expand Down
39 changes: 39 additions & 0 deletions src/offset_date_time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ impl OffsetDateTime {
#[cfg(feature = "std")]
#[cfg_attr(__time_03_docs, doc(cfg(feature = "std")))]
pub fn now_utc() -> Self {
#[cfg(all(
target_arch = "wasm32",
not(any(target_os = "emscripten", target_os = "wasi"))
))]
{
js_sys::Date::new_0().into()
}

#[cfg(not(all(
target_arch = "wasm32",
not(any(target_os = "emscripten", target_os = "wasi"))
)))]
SystemTime::now().into()
}

Expand Down Expand Up @@ -1320,4 +1332,31 @@ impl From<OffsetDateTime> for SystemTime {
}
}
}

#[allow(clippy::fallible_impl_from)]
#[cfg(all(
target_arch = "wasm32",
not(any(target_os = "emscripten", target_os = "wasi"))
))]
impl From<js_sys::Date> for OffsetDateTime {
fn from(js_date: js_sys::Date) -> Self {
// get_time() returns milliseconds
let timestamp_nanos = (js_date.get_time() * 1_000_000.0) as i128;
Self::from_unix_timestamp_nanos(timestamp_nanos)
.expect("invalid timestamp: Timestamp cannot fit in range")
}
}

#[cfg(all(
target_arch = "wasm32",
not(any(target_os = "emscripten", target_os = "wasi"))
))]
impl From<OffsetDateTime> for js_sys::Date {
fn from(datetime: OffsetDateTime) -> Self {
// new Date() takes milliseconds
let timestamp = (datetime.unix_timestamp_nanos() / 1_000_000) as f64;
js_sys::Date::new(&timestamp.into())
}
}

// endregion trait impls
7 changes: 7 additions & 0 deletions src/sys/local_offset_at/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

#[cfg_attr(target_family = "windows", path = "windows.rs")]
#[cfg_attr(target_family = "unix", path = "unix.rs")]
#[cfg_attr(
all(
target_arch = "wasm32",
not(any(target_os = "emscripten", target_os = "wasi"))
),
path = "wasm_js.rs"
)]
mod imp;

use crate::{OffsetDateTime, UtcOffset};
Expand Down
12 changes: 12 additions & 0 deletions src/sys/local_offset_at/wasm_js.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use crate::{OffsetDateTime, UtcOffset};

/// Obtain the system's UTC offset.
pub(super) fn local_offset_at(datetime: OffsetDateTime) -> Option<UtcOffset> {
let js_date: js_sys::Date = datetime.into();
// The number of minutes returned by getTimezoneOffset() is positive if the local time zone
// is behind UTC, and negative if the local time zone is ahead of UTC. For example,
// for UTC+10, -600 will be returned.
let timezone_offset = (js_date.get_timezone_offset() as i32) * -60;

UtcOffset::from_whole_seconds(timezone_offset).ok()
}

0 comments on commit ab17a66

Please sign in to comment.