workflow_core/
time.rs

1//!
2//! `time` module provides re-export of WASM32-compatible `Instant` and provides
3//! platform neutral implementations for [`unixtime_as_millis_u128()`] and
4//! [`unixtime_as_millis_f64()`].
5//!
6
7use cfg_if::cfg_if;
8
9/// re-export of [`instant`] crate supporting native and WASM implementations
10pub use instant::*;
11
12pub const SECONDS: u64 = 1000;
13pub const MINUTES: u64 = SECONDS * 60;
14pub const HOURS: u64 = MINUTES * 60;
15pub const DAYS: u64 = HOURS * 24;
16
17pub enum TimeFormat {
18    Time24,
19    Time12,
20    Locale,
21    Custom(String),
22}
23
24cfg_if! {
25    if #[cfg(target_arch = "wasm32")] {
26        use js_sys::{Date,Intl,Reflect};
27        use wasm_bindgen::prelude::JsValue;
28
29        #[inline(always)]
30        pub fn unixtime_as_millis_u128() -> u128 {
31            Date::now() as u128
32        }
33
34        #[inline(always)]
35        pub fn unixtime_as_millis_f64() -> f64 {
36            Date::now()
37        }
38
39        #[inline(always)]
40        pub fn unixtime_as_millis_u64() -> u64 {
41            Date::now() as u64
42        }
43
44        #[inline(always)]
45        pub fn unixtime_to_locale_string(unixtime : u64) -> String {
46            let date = Date::new(&JsValue::from(unixtime as f64));
47            date.to_locale_string(default_locale().as_str(), &JsValue::UNDEFINED).as_string().unwrap()
48        }
49
50        fn default_locale() -> String {
51            static mut LOCALE: Option<String> = None;
52            unsafe {
53                LOCALE.get_or_insert_with(|| {
54                    let date_time_format = Intl::DateTimeFormat::default();
55                    let resolved_options = date_time_format.resolved_options();
56                    let locale = Reflect::get(&resolved_options, &JsValue::from("locale")).expect("Intl::DateTimeFormat().resolvedOptions().locale is not defined");
57                    locale.as_string().expect("Intl::DateTimeFormat().resolvedOptions().locale()")
58                }).clone()
59            }
60        }
61
62        pub fn init_desired_time_format(_time_format : TimeFormat) {
63            // time format is ignored in WASM and
64            // the browser's locale is used instead
65        }
66
67    } else {
68        use chrono::{Local, TimeZone};
69
70        #[inline(always)]
71        pub fn unixtime_as_millis_u128() -> u128 {
72            SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).expect("unixtime_as_millis_u64").as_millis()
73        }
74
75        #[inline(always)]
76        pub fn unixtime_as_millis_f64() -> f64 {
77            SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).expect("unixtime_as_millis_u64").as_millis() as f64
78        }
79
80        #[inline(always)]
81        pub fn unixtime_as_millis_u64() -> u64 {
82            SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).expect("unixtime_as_millis_u64").as_millis() as u64
83        }
84
85        static mut TIME_FORMAT: Option<String> = None;
86
87        #[inline(always)]
88        fn time_format() -> &'static str {
89            unsafe {
90                TIME_FORMAT.get_or_insert_with(|| {
91                    "%Y-%m-%d %H:%M:%S".to_string()
92                }).as_str()
93            }
94        }
95
96        pub fn init_desired_time_format(time_format : TimeFormat) {
97            unsafe {
98                match time_format {
99                    TimeFormat::Time24 => {
100                        TIME_FORMAT = Some("%Y-%m-%d %H:%M:%S".to_string());
101                    },
102                    TimeFormat::Time12 => {
103                        TIME_FORMAT = Some("%Y-%m-%d %I:%M:%S %p".to_string());
104                    },
105                    TimeFormat::Locale => {
106                        TIME_FORMAT = Some("%c".to_string());
107                    },
108                    TimeFormat::Custom(format) => {
109                        TIME_FORMAT = Some(format);
110                    }
111                }
112            }
113        }
114
115        #[inline(always)]
116        pub fn unixtime_to_locale_string(unixtime : u64) -> String {
117            let local = Local.timestamp_millis_opt(unixtime as i64).unwrap();
118            local.format(time_format()).to_string()
119        }
120    }
121}
122
123/*
124#[cfg(test)]
125mod tests {
126    use super::*;
127
128    #[test]
129    fn test_unixtime_to_locale_string() {
130        let now = unixtime_as_millis_u64();
131        let locale_string = unixtime_to_locale_string(now);
132        println!("locale_string: {}", locale_string);
133    }
134}
135*/