plot/lib/logic/
tag_time.rs1use chrono::{Datelike, Local, NaiveDate, NaiveDateTime, NaiveTime, Timelike, Weekday};
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub struct TagTime(pub String);
5
6fn nanos_to_tq(nanos: u32) -> (u32, u32) {
13 let nanos_u64 = nanos as u64;
14 let t = (nanos_u64 * 60 / 1_000_000_000) as u32;
15 let q = ((nanos_u64 * 3600 / 1_000_000_000) % 60) as u32;
16 (t, q)
17}
18
19fn tq_to_nanos(t: u32, q: u32) -> u32 {
22 let total_q = (t as u64 * 60) + q as u64;
23 ((total_q * 1_000_000_000) / 3600) as u32
25}
26
27pub fn tag_from_time<T: Datelike + Timelike>(time: &T) -> TagTime {
34 let r = time.iso_week().year();
36 let w = time.iso_week().week();
37 let d = time.weekday().number_from_monday();
38
39 let h = time.hour();
40 let m = time.minute();
41 let s = time.second();
42
43 let (t, q) = nanos_to_tq(time.nanosecond());
44
45 TagTime(format!("R{r:04}W{w:02}D{d}H{h:02}M{m:02}S{s:02}T{t:02}Q{q:02}"))
46}
47
48pub fn tag_from_time_now() -> TagTime {
50 let now = Local::now();
51 tag_from_time(&now)
52}
53
54pub fn tag_to_time(tag: &TagTime) -> Option<NaiveDateTime> {
57 let s = &tag.0;
58
59 if s.len() != 25 {
62 return None;
63 }
64
65 let r: i32 = s[1..5].parse().ok()?;
67 let w: u32 = s[6..8].parse().ok()?;
68 let d: u32 = s[9..10].parse().ok()?;
69 let h: u32 = s[11..13].parse().ok()?;
70 let m: u32 = s[14..16].parse().ok()?;
71 let sec: u32 = s[17..19].parse().ok()?;
72 let t: u32 = s[20..22].parse().ok()?;
73 let q: u32 = s[23..25].parse().ok()?;
74
75 let weekday = match d {
77 1 => Weekday::Mon,
78 2 => Weekday::Tue,
79 3 => Weekday::Wed,
80 4 => Weekday::Thu,
81 5 => Weekday::Fri,
82 6 => Weekday::Sat,
83 7 => Weekday::Sun,
84 _ => return None,
85 };
86 let date = NaiveDate::from_isoywd_opt(r, w, weekday)?;
87
88 let nanos = tq_to_nanos(t, q);
90 let time = NaiveTime::from_hms_nano_opt(h, m, sec, nanos)?;
91
92 Some(NaiveDateTime::new(date, time))
93}