[go: up one dir, main page]

worker/
date.rs

1use std::fmt::Display;
2
3use chrono::offset::TimeZone;
4use chrono::Datelike;
5use js_sys::Date as JsDate;
6use wasm_bindgen::JsValue;
7
8/// The equivalent to a JavaScript `Date` Object.
9/// ```no_run
10/// let now = Date::now();
11/// let millis = now.as_millis();
12/// // or use a specific point in time:
13/// let t1: Date = DateInit::Millis(1630611511000).into();
14/// let t2: Date = DateInit::String("Thu, 02 Sep 2021 19:38:31 GMT".to_string()).into();
15/// ```
16#[derive(Debug, Clone, Eq)]
17pub struct Date {
18    js_date: JsDate,
19}
20
21impl PartialEq for Date {
22    fn eq(&self, other: &Self) -> bool {
23        self.js_date.as_f64() == other.js_date.as_f64()
24    }
25}
26
27/// Initialize a `Date` by constructing this enum.
28/// ```no_run
29/// let t1: Date = DateInit::Millis(1630611511000).into();
30/// let t2: Date = DateInit::String("Thu, 02 Sep 2021 19:38:31 GMT".to_string()).into();
31/// ```
32#[derive(Debug)]
33pub enum DateInit {
34    Millis(u64),
35    String(String),
36}
37
38impl From<DateInit> for Date {
39    fn from(init: DateInit) -> Self {
40        Date::new(init)
41    }
42}
43
44impl Date {
45    /// Create a new Date, which requires being initialized from a known DateInit value.
46    pub fn new(init: DateInit) -> Self {
47        let val = match init {
48            DateInit::Millis(n) => JsValue::from_f64(n as f64),
49            DateInit::String(s) => JsValue::from_str(&s),
50        };
51
52        Self {
53            js_date: JsDate::new(&val),
54        }
55    }
56
57    /// Get the current time, represented by a Date.
58    pub fn now() -> Self {
59        Self {
60            js_date: JsDate::new_0(),
61        }
62    }
63
64    /// Convert a Date into its number of milliseconds since the Unix epoch.
65    pub fn as_millis(&self) -> u64 {
66        self.js_date.get_time() as u64
67    }
68}
69
70impl Display for Date {
71    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
72        write!(f, "{}", self.js_date.to_string())
73    }
74}
75
76#[allow(deprecated)]
77impl<T: TimeZone> From<chrono::Date<T>> for Date {
78    fn from(d: chrono::Date<T>) -> Self {
79        Self {
80            js_date: JsDate::new_with_year_month_day(
81                d.year() as u32,
82                d.month() as i32 - 1,
83                d.day() as i32,
84            ),
85        }
86    }
87}
88
89impl<T: TimeZone> From<chrono::DateTime<T>> for Date {
90    fn from(dt: chrono::DateTime<T>) -> Self {
91        DateInit::Millis(dt.timestamp_millis() as u64).into()
92    }
93}
94
95impl From<Date> for JsDate {
96    fn from(val: Date) -> Self {
97        val.js_date
98    }
99}
100
101impl From<JsDate> for Date {
102    fn from(js_date: JsDate) -> Self {
103        Self { js_date }
104    }
105}