Skip to main content

fmi_schema/
date_time.rs

1//! DateTime support for FMI schema.
2
3/// A wrapper around `chrono::DateTime` that implements `FromStr` for `xsd:dateTime`.
4#[derive(Debug, Clone, PartialEq)]
5pub struct DateTime(chrono::DateTime<chrono::FixedOffset>);
6
7impl std::fmt::Display for DateTime {
8    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
9        self.0.to_rfc3339().fmt(f)
10    }
11}
12
13impl std::str::FromStr for DateTime {
14    type Err = chrono::format::ParseError;
15
16    // Note:
17    // `parse_from_rfc3339` parses an RFC 3339 and ISO 8601 date and time string.
18    // XSD follows ISO 8601, which allows no time zone at the end of literal.
19    // Since RFC 3339 does not allow such behavior, the function tries to add
20    // 'Z' (which equals "+00:00") in case there is no timezone provided.
21    fn from_str(s: &str) -> Result<Self, Self::Err> {
22        let tz_provided = s.ends_with('Z') || s.contains('+') || s.matches('-').count() == 3;
23        let s_with_timezone = if tz_provided {
24            s.to_string()
25        } else {
26            format!("{s}Z")
27        };
28        match chrono::DateTime::parse_from_rfc3339(&s_with_timezone) {
29            Ok(cdt) => Ok(DateTime(cdt)),
30            Err(err) => Err(err),
31        }
32    }
33}