Skip to content

Commit ab17a66

Browse files
xy2itmpfs
andauthored
WASM support (#491)
Co-authored-by: tmpfs <[email protected]>
1 parent eb70b0e commit ab17a66

File tree

4 files changed

+61
-0
lines changed

4 files changed

+61
-0
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ time-macros = { version = "=0.2.4", path = "time-macros", optional = true }
4949
libc = "0.2.98"
5050
num_threads = "0.1.2"
5151

52+
[target.'cfg(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi"))))'.dependencies]
53+
js-sys = "0.3.58"
54+
5255
[dev-dependencies]
5356
rand = { version = "0.8.4", default-features = false }
5457
serde = { version = "1.0.126", default-features = false, features = ["derive"] }

src/offset_date_time.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,18 @@ impl OffsetDateTime {
5959
#[cfg(feature = "std")]
6060
#[cfg_attr(__time_03_docs, doc(cfg(feature = "std")))]
6161
pub fn now_utc() -> Self {
62+
#[cfg(all(
63+
target_arch = "wasm32",
64+
not(any(target_os = "emscripten", target_os = "wasi"))
65+
))]
66+
{
67+
js_sys::Date::new_0().into()
68+
}
69+
70+
#[cfg(not(all(
71+
target_arch = "wasm32",
72+
not(any(target_os = "emscripten", target_os = "wasi"))
73+
)))]
6274
SystemTime::now().into()
6375
}
6476

@@ -1320,4 +1332,31 @@ impl From<OffsetDateTime> for SystemTime {
13201332
}
13211333
}
13221334
}
1335+
1336+
#[allow(clippy::fallible_impl_from)]
1337+
#[cfg(all(
1338+
target_arch = "wasm32",
1339+
not(any(target_os = "emscripten", target_os = "wasi"))
1340+
))]
1341+
impl From<js_sys::Date> for OffsetDateTime {
1342+
fn from(js_date: js_sys::Date) -> Self {
1343+
// get_time() returns milliseconds
1344+
let timestamp_nanos = (js_date.get_time() * 1_000_000.0) as i128;
1345+
Self::from_unix_timestamp_nanos(timestamp_nanos)
1346+
.expect("invalid timestamp: Timestamp cannot fit in range")
1347+
}
1348+
}
1349+
1350+
#[cfg(all(
1351+
target_arch = "wasm32",
1352+
not(any(target_os = "emscripten", target_os = "wasi"))
1353+
))]
1354+
impl From<OffsetDateTime> for js_sys::Date {
1355+
fn from(datetime: OffsetDateTime) -> Self {
1356+
// new Date() takes milliseconds
1357+
let timestamp = (datetime.unix_timestamp_nanos() / 1_000_000) as f64;
1358+
js_sys::Date::new(&timestamp.into())
1359+
}
1360+
}
1361+
13231362
// endregion trait impls

src/sys/local_offset_at/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
33
#[cfg_attr(target_family = "windows", path = "windows.rs")]
44
#[cfg_attr(target_family = "unix", path = "unix.rs")]
5+
#[cfg_attr(
6+
all(
7+
target_arch = "wasm32",
8+
not(any(target_os = "emscripten", target_os = "wasi"))
9+
),
10+
path = "wasm_js.rs"
11+
)]
512
mod imp;
613

714
use crate::{OffsetDateTime, UtcOffset};

src/sys/local_offset_at/wasm_js.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use crate::{OffsetDateTime, UtcOffset};
2+
3+
/// Obtain the system's UTC offset.
4+
pub(super) fn local_offset_at(datetime: OffsetDateTime) -> Option<UtcOffset> {
5+
let js_date: js_sys::Date = datetime.into();
6+
// The number of minutes returned by getTimezoneOffset() is positive if the local time zone
7+
// is behind UTC, and negative if the local time zone is ahead of UTC. For example,
8+
// for UTC+10, -600 will be returned.
9+
let timezone_offset = (js_date.get_timezone_offset() as i32) * -60;
10+
11+
UtcOffset::from_whole_seconds(timezone_offset).ok()
12+
}

0 commit comments

Comments
 (0)