1use std::fmt::{Display, Formatter};
2use std::str::FromStr;
3use chrono::{FixedOffset, Local};
4use crate::error::FhirError;
5
6#[derive(Clone, Debug)]
7pub struct Date(chrono::NaiveDate, usize);
8
9impl From<chrono::DateTime<Local>> for Date {
10 fn from(value: chrono::DateTime<Local>) -> Self {
11 Self(value.date_naive(), 10)
12 }
13}
14
15impl FromStr for Date {
16 type Err = FhirError;
17
18 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
19 let precision = s.len();
20 let val = match precision {
21 4 => {format!("{}-01-01", s)},
22 7 => {format!("{}-01", s)},
23 10 => {format!("{}", s)},
24 _ => {return Err(FhirError::error("错误的日期格式,只接受YYYY,YYYY-MM,YYYY-MM-DD三种格式"));}
25 };
26 let val = chrono::NaiveDate::from_str(val.as_str())?;
27 Ok(Date(val, precision))
28 }
29}
30
31impl Display for Date {
32 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
33 match self.1 {
34 4 => {write!(f, "{}", self.0.format("%Y"))},
35 7 => {write!(f, "{}", self.0.format("%Y-%m"))},
36 10 => {write!(f, "{}", self.0.format("%Y-%m-%d"))},
37 _ => {write!(f, "Error")}
38 }
39 }
40}
41
42#[derive(Clone, Debug)]
43pub struct Time(chrono::NaiveTime, usize);
44
45impl From<chrono::DateTime<Local>> for Time {
46 fn from(value: chrono::DateTime<Local>) -> Self {
47 Self(value.time(), 12)
48 }
49}
50
51impl Display for Time {
52 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
53 match self.1 {
54 8 => {write!(f, "{}", self.0.format("%H:%M:%S"))},
55 12 => {write!(f, "{}", self.0.format("%H:%M:%S.%3f"))},
56 _ => {write!(f, "Error")}
57 }
58 }
59}
60
61impl FromStr for Time {
62 type Err = FhirError;
63
64 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
65 let precision = s.len();
66 let val = match precision {
67 8 => {chrono::NaiveTime::parse_from_str(s, "%H:%M:%S")?},
68 12 => {chrono::NaiveTime::parse_from_str(s, "%H:%M:%S.%3f")?},
69 _ => {return Err(FhirError::error("错误的时间格式,只接受HH::MM::SS,HH:MM:SS.sss两种格式"));}
70 };
71 Ok(Time(val, precision))
72 }
73}
74
75#[derive(Clone, Debug)]
87pub struct DateTime(chrono::DateTime<FixedOffset>, usize);
88
89impl From<chrono::DateTime<Local>> for DateTime {
90 fn from(value: chrono::DateTime<Local>) -> Self {
91 Self(value.into(), 29)
92 }
93}
94
95impl Display for DateTime {
96 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
97 match self.1 {
98 4 => {write!(f, "{}", self.0.format("%Y"))},
99 7 => {write!(f, "{}", self.0.format("%Y-%m"))},
100 10 => {write!(f, "{}", self.0.format("%Y-%m-%d"))},
101 20|25 => {write!(f, "{}", self.0.format("%Y-%m-%dT%H:%M:%S%:z"))},
102 24|29 => {write!(f, "{}", self.0.format("%Y-%m-%dT%H:%M:%S.%3f%:z"))},
103 _ => {write!(f, "Error")}
104 }
105 }
106}
107
108impl FromStr for DateTime {
109 type Err = FhirError;
110
111 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
112 let pattern = "0000-01-01T00:00:00.000Z";
113 let precision = s.len();
114 let val = match precision {
115 4|7|10|24 => {
116 let dt = format!("{}{}", s, &pattern[precision..]);
117 chrono::DateTime::<chrono::Local>::from_str(dt.as_str())?.into()
118 },
119 20 => {
120 let dt = format!("{}{}", &s[0..precision-1], &pattern[precision-1..]);
121 chrono::DateTime::<chrono::Local>::from_str(dt.as_str())?.into()
122 },
123 25|29 => {
124 chrono::DateTime::from_str(s)?
125 },
126 _ => {return Err(FhirError::error("错误的时间格式,只接受FHIR规范约定的日期时间格式"));}
127 };
128 Ok(DateTime(val, precision))
129 }
130}
131
132#[derive(Clone, Debug)]
147pub struct Instant(chrono::DateTime<FixedOffset>, usize);
148
149impl From<chrono::DateTime<Local>> for Instant {
150 fn from(value: chrono::DateTime<Local>) -> Self {
151 Self(value.into(), 29)
152 }
153}
154
155impl Display for Instant {
156 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
157 match self.1 {
158 20|25 => {write!(f, "{}", self.0.format("%Y-%m-%dT%H:%M:%S%:z"))},
159 24|29 => {write!(f, "{}", self.0.format("%Y-%m-%dT%H:%M:%S.%3f%:z"))},
160 _ => {write!(f, "Error")}
161 }
162 }
163}
164
165impl FromStr for Instant {
166 type Err = FhirError;
167
168 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
169 let precision = s.len();
170 let val = match precision {
171 20|24 => {
172 chrono::DateTime::<chrono::Local>::from_str(s)?.into()
173 },
174 25|29 => {
175 chrono::DateTime::from_str(s)?
176 },
177 _ => {return Err(FhirError::error("错误的时间格式,只接受FHIR规范约定的日期时间格式"));}
178 };
179 Ok(Instant(val, precision))
180 }
181}
182
183#[test]
184fn test_datetime() -> crate::prelude::Result<()> {
185 let d1 = Date::from(Local::now());
186 println!("Date: {}", d1.to_string());
187
188 let t1 = Time::from(Local::now());
189 println!("Time: {}", t1.to_string());
190
191 let local = Local::now();
192
193 let dt1 = DateTime::from(local);
194 println!("DateTime: {}", dt1.to_string());
195
196 let instance = Instant::from(local);
197 println!("Instant: {}", instance.to_string());
198
199 Ok(())
200}