Skip to main content

dfx_base/fields/converters/
datetime.rs

1#![allow(dead_code)]
2#![allow(unused)]
3pub const MICROS_PER_MILLIS: u32 = 1000;
4pub const NANOS_PER_MICRO: u32 = 1000;
5pub const TICKS_PER_MICROSECOND: u32 = 10;
6pub const NANOSECONDS_PER_TICK: u32 = 100;
7
8// https://docs.rs/chrono/latest/chrono/format/strftime/index.html
9pub const DATE_TIME_FORMAT_WITH_NANOSECONDS_LEN: usize = 8 + 1 + 6 + 2 + 1 + 9;
10pub const DATE_TIME_FORMAT_WITH_NANOSECONDS: &str = "%Y%m%d-%H:%M:%S.%f";
11pub const DATE_TIME_FORMAT_WITH_MICROSECONDS_LEN: usize = 8 + 1 + 6 + 2 + 1 + 6;
12pub const DATE_TIME_FORMAT_WITH_MICROSECONDS: &str = "%Y%m%d-%H:%M:%S.%6f";
13pub const DATE_TIME_FORMAT_WITH_MILLISECONDS_LEN: usize = 8 + 1 + 6 + 2 + 1 + 3;
14pub const DATE_TIME_FORMAT_WITH_MILLISECONDS: &str = "%Y%m%d-%H:%M:%S.%3f";
15pub const DATE_TIME_FORMAT_WITHOUT_MILLISECONDS_LEN: usize = 8 + 1 + 6 + 2;
16pub const DATE_TIME_FORMAT_WITHOUT_MILLISECONDS: &str = "%Y%m%d-%H:%M:%S";
17pub const DATE_ONLY_FORMAT: &str = "%Y%m%d";
18pub const TIME_ONLY_FORMAT_WITH_NANOSECONDS: &str = "%H:%M:%S.%f";
19pub const TIME_ONLY_FORMAT_WITH_MICROSECONDS: &str = "%H:%M:%S.%6f";
20pub const TIME_ONLY_FORMAT_WITH_MILLISECONDS: &str = "%H:%M:%S.%3f";
21pub const TIME_ONLY_FORMAT_WITHOUT_MILLISECONDS: &str = "%H:%M:%S";
22
23#[derive(Clone, Debug, PartialEq, Eq)]
24pub enum DateTimeFormat {
25    Nanoseconds,
26    Microseconds,
27    Milliseconds,
28    Seconds,
29}
30
31impl DateTimeFormat {
32    pub fn as_datetime_format(&self) -> &str {
33        match self {
34            DateTimeFormat::Nanoseconds => DATE_TIME_FORMAT_WITH_NANOSECONDS,
35            DateTimeFormat::Microseconds => DATE_TIME_FORMAT_WITH_MICROSECONDS,
36            DateTimeFormat::Milliseconds => DATE_TIME_FORMAT_WITH_MILLISECONDS,
37            DateTimeFormat::Seconds => DATE_TIME_FORMAT_WITHOUT_MILLISECONDS,
38        }
39    }
40    pub fn as_time_format(&self) -> &str {
41        match self {
42            DateTimeFormat::Nanoseconds => TIME_ONLY_FORMAT_WITH_NANOSECONDS,
43            DateTimeFormat::Microseconds => TIME_ONLY_FORMAT_WITH_MICROSECONDS,
44            DateTimeFormat::Milliseconds => TIME_ONLY_FORMAT_WITH_MILLISECONDS,
45            DateTimeFormat::Seconds => TIME_ONLY_FORMAT_WITHOUT_MILLISECONDS,
46        }
47    }
48}
49
50impl std::convert::TryFrom<String> for DateTimeFormat {
51    type Error = &'static str;
52
53    fn try_from(value: String) -> Result<Self, Self::Error> {
54        match value.as_str() {
55            "Nanoseconds" => Ok(Self::Nanoseconds),
56            "Microseconds" => Ok(Self::Microseconds),
57            "Milliseconds" => Ok(Self::Milliseconds),
58            "Seconds" => Ok(Self::Seconds),
59            _ => Err("Valid format is ... TODO")
60        }
61    }
62}
63
64use chrono::{DateTime as ChronoDateTime, TimeZone, Utc, NaiveDateTime, NaiveDate, NaiveTime, Local};
65
66use crate::field_map::FieldValue;
67use crate::fields::converters::TryFrom;
68use crate::fields::ConversionError;
69
70use super::IntoBytes;
71
72impl<'a> TryFrom<&'a FieldValue> for ChronoDateTime<Utc> {
73    type Error = ConversionError;
74
75    fn try_from(value: &'a FieldValue) -> Result<Self, Self::Error> {
76        let time: &str = TryFrom::try_from(value)?;
77        match Utc.datetime_from_str(time, DATE_TIME_FORMAT_WITHOUT_MILLISECONDS) {
78            Ok(t) => Ok(t),
79            Err(e) => match Utc.datetime_from_str(time, DATE_TIME_FORMAT_WITH_MILLISECONDS) {
80                Ok(t) => Ok(t),
81                Err(_) => todo!(),
82            },
83        }
84    }
85}
86
87pub type Date = NaiveDate;
88pub type Time = NaiveTime;
89pub type DateTime = NaiveDateTime;
90
91impl<'a> TryFrom<&'a FieldValue> for DateTime {
92    type Error = ConversionError;
93
94    fn try_from(value: &'a FieldValue) -> Result<Self, Self::Error> {
95        let time: &str = TryFrom::try_from(value)?;
96        let format = match time.len() {
97            DATE_TIME_FORMAT_WITH_NANOSECONDS_LEN => Ok(DATE_TIME_FORMAT_WITH_NANOSECONDS),
98            DATE_TIME_FORMAT_WITH_MICROSECONDS_LEN => Ok(DATE_TIME_FORMAT_WITH_MICROSECONDS),
99            DATE_TIME_FORMAT_WITH_MILLISECONDS_LEN => Ok(DATE_TIME_FORMAT_WITH_MILLISECONDS),
100            DATE_TIME_FORMAT_WITHOUT_MILLISECONDS_LEN => Ok(DATE_TIME_FORMAT_WITHOUT_MILLISECONDS),
101            len => Err(ConversionError::EncodingError),
102        }?;
103        match NaiveDateTime::parse_from_str(time, format) {
104            Ok(v) => Ok(v),
105            Err(e) => todo!("{e}"),
106        }
107    }
108}
109
110impl<'a> TryFrom<&'a FieldValue> for Time {
111    type Error = ConversionError;
112
113    fn try_from(value: &'a FieldValue) -> Result<Self, Self::Error> {
114        todo!()
115    }
116}
117
118impl<'a> TryFrom<&'a FieldValue> for Date {
119    type Error = ConversionError;
120
121    fn try_from(value: &'a FieldValue) -> Result<Self, Self::Error> {
122        todo!()
123    }
124}
125
126impl IntoBytes<FieldValue> for DateTime {
127    fn as_bytes(&self) -> FieldValue {
128        todo!()
129    }
130}
131
132impl IntoBytes<FieldValue> for Date {
133    fn as_bytes(&self) -> FieldValue {
134        todo!()
135    }
136}
137
138impl IntoBytes<FieldValue> for Time {
139    fn as_bytes(&self) -> FieldValue {
140        todo!()
141    }
142}