Skip to main content

serde_with/
chrono_0_4.rs

1//! De/Serialization of [chrono] types
2//!
3//! This modules is only available if using the `chrono_0_4` feature of the crate.
4//!
5//! [chrono]: https://docs.rs/chrono/
6
7// Serialization of large numbers can result in overflows
8// The time calculations are prone to this, so lint here extra
9// https://github.com/jonasbb/serde_with/issues/771
10#![warn(clippy::as_conversions)]
11
12use crate::{
13    formats::{Flexible, Format, Strict, Strictness},
14    prelude::*,
15};
16#[cfg(feature = "std")]
17use ::chrono_0_4::Local;
18use ::chrono_0_4::{DateTime, Duration, NaiveDateTime, TimeZone, Utc};
19
20/// Create a [`DateTime`] for the Unix Epoch using the [`Utc`] timezone
21fn unix_epoch_utc() -> DateTime<Utc> {
22    Utc.from_utc_datetime(&unix_epoch_naive())
23}
24
25/// Create a [`DateTime`] for the Unix Epoch using the [`Local`] timezone
26#[cfg(feature = "std")]
27fn unix_epoch_local() -> DateTime<Local> {
28    Local.from_utc_datetime(&unix_epoch_naive())
29}
30
31/// Create a [`NaiveDateTime`] for the Unix Epoch
32fn unix_epoch_naive() -> NaiveDateTime {
33    DateTime::from_timestamp(0, 0).unwrap().naive_utc()
34}
35
36/// Deserialize a Unix timestamp with optional sub-second precision into a `DateTime<Utc>`.
37///
38/// The `DateTime<Utc>` can be serialized from an integer, a float, or a string representing a number.
39///
40/// # Examples
41///
42/// ```
43/// # use chrono_0_4::{DateTime, Utc};
44/// # use serde::Deserialize;
45/// #
46/// #[derive(Debug, Deserialize)]
47/// struct S {
48///     #[serde(with = "serde_with::chrono_0_4::datetime_utc_ts_seconds_from_any")]
49///     date: DateTime<Utc>,
50/// }
51///
52/// // Deserializes integers
53/// assert!(serde_json::from_str::<S>(r#"{ "date": 1478563200 }"#).is_ok());
54/// # // Ensure the date field is not dead code
55/// # assert_eq!(serde_json::from_str::<S>(r#"{ "date": 1478563200 }"#).unwrap().date.timestamp(), 1478563200);
56/// // floats
57/// assert!(serde_json::from_str::<S>(r#"{ "date": 1478563200.123 }"#).is_ok());
58/// // and strings with numbers, for high-precision values
59/// assert!(serde_json::from_str::<S>(r#"{ "date": "1478563200.123" }"#).is_ok());
60/// ```
61// Requires float operations from std
62#[cfg(feature = "std")]
63pub mod datetime_utc_ts_seconds_from_any {
64    use super::*;
65
66    /// Deserialize a Unix timestamp with optional subsecond precision into a `DateTime<Utc>`.
67    pub fn deserialize<'de, D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
68    where
69        D: Deserializer<'de>,
70    {
71        struct Helper;
72        impl Visitor<'_> for Helper {
73            type Value = DateTime<Utc>;
74
75            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
76                formatter
77                    .write_str("an integer, float, or string with optional subsecond precision.")
78            }
79
80            fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
81            where
82                E: DeError,
83            {
84                DateTime::from_timestamp(value, 0).ok_or_else(|| {
85                    DeError::custom(format_args!("a timestamp which can be represented in a DateTime but received \'{0}\'",
    value)format_args!(
86                        "a timestamp which can be represented in a DateTime but received '{value}'"
87                    ))
88                })
89            }
90
91            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
92            where
93                E: DeError,
94            {
95                let value = i64::try_from(value).map_err(|_| {
96                    DeError::custom(format_args!("a timestamp which can be represented in a DateTime but received \'{0}\'",
    value)format_args!(
97                        "a timestamp which can be represented in a DateTime but received '{value}'"
98                    ))
99                })?;
100                DateTime::from_timestamp(value, 0).ok_or_else(|| {
101                    DeError::custom(format_args!("a timestamp which can be represented in a DateTime but received \'{0}\'",
    value)format_args!(
102                        "a timestamp which can be represented in a DateTime but received '{value}'"
103                    ))
104                })
105            }
106
107            // as conversions are necessary for floats
108            #[allow(clippy::as_conversions)]
109            fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
110            where
111                E: DeError,
112            {
113                let seconds = value.trunc() as i64;
114                let nsecs = (value.fract() * 1_000_000_000_f64).abs() as u32;
115                DateTime::from_timestamp(seconds, nsecs).ok_or_else(|| {
116                    DeError::custom(format_args!("a timestamp which can be represented in a DateTime but received \'{0}\'",
    value)format_args!(
117                        "a timestamp which can be represented in a DateTime but received '{value}'"
118                    ))
119                })
120            }
121
122            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
123            where
124                E: DeError,
125            {
126                let parts: Vec<_> = value.split('.').collect();
127
128                match *parts.as_slice() {
129                    [seconds] => {
130                        if let Ok(seconds) = seconds.parse() {
131                            DateTime::from_timestamp(seconds, 0).ok_or_else(|| {
132                                DeError::custom(format_args!("a timestamp which can be represented in a DateTime but received \'{0}\'",
    value)format_args!(
133                                    "a timestamp which can be represented in a DateTime but received '{value}'"
134                                ))
135                            })
136                        } else {
137                            Err(DeError::invalid_value(Unexpected::Str(value), &self))
138                        }
139                    }
140                    [seconds, subseconds] => {
141                        if let Ok(seconds) = seconds.parse() {
142                            let subseclen =
143                            match u32::try_from(subseconds.chars().count()) {
144                                Ok(subseclen) if subseclen <= 9 => subseclen,
145                                _ =>    return Err(DeError::custom(format_args!("DateTimes only support nanosecond precision but \'{0}\' has more than 9 digits.",
    value)format_args!(
146                                    "DateTimes only support nanosecond precision but '{value}' has more than 9 digits."
147                                ))),
148                            };
149
150                            if let Ok(mut subseconds) = subseconds.parse() {
151                                // convert subseconds to nanoseconds (10^-9), require 9 places for nanoseconds
152                                subseconds *= 10u32.pow(9 - subseclen);
153                                DateTime::from_timestamp(seconds, subseconds).ok_or_else(|| {
154                                    DeError::custom(format_args!("a timestamp which can be represented in a DateTime but received \'{0}\'",
    value)format_args!(
155                                        "a timestamp which can be represented in a DateTime but received '{value}'"
156                                    ))
157                                })
158                            } else {
159                                Err(DeError::invalid_value(Unexpected::Str(value), &self))
160                            }
161                        } else {
162                            Err(DeError::invalid_value(Unexpected::Str(value), &self))
163                        }
164                    }
165
166                    _ => Err(DeError::invalid_value(Unexpected::Str(value), &self)),
167                }
168            }
169        }
170
171        deserializer.deserialize_any(Helper)
172    }
173}
174
175impl SerializeAs<NaiveDateTime> for DateTime<Utc> {
176    fn serialize_as<S>(source: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
177    where
178        S: Serializer,
179    {
180        let datetime = Utc.from_utc_datetime(source);
181        datetime.serialize(serializer)
182    }
183}
184
185impl<'de> DeserializeAs<'de, NaiveDateTime> for DateTime<Utc> {
186    fn deserialize_as<D>(deserializer: D) -> Result<NaiveDateTime, D::Error>
187    where
188        D: Deserializer<'de>,
189    {
190        DateTime::<Utc>::deserialize(deserializer).map(|datetime| datetime.naive_utc())
191    }
192}
193
194/// Convert a [`chrono_0_4::Duration`] into a [`DurationSigned`]
195fn duration_into_duration_signed(dur: &Duration) -> DurationSigned {
196    match dur.to_std() {
197        Ok(dur) => DurationSigned::with_duration(Sign::Positive, dur),
198        Err(_) => {
199            if let Ok(dur) = (-*dur).to_std() {
200                DurationSigned::with_duration(Sign::Negative, dur)
201            } else {
202                {
    ::core::panicking::panic_fmt(format_args!("A chrono Duration should be convertible to a DurationSigned"));
}panic!("A chrono Duration should be convertible to a DurationSigned")
203            }
204        }
205    }
206}
207
208/// Convert a [`DurationSigned`] into a [`chrono_0_4::Duration`]
209fn duration_from_duration_signed<'de, D>(dur: DurationSigned) -> Result<Duration, D::Error>
210where
211    D: Deserializer<'de>,
212{
213    let mut chrono_dur = match Duration::from_std(dur.duration) {
214        Ok(dur) => dur,
215        Err(msg) => {
216            return Err(DeError::custom(format_args!("Duration is outside of the representable range: {0}", msg)format_args!(
217                "Duration is outside of the representable range: {msg}"
218            )))
219        }
220    };
221    if dur.sign.is_negative() {
222        chrono_dur = -chrono_dur;
223    }
224    Ok(chrono_dur)
225}
226
227macro_rules! use_duration_signed_ser {
228    (
229        $main_trait:ident $internal_trait:ident =>
230        {
231            $ty:ty; $converter:ident =>
232            $({
233                $format:ty, $strictness:ty =>
234                $($tbound:ident: $bound:ident $(,)?)*
235            })*
236        }
237    ) => {
238        $(
239            impl<$($tbound ,)*> SerializeAs<$ty> for $main_trait<$format, $strictness>
240            where
241                $($tbound: $bound,)*
242            {
243                fn serialize_as<S>(source: &$ty, serializer: S) -> Result<S::Ok, S::Error>
244                where
245                    S: Serializer,
246                {
247                    let dur: DurationSigned = $converter(source);
248                    $internal_trait::<$format, $strictness>::serialize_as(
249                        &dur,
250                        serializer,
251                    )
252                }
253            }
254        )*
255    };
256    (
257        $( $main_trait:ident $internal_trait:ident, )+ => $rest:tt
258    ) => {
259        $( use_duration_signed_ser!($main_trait $internal_trait => $rest); )+
260    };
261}
262
263fn datetime_to_duration<TZ>(source: &DateTime<TZ>) -> DurationSigned
264where
265    TZ: TimeZone,
266{
267    duration_into_duration_signed(&source.clone().signed_duration_since(unix_epoch_utc()))
268}
269
270fn naive_datetime_to_duration(source: &NaiveDateTime) -> DurationSigned {
271    duration_into_duration_signed(&source.signed_duration_since(unix_epoch_naive()))
272}
273
274impl<STRICTNESS> SerializeAs<Duration> for
    DurationNanoSeconds<f64, STRICTNESS> where STRICTNESS: Strictness {
    fn serialize_as<S>(source: &Duration, serializer: S)
        -> Result<S::Ok, S::Error> where S: Serializer {
        let dur: DurationSigned = duration_into_duration_signed(source);
        DurationNanoSeconds::<f64, STRICTNESS>::serialize_as(&dur, serializer)
    }
}use_duration_signed_ser!(
275    DurationSeconds DurationSeconds,
276    DurationMilliSeconds DurationMilliSeconds,
277    DurationMicroSeconds DurationMicroSeconds,
278    DurationNanoSeconds DurationNanoSeconds,
279    => {
280        Duration; duration_into_duration_signed =>
281        {i64, STRICTNESS => STRICTNESS: Strictness}
282        {f64, STRICTNESS => STRICTNESS: Strictness}
283    }
284);
285#[cfg(feature = "alloc")]
286impl<STRICTNESS> SerializeAs<Duration> for
    DurationNanoSeconds<String, STRICTNESS> where STRICTNESS: Strictness {
    fn serialize_as<S>(source: &Duration, serializer: S)
        -> Result<S::Ok, S::Error> where S: Serializer {
        let dur: DurationSigned = duration_into_duration_signed(source);
        DurationNanoSeconds::<String,
                STRICTNESS>::serialize_as(&dur, serializer)
    }
}use_duration_signed_ser!(
287    DurationSeconds DurationSeconds,
288    DurationMilliSeconds DurationMilliSeconds,
289    DurationMicroSeconds DurationMicroSeconds,
290    DurationNanoSeconds DurationNanoSeconds,
291    => {
292        Duration; duration_into_duration_signed =>
293        {String, STRICTNESS => STRICTNESS: Strictness}
294    }
295);
296impl<TZ, STRICTNESS> SerializeAs<DateTime<TZ>> for
    TimestampNanoSeconds<f64, STRICTNESS> where TZ: TimeZone,
    STRICTNESS: Strictness {
    fn serialize_as<S>(source: &DateTime<TZ>, serializer: S)
        -> Result<S::Ok, S::Error> where S: Serializer {
        let dur: DurationSigned = datetime_to_duration(source);
        DurationNanoSeconds::<f64, STRICTNESS>::serialize_as(&dur, serializer)
    }
}use_duration_signed_ser!(
297    TimestampSeconds DurationSeconds,
298    TimestampMilliSeconds DurationMilliSeconds,
299    TimestampMicroSeconds DurationMicroSeconds,
300    TimestampNanoSeconds DurationNanoSeconds,
301    => {
302        DateTime<TZ>; datetime_to_duration =>
303        {i64, STRICTNESS => TZ: TimeZone, STRICTNESS: Strictness}
304        {f64, STRICTNESS => TZ: TimeZone, STRICTNESS: Strictness}
305    }
306);
307#[cfg(feature = "alloc")]
308impl<TZ, STRICTNESS> SerializeAs<DateTime<TZ>> for
    TimestampNanoSeconds<String, STRICTNESS> where TZ: TimeZone,
    STRICTNESS: Strictness {
    fn serialize_as<S>(source: &DateTime<TZ>, serializer: S)
        -> Result<S::Ok, S::Error> where S: Serializer {
        let dur: DurationSigned = datetime_to_duration(source);
        DurationNanoSeconds::<String,
                STRICTNESS>::serialize_as(&dur, serializer)
    }
}use_duration_signed_ser!(
309    TimestampSeconds DurationSeconds,
310    TimestampMilliSeconds DurationMilliSeconds,
311    TimestampMicroSeconds DurationMicroSeconds,
312    TimestampNanoSeconds DurationNanoSeconds,
313    => {
314        DateTime<TZ>; datetime_to_duration =>
315        {String, STRICTNESS => TZ: TimeZone, STRICTNESS: Strictness}
316    }
317);
318impl<STRICTNESS> SerializeAs<NaiveDateTime> for
    TimestampNanoSeconds<f64, STRICTNESS> where STRICTNESS: Strictness {
    fn serialize_as<S>(source: &NaiveDateTime, serializer: S)
        -> Result<S::Ok, S::Error> where S: Serializer {
        let dur: DurationSigned = naive_datetime_to_duration(source);
        DurationNanoSeconds::<f64, STRICTNESS>::serialize_as(&dur, serializer)
    }
}use_duration_signed_ser!(
319    TimestampSeconds DurationSeconds,
320    TimestampMilliSeconds DurationMilliSeconds,
321    TimestampMicroSeconds DurationMicroSeconds,
322    TimestampNanoSeconds DurationNanoSeconds,
323    => {
324        NaiveDateTime; naive_datetime_to_duration =>
325        {i64, STRICTNESS => STRICTNESS: Strictness}
326        {f64, STRICTNESS => STRICTNESS: Strictness}
327    }
328);
329#[cfg(feature = "alloc")]
330impl<STRICTNESS> SerializeAs<NaiveDateTime> for
    TimestampNanoSeconds<String, STRICTNESS> where STRICTNESS: Strictness {
    fn serialize_as<S>(source: &NaiveDateTime, serializer: S)
        -> Result<S::Ok, S::Error> where S: Serializer {
        let dur: DurationSigned = naive_datetime_to_duration(source);
        DurationNanoSeconds::<String,
                STRICTNESS>::serialize_as(&dur, serializer)
    }
}use_duration_signed_ser!(
331    TimestampSeconds DurationSeconds,
332    TimestampMilliSeconds DurationMilliSeconds,
333    TimestampMicroSeconds DurationMicroSeconds,
334    TimestampNanoSeconds DurationNanoSeconds,
335    => {
336        NaiveDateTime; naive_datetime_to_duration =>
337        {String, STRICTNESS => STRICTNESS: Strictness}
338    }
339);
340
341// Duration/Timestamp WITH FRACTIONS
342impl<STRICTNESS> SerializeAs<Duration> for
    DurationNanoSecondsWithFrac<f64, STRICTNESS> where STRICTNESS: Strictness
    {
    fn serialize_as<S>(source: &Duration, serializer: S)
        -> Result<S::Ok, S::Error> where S: Serializer {
        let dur: DurationSigned = duration_into_duration_signed(source);
        DurationNanoSecondsWithFrac::<f64,
                STRICTNESS>::serialize_as(&dur, serializer)
    }
}use_duration_signed_ser!(
343    DurationSecondsWithFrac DurationSecondsWithFrac,
344    DurationMilliSecondsWithFrac DurationMilliSecondsWithFrac,
345    DurationMicroSecondsWithFrac DurationMicroSecondsWithFrac,
346    DurationNanoSecondsWithFrac DurationNanoSecondsWithFrac,
347    => {
348        Duration; duration_into_duration_signed =>
349        {f64, STRICTNESS => STRICTNESS: Strictness}
350    }
351);
352#[cfg(feature = "alloc")]
353impl<STRICTNESS> SerializeAs<Duration> for
    DurationNanoSecondsWithFrac<String, STRICTNESS> where
    STRICTNESS: Strictness {
    fn serialize_as<S>(source: &Duration, serializer: S)
        -> Result<S::Ok, S::Error> where S: Serializer {
        let dur: DurationSigned = duration_into_duration_signed(source);
        DurationNanoSecondsWithFrac::<String,
                STRICTNESS>::serialize_as(&dur, serializer)
    }
}use_duration_signed_ser!(
354    DurationSecondsWithFrac DurationSecondsWithFrac,
355    DurationMilliSecondsWithFrac DurationMilliSecondsWithFrac,
356    DurationMicroSecondsWithFrac DurationMicroSecondsWithFrac,
357    DurationNanoSecondsWithFrac DurationNanoSecondsWithFrac,
358    => {
359        Duration; duration_into_duration_signed =>
360        {String, STRICTNESS => STRICTNESS: Strictness}
361    }
362);
363impl<TZ, STRICTNESS> SerializeAs<DateTime<TZ>> for
    TimestampNanoSecondsWithFrac<f64, STRICTNESS> where TZ: TimeZone,
    STRICTNESS: Strictness {
    fn serialize_as<S>(source: &DateTime<TZ>, serializer: S)
        -> Result<S::Ok, S::Error> where S: Serializer {
        let dur: DurationSigned = datetime_to_duration(source);
        DurationNanoSecondsWithFrac::<f64,
                STRICTNESS>::serialize_as(&dur, serializer)
    }
}use_duration_signed_ser!(
364    TimestampSecondsWithFrac DurationSecondsWithFrac,
365    TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
366    TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
367    TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
368    => {
369        DateTime<TZ>; datetime_to_duration =>
370        {f64, STRICTNESS => TZ: TimeZone, STRICTNESS: Strictness}
371    }
372);
373#[cfg(feature = "alloc")]
374impl<TZ, STRICTNESS> SerializeAs<DateTime<TZ>> for
    TimestampNanoSecondsWithFrac<String, STRICTNESS> where TZ: TimeZone,
    STRICTNESS: Strictness {
    fn serialize_as<S>(source: &DateTime<TZ>, serializer: S)
        -> Result<S::Ok, S::Error> where S: Serializer {
        let dur: DurationSigned = datetime_to_duration(source);
        DurationNanoSecondsWithFrac::<String,
                STRICTNESS>::serialize_as(&dur, serializer)
    }
}use_duration_signed_ser!(
375    TimestampSecondsWithFrac DurationSecondsWithFrac,
376    TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
377    TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
378    TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
379    => {
380        DateTime<TZ>; datetime_to_duration =>
381        {String, STRICTNESS => TZ: TimeZone, STRICTNESS: Strictness}
382    }
383);
384impl<STRICTNESS> SerializeAs<NaiveDateTime> for
    TimestampNanoSecondsWithFrac<f64, STRICTNESS> where STRICTNESS: Strictness
    {
    fn serialize_as<S>(source: &NaiveDateTime, serializer: S)
        -> Result<S::Ok, S::Error> where S: Serializer {
        let dur: DurationSigned = naive_datetime_to_duration(source);
        DurationNanoSecondsWithFrac::<f64,
                STRICTNESS>::serialize_as(&dur, serializer)
    }
}use_duration_signed_ser!(
385    TimestampSecondsWithFrac DurationSecondsWithFrac,
386    TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
387    TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
388    TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
389    => {
390        NaiveDateTime; naive_datetime_to_duration =>
391        {f64, STRICTNESS => STRICTNESS: Strictness}
392    }
393);
394#[cfg(feature = "alloc")]
395impl<STRICTNESS> SerializeAs<NaiveDateTime> for
    TimestampNanoSecondsWithFrac<String, STRICTNESS> where
    STRICTNESS: Strictness {
    fn serialize_as<S>(source: &NaiveDateTime, serializer: S)
        -> Result<S::Ok, S::Error> where S: Serializer {
        let dur: DurationSigned = naive_datetime_to_duration(source);
        DurationNanoSecondsWithFrac::<String,
                STRICTNESS>::serialize_as(&dur, serializer)
    }
}use_duration_signed_ser!(
396    TimestampSecondsWithFrac DurationSecondsWithFrac,
397    TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
398    TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
399    TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
400    => {
401        NaiveDateTime; naive_datetime_to_duration =>
402        {String, STRICTNESS => STRICTNESS: Strictness}
403    }
404);
405
406macro_rules! use_duration_signed_de {
407    (
408        $main_trait:ident $internal_trait:ident =>
409        {
410            $ty:ty; $converter:ident =>
411            $({
412                $format:ty, $strictness:ty =>
413                $($tbound:ident: $bound:ident)*
414            })*
415        }
416    ) =>{
417        $(
418            impl<'de, $($tbound,)*> DeserializeAs<'de, $ty> for $main_trait<$format, $strictness>
419            where
420                $($tbound: $bound,)*
421            {
422                fn deserialize_as<D>(deserializer: D) -> Result<$ty, D::Error>
423                where
424                    D: Deserializer<'de>,
425                {
426                    let dur: DurationSigned = $internal_trait::<$format, $strictness>::deserialize_as(deserializer)?;
427                    $converter::<D>(dur)
428                }
429            }
430        )*
431    };
432    (
433        $( $main_trait:ident $internal_trait:ident, )+ => $rest:tt
434    ) => {
435        $( use_duration_signed_de!($main_trait $internal_trait => $rest); )+
436    };
437}
438
439fn duration_to_datetime_utc<'de, D>(dur: DurationSigned) -> Result<DateTime<Utc>, D::Error>
440where
441    D: Deserializer<'de>,
442{
443    Ok(unix_epoch_utc() + duration_from_duration_signed::<D>(dur)?)
444}
445
446#[cfg(feature = "std")]
447fn duration_to_datetime_local<'de, D>(dur: DurationSigned) -> Result<DateTime<Local>, D::Error>
448where
449    D: Deserializer<'de>,
450{
451    Ok(unix_epoch_local() + duration_from_duration_signed::<D>(dur)?)
452}
453
454fn duration_to_naive_datetime<'de, D>(dur: DurationSigned) -> Result<NaiveDateTime, D::Error>
455where
456    D: Deserializer<'de>,
457{
458    Ok(unix_epoch_naive() + duration_from_duration_signed::<D>(dur)?)
459}
460
461// No subsecond precision
462impl<'de, FORMAT> DeserializeAs<'de, Duration> for
    DurationNanoSeconds<FORMAT, Flexible> where FORMAT: Format {
    fn deserialize_as<D>(deserializer: D) -> Result<Duration, D::Error> where
        D: Deserializer<'de> {
        let dur: DurationSigned =
            DurationNanoSeconds::<FORMAT,
                        Flexible>::deserialize_as(deserializer)?;
        duration_from_duration_signed::<D>(dur)
    }
}use_duration_signed_de!(
463    DurationSeconds DurationSeconds,
464    DurationMilliSeconds DurationMilliSeconds,
465    DurationMicroSeconds DurationMicroSeconds,
466    DurationNanoSeconds DurationNanoSeconds,
467    => {
468        Duration; duration_from_duration_signed =>
469        {i64, Strict =>}
470        {FORMAT, Flexible => FORMAT: Format}
471    }
472);
473#[cfg(feature = "alloc")]
474impl<'de> DeserializeAs<'de, Duration> for DurationNanoSeconds<String, Strict>
    where  {
    fn deserialize_as<D>(deserializer: D) -> Result<Duration, D::Error> where
        D: Deserializer<'de> {
        let dur: DurationSigned =
            DurationNanoSeconds::<String,
                        Strict>::deserialize_as(deserializer)?;
        duration_from_duration_signed::<D>(dur)
    }
}use_duration_signed_de!(
475    DurationSeconds DurationSeconds,
476    DurationMilliSeconds DurationMilliSeconds,
477    DurationMicroSeconds DurationMicroSeconds,
478    DurationNanoSeconds DurationNanoSeconds,
479    => {
480        Duration; duration_from_duration_signed =>
481        {String, Strict =>}
482    }
483);
484#[cfg(feature = "std")]
485impl<'de> DeserializeAs<'de, Duration> for DurationNanoSeconds<f64, Strict>
    where  {
    fn deserialize_as<D>(deserializer: D) -> Result<Duration, D::Error> where
        D: Deserializer<'de> {
        let dur: DurationSigned =
            DurationNanoSeconds::<f64, Strict>::deserialize_as(deserializer)?;
        duration_from_duration_signed::<D>(dur)
    }
}use_duration_signed_de!(
486    DurationSeconds DurationSeconds,
487    DurationMilliSeconds DurationMilliSeconds,
488    DurationMicroSeconds DurationMicroSeconds,
489    DurationNanoSeconds DurationNanoSeconds,
490    => {
491        Duration; duration_from_duration_signed =>
492        {f64, Strict =>}
493    }
494);
495impl<'de, FORMAT> DeserializeAs<'de, DateTime<Utc>> for
    TimestampNanoSeconds<FORMAT, Flexible> where FORMAT: Format {
    fn deserialize_as<D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
        where D: Deserializer<'de> {
        let dur: DurationSigned =
            DurationNanoSeconds::<FORMAT,
                        Flexible>::deserialize_as(deserializer)?;
        duration_to_datetime_utc::<D>(dur)
    }
}use_duration_signed_de!(
496    TimestampSeconds DurationSeconds,
497    TimestampMilliSeconds DurationMilliSeconds,
498    TimestampMicroSeconds DurationMicroSeconds,
499    TimestampNanoSeconds DurationNanoSeconds,
500    => {
501        DateTime<Utc>; duration_to_datetime_utc =>
502        {i64, Strict =>}
503        {FORMAT, Flexible => FORMAT: Format}
504    }
505);
506#[cfg(feature = "alloc")]
507impl<'de> DeserializeAs<'de, DateTime<Utc>> for
    TimestampNanoSeconds<String, Strict> where  {
    fn deserialize_as<D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
        where D: Deserializer<'de> {
        let dur: DurationSigned =
            DurationNanoSeconds::<String,
                        Strict>::deserialize_as(deserializer)?;
        duration_to_datetime_utc::<D>(dur)
    }
}use_duration_signed_de!(
508    TimestampSeconds DurationSeconds,
509    TimestampMilliSeconds DurationMilliSeconds,
510    TimestampMicroSeconds DurationMicroSeconds,
511    TimestampNanoSeconds DurationNanoSeconds,
512    => {
513        DateTime<Utc>; duration_to_datetime_utc =>
514        {String, Strict =>}
515    }
516);
517#[cfg(feature = "std")]
518impl<'de> DeserializeAs<'de, DateTime<Utc>> for
    TimestampNanoSeconds<f64, Strict> where  {
    fn deserialize_as<D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
        where D: Deserializer<'de> {
        let dur: DurationSigned =
            DurationNanoSeconds::<f64, Strict>::deserialize_as(deserializer)?;
        duration_to_datetime_utc::<D>(dur)
    }
}use_duration_signed_de!(
519    TimestampSeconds DurationSeconds,
520    TimestampMilliSeconds DurationMilliSeconds,
521    TimestampMicroSeconds DurationMicroSeconds,
522    TimestampNanoSeconds DurationNanoSeconds,
523    => {
524        DateTime<Utc>; duration_to_datetime_utc =>
525        {f64, Strict =>}
526    }
527);
528#[cfg(feature = "std")]
529impl<'de, FORMAT> DeserializeAs<'de, DateTime<Local>> for
    TimestampNanoSeconds<FORMAT, Flexible> where FORMAT: Format {
    fn deserialize_as<D>(deserializer: D) -> Result<DateTime<Local>, D::Error>
        where D: Deserializer<'de> {
        let dur: DurationSigned =
            DurationNanoSeconds::<FORMAT,
                        Flexible>::deserialize_as(deserializer)?;
        duration_to_datetime_local::<D>(dur)
    }
}use_duration_signed_de!(
530    TimestampSeconds DurationSeconds,
531    TimestampMilliSeconds DurationMilliSeconds,
532    TimestampMicroSeconds DurationMicroSeconds,
533    TimestampNanoSeconds DurationNanoSeconds,
534    => {
535        DateTime<Local>; duration_to_datetime_local =>
536        {i64, Strict =>}
537        {f64, Strict =>}
538        {String, Strict =>}
539        {FORMAT, Flexible => FORMAT: Format}
540    }
541);
542impl<'de, FORMAT> DeserializeAs<'de, NaiveDateTime> for
    TimestampNanoSeconds<FORMAT, Flexible> where FORMAT: Format {
    fn deserialize_as<D>(deserializer: D) -> Result<NaiveDateTime, D::Error>
        where D: Deserializer<'de> {
        let dur: DurationSigned =
            DurationNanoSeconds::<FORMAT,
                        Flexible>::deserialize_as(deserializer)?;
        duration_to_naive_datetime::<D>(dur)
    }
}use_duration_signed_de!(
543    TimestampSeconds DurationSeconds,
544    TimestampMilliSeconds DurationMilliSeconds,
545    TimestampMicroSeconds DurationMicroSeconds,
546    TimestampNanoSeconds DurationNanoSeconds,
547    => {
548        NaiveDateTime; duration_to_naive_datetime =>
549        {i64, Strict =>}
550        {FORMAT, Flexible => FORMAT: Format}
551    }
552);
553#[cfg(feature = "alloc")]
554impl<'de> DeserializeAs<'de, NaiveDateTime> for
    TimestampNanoSeconds<String, Strict> where  {
    fn deserialize_as<D>(deserializer: D) -> Result<NaiveDateTime, D::Error>
        where D: Deserializer<'de> {
        let dur: DurationSigned =
            DurationNanoSeconds::<String,
                        Strict>::deserialize_as(deserializer)?;
        duration_to_naive_datetime::<D>(dur)
    }
}use_duration_signed_de!(
555    TimestampSeconds DurationSeconds,
556    TimestampMilliSeconds DurationMilliSeconds,
557    TimestampMicroSeconds DurationMicroSeconds,
558    TimestampNanoSeconds DurationNanoSeconds,
559    => {
560        NaiveDateTime; duration_to_naive_datetime =>
561        {String, Strict =>}
562    }
563);
564#[cfg(feature = "std")]
565impl<'de> DeserializeAs<'de, NaiveDateTime> for
    TimestampNanoSeconds<f64, Strict> where  {
    fn deserialize_as<D>(deserializer: D) -> Result<NaiveDateTime, D::Error>
        where D: Deserializer<'de> {
        let dur: DurationSigned =
            DurationNanoSeconds::<f64, Strict>::deserialize_as(deserializer)?;
        duration_to_naive_datetime::<D>(dur)
    }
}use_duration_signed_de!(
566    TimestampSeconds DurationSeconds,
567    TimestampMilliSeconds DurationMilliSeconds,
568    TimestampMicroSeconds DurationMicroSeconds,
569    TimestampNanoSeconds DurationNanoSeconds,
570    => {
571        NaiveDateTime; duration_to_naive_datetime =>
572        {f64, Strict =>}
573    }
574);
575
576// Duration/Timestamp WITH FRACTIONS
577impl<'de, FORMAT> DeserializeAs<'de, Duration> for
    DurationNanoSecondsWithFrac<FORMAT, Flexible> where FORMAT: Format {
    fn deserialize_as<D>(deserializer: D) -> Result<Duration, D::Error> where
        D: Deserializer<'de> {
        let dur: DurationSigned =
            DurationNanoSecondsWithFrac::<FORMAT,
                        Flexible>::deserialize_as(deserializer)?;
        duration_from_duration_signed::<D>(dur)
    }
}use_duration_signed_de!(
578    DurationSecondsWithFrac DurationSecondsWithFrac,
579    DurationMilliSecondsWithFrac DurationMilliSecondsWithFrac,
580    DurationMicroSecondsWithFrac DurationMicroSecondsWithFrac,
581    DurationNanoSecondsWithFrac DurationNanoSecondsWithFrac,
582    => {
583        Duration; duration_from_duration_signed =>
584        {f64, Strict =>}
585        {FORMAT, Flexible => FORMAT: Format}
586    }
587);
588#[cfg(feature = "alloc")]
589impl<'de> DeserializeAs<'de, Duration> for
    DurationNanoSecondsWithFrac<String, Strict> where  {
    fn deserialize_as<D>(deserializer: D) -> Result<Duration, D::Error> where
        D: Deserializer<'de> {
        let dur: DurationSigned =
            DurationNanoSecondsWithFrac::<String,
                        Strict>::deserialize_as(deserializer)?;
        duration_from_duration_signed::<D>(dur)
    }
}use_duration_signed_de!(
590    DurationSecondsWithFrac DurationSecondsWithFrac,
591    DurationMilliSecondsWithFrac DurationMilliSecondsWithFrac,
592    DurationMicroSecondsWithFrac DurationMicroSecondsWithFrac,
593    DurationNanoSecondsWithFrac DurationNanoSecondsWithFrac,
594    => {
595        Duration; duration_from_duration_signed =>
596        {String, Strict =>}
597    }
598);
599impl<'de, FORMAT> DeserializeAs<'de, DateTime<Utc>> for
    TimestampNanoSecondsWithFrac<FORMAT, Flexible> where FORMAT: Format {
    fn deserialize_as<D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
        where D: Deserializer<'de> {
        let dur: DurationSigned =
            DurationNanoSecondsWithFrac::<FORMAT,
                        Flexible>::deserialize_as(deserializer)?;
        duration_to_datetime_utc::<D>(dur)
    }
}use_duration_signed_de!(
600    TimestampSecondsWithFrac DurationSecondsWithFrac,
601    TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
602    TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
603    TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
604    => {
605        DateTime<Utc>; duration_to_datetime_utc =>
606        {f64, Strict =>}
607        {FORMAT, Flexible => FORMAT: Format}
608    }
609);
610#[cfg(feature = "alloc")]
611impl<'de> DeserializeAs<'de, DateTime<Utc>> for
    TimestampNanoSecondsWithFrac<String, Strict> where  {
    fn deserialize_as<D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
        where D: Deserializer<'de> {
        let dur: DurationSigned =
            DurationNanoSecondsWithFrac::<String,
                        Strict>::deserialize_as(deserializer)?;
        duration_to_datetime_utc::<D>(dur)
    }
}use_duration_signed_de!(
612    TimestampSecondsWithFrac DurationSecondsWithFrac,
613    TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
614    TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
615    TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
616    => {
617        DateTime<Utc>; duration_to_datetime_utc =>
618        {String, Strict =>}
619    }
620);
621#[cfg(feature = "std")]
622impl<'de, FORMAT> DeserializeAs<'de, DateTime<Local>> for
    TimestampNanoSecondsWithFrac<FORMAT, Flexible> where FORMAT: Format {
    fn deserialize_as<D>(deserializer: D) -> Result<DateTime<Local>, D::Error>
        where D: Deserializer<'de> {
        let dur: DurationSigned =
            DurationNanoSecondsWithFrac::<FORMAT,
                        Flexible>::deserialize_as(deserializer)?;
        duration_to_datetime_local::<D>(dur)
    }
}use_duration_signed_de!(
623    TimestampSecondsWithFrac DurationSecondsWithFrac,
624    TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
625    TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
626    TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
627    => {
628        DateTime<Local>; duration_to_datetime_local =>
629        {f64, Strict =>}
630        {String, Strict =>}
631        {FORMAT, Flexible => FORMAT: Format}
632    }
633);
634impl<'de, FORMAT> DeserializeAs<'de, NaiveDateTime> for
    TimestampNanoSecondsWithFrac<FORMAT, Flexible> where FORMAT: Format {
    fn deserialize_as<D>(deserializer: D) -> Result<NaiveDateTime, D::Error>
        where D: Deserializer<'de> {
        let dur: DurationSigned =
            DurationNanoSecondsWithFrac::<FORMAT,
                        Flexible>::deserialize_as(deserializer)?;
        duration_to_naive_datetime::<D>(dur)
    }
}use_duration_signed_de!(
635    TimestampSecondsWithFrac DurationSecondsWithFrac,
636    TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
637    TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
638    TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
639    => {
640        NaiveDateTime; duration_to_naive_datetime =>
641        {f64, Strict =>}
642        {FORMAT, Flexible => FORMAT: Format}
643    }
644);
645#[cfg(feature = "alloc")]
646impl<'de> DeserializeAs<'de, NaiveDateTime> for
    TimestampNanoSecondsWithFrac<String, Strict> where  {
    fn deserialize_as<D>(deserializer: D) -> Result<NaiveDateTime, D::Error>
        where D: Deserializer<'de> {
        let dur: DurationSigned =
            DurationNanoSecondsWithFrac::<String,
                        Strict>::deserialize_as(deserializer)?;
        duration_to_naive_datetime::<D>(dur)
    }
}use_duration_signed_de!(
647    TimestampSecondsWithFrac DurationSecondsWithFrac,
648    TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
649    TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
650    TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
651    => {
652        NaiveDateTime; duration_to_naive_datetime =>
653        {String, Strict =>}
654    }
655);