1use std::fmt::Display;
2
3use chrono::offset::TimeZone;
4use chrono::Datelike;
5use js_sys::Date as JsDate;
6use wasm_bindgen::JsValue;
7
8#[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#[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 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 pub fn now() -> Self {
59 Self {
60 js_date: JsDate::new_0(),
61 }
62 }
63
64 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}