Skip to main content

veilid_tools/
raw_timestamp.rs

1use super::*;
2
3cfg_if! {
4    if #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] {
5        use js_sys::Date;
6
7        #[must_use]
8        pub fn get_raw_timestamp() -> u64 {
9            if is_browser() {
10                (Date::now() * 1000.0f64) as u64
11            } else {
12                panic!("WASM requires browser environment");
13            }
14        }
15
16        #[must_use]
17        pub fn display_ts(ts: u64) -> String {
18            if is_browser() {
19                let now = Date::new_0();
20                now.set_time(Date::now());
21                let date = Date::new_0();
22                date.set_time((ts / 1000u64) as f64);
23
24                let show_year = now.get_utc_full_year() != date.get_utc_full_year();
25                let show_month = show_year || now.get_utc_month() != date.get_utc_month();
26                let show_date = show_month || now.get_utc_date() != date.get_utc_date();
27
28                let s_year = if show_year {
29                    format!("{:04}/",date.get_utc_full_year())
30                } else {
31                    "".to_owned()
32                };
33                let s_month = if show_month {
34                    format!("{:02}/",date.get_utc_month())
35                } else {
36                    "".to_owned()
37                };
38                let s_date = if show_date {
39                    format!("{:02}-",date.get_utc_date())
40                } else {
41                    "".to_owned()
42                };
43                let s_time = format!("{:02}:{:02}:{:02}.{:04}",
44                    date.get_utc_hours(),
45                    date.get_utc_minutes(),
46                    date.get_utc_seconds(),
47                    date.get_utc_milliseconds()
48                );
49
50                format!("{}{}{}{}",
51                    s_year,
52                    s_month,
53                    s_date,
54                    s_time
55                )
56            } else {
57                panic!("WASM requires browser environment");
58            }
59        }
60    } else {
61        use std::time::{SystemTime, UNIX_EPOCH};
62        use chrono::{Datelike, Timelike};
63
64        #[must_use]
65        pub fn get_raw_timestamp() -> u64 {
66            match SystemTime::now().duration_since(UNIX_EPOCH) {
67                Ok(n) => n.as_micros() as u64,
68                Err(_) => panic!("SystemTime before UNIX_EPOCH!"),
69            }
70        }
71
72        #[must_use]
73        pub fn display_ts(ts: u64) -> String {
74            let now = chrono::DateTime::<chrono::Utc>::from(SystemTime::now());
75            let date = chrono::DateTime::<chrono::Utc>::from(UNIX_EPOCH + Duration::from_micros(ts));
76
77            let show_year = now.year() != date.year();
78            let show_month = show_year || now.month() != date.month();
79            let show_date = show_month || now.day() != date.day();
80
81            let s_year = if show_year {
82                format!("{:04}/",date.year())
83            } else {
84                "".to_owned()
85            };
86            let s_month = if show_month {
87                format!("{:02}/",date.month())
88            } else {
89                "".to_owned()
90            };
91            let s_date = if show_date {
92                format!("{:02}-",date.day())
93            } else {
94                "".to_owned()
95            };
96            let s_time = format!("{:02}:{:02}:{:02}.{:04}",
97                date.hour(),
98                date.minute(),
99                date.second(),
100                date.nanosecond()/1_000_000
101            );
102            format!("{}{}{}{}",
103                s_year,
104                s_month,
105                s_date,
106                s_time)
107        }
108    }
109}
110
111const DAY: u64 = 1_000_000u64 * 60 * 60 * 24;
112const HOUR: u64 = 1_000_000u64 * 60 * 60;
113const MIN: u64 = 1_000_000u64 * 60;
114const SEC: u64 = 1_000_000u64;
115const MSEC: u64 = 1_000u64;
116
117#[must_use]
118pub fn display_duration(dur: u64) -> String {
119    let days = dur / DAY;
120    let dur = dur % DAY;
121    let hours = dur / HOUR;
122    let dur = dur % HOUR;
123    let mins = dur / MIN;
124    let dur = dur % MIN;
125    let secs = dur / SEC;
126    let dur = dur % SEC;
127    let msecs = dur / MSEC;
128    let dur = dur % MSEC;
129
130    // microseconds format
131    if days == 0 && hours == 0 && mins == 0 && secs == 0 {
132        format!("{}.{:03}ms", msecs, dur)
133    } else {
134        format!(
135            "{}{}{}{}.{:03}s",
136            if days != 0 {
137                format!("{}d", days)
138            } else {
139                "".to_owned()
140            },
141            if hours != 0 {
142                format!("{}h", hours)
143            } else {
144                "".to_owned()
145            },
146            if mins != 0 {
147                format!("{}m", mins)
148            } else {
149                "".to_owned()
150            },
151            secs,
152            msecs
153        )
154    }
155}
156
157#[must_use]
158pub fn parse_duration(s: &str) -> Option<u64> {
159    let mut dur_total: u64 = 0;
160    let mut dur: u64 = 0;
161    for c in s.as_bytes() {
162        match c {
163            b'0'..=b'9' => {
164                dur *= 10;
165                dur += (c - b'0') as u64;
166            }
167            b'h' => {
168                dur *= 3_600_000u64;
169                dur_total += dur;
170                dur = 0;
171            }
172            b'm' => {
173                dur *= 60_000u64;
174                dur_total += dur;
175                dur = 0;
176            }
177            b's' => {
178                dur *= 1_000u64;
179                dur_total += dur;
180                dur = 0;
181            }
182            _ => return None,
183        }
184    }
185    dur_total += dur;
186    Some(dur_total * 1_000u64)
187}