Skip to main content

calendar_link/
time.rs

1use chrono::{DateTime, Local, Utc};
2use core::fmt::{Display, Formatter};
3use std::fmt::Debug;
4
5#[derive(Debug, Clone, Copy)]
6pub enum EventTime {
7    Utc(DateTime<Utc>),
8    Local(DateTime<Local>),
9}
10
11impl EventTime {
12    #[cfg(test)]
13    pub fn fixed_utc_time() -> DateTime<Utc> {
14        let utc_str_z = "2019-12-28T12:00:00.000Z";
15        chrono::DateTime::parse_from_rfc3339(utc_str_z)
16            .unwrap()
17            .to_utc()
18    }
19    #[cfg(test)]
20    pub fn fixed_utc() -> Self {
21        EventTime::Utc(Self::fixed_utc_time())
22    }
23
24    pub fn is_utc(&self) -> bool {
25        match self {
26            EventTime::Utc(_) => true,
27            EventTime::Local(_) => false,
28        }
29    }
30    pub fn format_as_string(&self, format: EventTimeFormat) -> String {
31        let fmt = format.as_ref();
32        match self {
33            EventTime::Utc(x) => x.format(fmt).to_string(),
34            EventTime::Local(x) => x.format(fmt).to_string(),
35        }
36    }
37}
38impl Default for EventTime {
39    fn default() -> Self {
40        Self::Utc(Default::default())
41    }
42}
43impl Display for EventTime {
44    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
45        if self.is_utc() {
46            write!(f, "{}", self.format_as_string(EventTimeFormat::DateTimeUtc))
47        } else {
48            write!(
49                f,
50                "{}",
51                self.format_as_string(EventTimeFormat::DateTimeLocal)
52            )
53        }
54    }
55}
56
57#[derive(Debug, Clone, Copy)]
58pub enum EventTimeFormat {
59    AllDay,
60    DateTimeUtc,
61    DateTimeLocal,
62}
63impl AsRef<str> for EventTimeFormat {
64    fn as_ref(&self) -> &str {
65        match self {
66            EventTimeFormat::AllDay => "%Y%m%d",
67            EventTimeFormat::DateTimeUtc => "%Y%m%dT%H%M%SZ",
68            EventTimeFormat::DateTimeLocal => "%Y-%m-%dT%H:%M:%S",
69        }
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76
77    #[test]
78    fn should_format_utc() {
79        let d = EventTime::fixed_utc_time();
80        let x = EventTime::Utc(d);
81        assert_eq!(x.to_string(), "20191228T120000Z");
82
83        let x = EventTime::Utc(d);
84        assert_eq!(x.format_as_string(EventTimeFormat::AllDay), "20191228");
85    }
86    #[test]
87    fn should_format_local() {
88        let d = EventTime::fixed_utc_time();
89        let x = EventTime::Local(d.into());
90        assert_eq!(x.to_string(), "2019-12-28T15:30:00"); // it may not pass on your system
91
92        let x = EventTime::Local(d.into());
93        assert_eq!(x.format_as_string(EventTimeFormat::AllDay), "20191228");
94    }
95}