mirror of
https://github.com/storytold/wordcraft.git
synced 2026-10-24 10:27:44 -06:00
Use the browser clock for now_iso on wasm (comment and tracked-change dates) (#214)
Fixes #188. Co-authored-by: Fabio Lussi <198260595+itrycodinganditsbad@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <echelon@gmail.com>
This commit is contained in:
co-authored by
Fabio Lussi
Claude Opus 5.5
Brandon Thomas
parent
24388e2c24
commit
58ae1d5685
Generated
+1
@@ -4939,6 +4939,7 @@ name = "wordcraft-engine"
|
||||
version = "0.4.0"
|
||||
dependencies = [
|
||||
"image",
|
||||
"js-sys",
|
||||
"log",
|
||||
"regex",
|
||||
"regex-automata",
|
||||
|
||||
@@ -27,5 +27,9 @@ regex = { workspace = true }
|
||||
regex-automata = { workspace = true }
|
||||
image = { workspace = true }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
# The browser clock for `now_iso` (`SystemTime::now()` panics on wasm32).
|
||||
js-sys = "0.3"
|
||||
|
||||
[dev-dependencies]
|
||||
zip = { workspace = true }
|
||||
|
||||
@@ -212,19 +212,26 @@ pub fn split_para(s: &mut Session, at: &Pos) -> Result<Pos, CmdError> {
|
||||
Ok(new)
|
||||
}
|
||||
|
||||
/// ISO-8601 timestamp (UTC, seconds) for `secs` since the Unix epoch.
|
||||
fn iso_from_unix_secs(secs: u64) -> String {
|
||||
let (y, m, d) = civil_from_days((secs / 86_400) as i64);
|
||||
let t = secs % 86_400;
|
||||
format!("{y:04}-{m:02}-{d:02}T{:02}:{:02}:{:02}Z", t / 3600, t / 60 % 60, t % 60)
|
||||
}
|
||||
|
||||
/// ISO-8601 timestamp (UTC, seconds).
|
||||
pub fn now_iso() -> String {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
let secs = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).map(|d| d.as_secs()).unwrap_or(0);
|
||||
let days = (secs / 86_400) as i64;
|
||||
let (y, m, d) = civil_from_days(days);
|
||||
let t = secs % 86_400;
|
||||
format!("{y:04}-{m:02}-{d:02}T{:02}:{:02}:{:02}Z", t / 3600, t / 60 % 60, t % 60)
|
||||
iso_from_unix_secs(secs)
|
||||
}
|
||||
// `SystemTime::now()` panics on wasm32-unknown-unknown, so ask the browser's clock.
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
"2026-01-01T00:00:00Z".to_string()
|
||||
let ms = js_sys::Date::now();
|
||||
// Clamp a NaN or pre-epoch clock to 0 rather than fail.
|
||||
iso_from_unix_secs(if ms.is_finite() && ms > 0.0 { (ms / 1000.0) as u64 } else { 0 })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,3 +253,21 @@ pub fn civil_from_days(z: i64) -> (i64, u32, u32) {
|
||||
pub fn story_param(s: &Session, v: &Value) -> StoryRef {
|
||||
v.get("story").and_then(|x| serde_json::from_value(x.clone()).ok()).unwrap_or(s.sel.focus.story)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod iso_tests {
|
||||
use super::iso_from_unix_secs;
|
||||
|
||||
#[test]
|
||||
fn formats_epoch_and_known_timestamps() {
|
||||
assert_eq!(iso_from_unix_secs(0), "1970-01-01T00:00:00Z");
|
||||
assert_eq!(iso_from_unix_secs(1_760_082_785), "2025-10-10T07:53:05Z");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn formats_leap_day_and_year_end() {
|
||||
assert_eq!(iso_from_unix_secs(1_709_164_800), "2024-02-29T00:00:00Z");
|
||||
assert_eq!(iso_from_unix_secs(951_782_400), "2000-02-29T00:00:00Z");
|
||||
assert_eq!(iso_from_unix_secs(1_735_689_599), "2024-12-31T23:59:59Z");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user