chrono/naive/datetime/
serde.rs

1use core::fmt;
2use serde::{de, ser};
3
4use super::NaiveDateTime;
5
6/// Serialize a `NaiveDateTime` as an ISO 8601 string
7///
8/// See [the `naive::serde` module](crate::naive::serde) for alternate serialization formats.
9impl ser::Serialize for NaiveDateTime {
10    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
11    where
12        S: ser::Serializer,
13    {
14        struct FormatWrapped<'a, D: 'a> {
15            inner: &'a D,
16        }
17
18        impl<'a, D: fmt::Debug> fmt::Display for FormatWrapped<'a, D> {
19            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
20                self.inner.fmt(f)
21            }
22        }
23
24        serializer.collect_str(&FormatWrapped { inner: &self })
25    }
26}
27
28struct NaiveDateTimeVisitor;
29
30impl<'de> de::Visitor<'de> for NaiveDateTimeVisitor {
31    type Value = NaiveDateTime;
32
33    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
34        formatter.write_str("a formatted date and time string")
35    }
36
37    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
38    where
39        E: de::Error,
40    {
41        value.parse().map_err(E::custom)
42    }
43}
44
45impl<'de> de::Deserialize<'de> for NaiveDateTime {
46    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
47    where
48        D: de::Deserializer<'de>,
49    {
50        deserializer.deserialize_str(NaiveDateTimeVisitor)
51    }
52}
53
54/// Used to serialize/deserialize from nanosecond-precision timestamps
55///
56/// # Example:
57///
58/// ```rust
59/// # use chrono::{NaiveDate, NaiveDateTime};
60/// # use serde_derive::{Deserialize, Serialize};
61/// use chrono::naive::serde::ts_nanoseconds;
62/// #[derive(Deserialize, Serialize)]
63/// struct S {
64///     #[serde(with = "ts_nanoseconds")]
65///     time: NaiveDateTime,
66/// }
67///
68/// let time = NaiveDate::from_ymd_opt(2018, 5, 17)
69///     .unwrap()
70///     .and_hms_nano_opt(02, 04, 59, 918355733)
71///     .unwrap();
72/// let my_s = S { time: time.clone() };
73///
74/// let as_string = serde_json::to_string(&my_s)?;
75/// assert_eq!(as_string, r#"{"time":1526522699918355733}"#);
76/// let my_s: S = serde_json::from_str(&as_string)?;
77/// assert_eq!(my_s.time, time);
78/// # Ok::<(), serde_json::Error>(())
79/// ```
80pub mod ts_nanoseconds {
81    use core::fmt;
82    use serde::{de, ser};
83
84    use crate::serde::invalid_ts;
85    use crate::{DateTime, NaiveDateTime};
86
87    /// Serialize a datetime into an integer number of nanoseconds since the epoch
88    ///
89    /// Intended for use with `serde`s `serialize_with` attribute.
90    ///
91    /// # Errors
92    ///
93    /// An `i64` with nanosecond precision can span a range of ~584 years. This function returns an
94    /// error on an out of range `DateTime`.
95    ///
96    /// The dates that can be represented as nanoseconds are between 1677-09-21T00:12:44.0 and
97    /// 2262-04-11T23:47:16.854775804.
98    ///
99    /// # Example:
100    ///
101    /// ```rust
102    /// # use chrono::{NaiveDate, NaiveDateTime};
103    /// # use serde_derive::Serialize;
104    /// use chrono::naive::serde::ts_nanoseconds::serialize as to_nano_ts;
105    /// #[derive(Serialize)]
106    /// struct S {
107    ///     #[serde(serialize_with = "to_nano_ts")]
108    ///     time: NaiveDateTime,
109    /// }
110    ///
111    /// let my_s = S {
112    ///     time: NaiveDate::from_ymd_opt(2018, 5, 17)
113    ///         .unwrap()
114    ///         .and_hms_nano_opt(02, 04, 59, 918355733)
115    ///         .unwrap(),
116    /// };
117    /// let as_string = serde_json::to_string(&my_s)?;
118    /// assert_eq!(as_string, r#"{"time":1526522699918355733}"#);
119    /// # Ok::<(), serde_json::Error>(())
120    /// ```
121    pub fn serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
122    where
123        S: ser::Serializer,
124    {
125        serializer.serialize_i64(dt.and_utc().timestamp_nanos_opt().ok_or(ser::Error::custom(
126            "value out of range for a timestamp with nanosecond precision",
127        ))?)
128    }
129
130    /// Deserialize a `NaiveDateTime` from a nanoseconds timestamp
131    ///
132    /// Intended for use with `serde`s `deserialize_with` attribute.
133    ///
134    /// # Example:
135    ///
136    /// ```rust
137    /// # use chrono::{DateTime, NaiveDateTime};
138    /// # use serde_derive::Deserialize;
139    /// use chrono::naive::serde::ts_nanoseconds::deserialize as from_nano_ts;
140    /// #[derive(Debug, PartialEq, Deserialize)]
141    /// struct S {
142    ///     #[serde(deserialize_with = "from_nano_ts")]
143    ///     time: NaiveDateTime,
144    /// }
145    ///
146    /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355733 }"#)?;
147    /// let expected = DateTime::from_timestamp(1526522699, 918355733).unwrap().naive_utc();
148    /// assert_eq!(my_s, S { time: expected });
149    ///
150    /// let my_s: S = serde_json::from_str(r#"{ "time": -1 }"#)?;
151    /// let expected = DateTime::from_timestamp(-1, 999_999_999).unwrap().naive_utc();
152    /// assert_eq!(my_s, S { time: expected });
153    /// # Ok::<(), serde_json::Error>(())
154    /// ```
155    pub fn deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error>
156    where
157        D: de::Deserializer<'de>,
158    {
159        d.deserialize_i64(NanoSecondsTimestampVisitor)
160    }
161
162    pub(super) struct NanoSecondsTimestampVisitor;
163
164    impl<'de> de::Visitor<'de> for NanoSecondsTimestampVisitor {
165        type Value = NaiveDateTime;
166
167        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
168            formatter.write_str("a unix timestamp")
169        }
170
171        fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
172        where
173            E: de::Error,
174        {
175            DateTime::from_timestamp(
176                value.div_euclid(1_000_000_000),
177                (value.rem_euclid(1_000_000_000)) as u32,
178            )
179            .map(|dt| dt.naive_utc())
180            .ok_or_else(|| invalid_ts(value))
181        }
182
183        fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
184        where
185            E: de::Error,
186        {
187            DateTime::from_timestamp((value / 1_000_000_000) as i64, (value % 1_000_000_000) as u32)
188                .map(|dt| dt.naive_utc())
189                .ok_or_else(|| invalid_ts(value))
190        }
191    }
192}
193
194/// Ser/de to/from optional timestamps in nanoseconds
195///
196/// Intended for use with `serde`'s `with` attribute.
197///
198/// # Example:
199///
200/// ```rust
201/// # use chrono::naive::{NaiveDate, NaiveDateTime};
202/// # use serde_derive::{Deserialize, Serialize};
203/// use chrono::naive::serde::ts_nanoseconds_option;
204/// #[derive(Deserialize, Serialize)]
205/// struct S {
206///     #[serde(with = "ts_nanoseconds_option")]
207///     time: Option<NaiveDateTime>,
208/// }
209///
210/// let time = Some(
211///     NaiveDate::from_ymd_opt(2018, 5, 17)
212///         .unwrap()
213///         .and_hms_nano_opt(02, 04, 59, 918355733)
214///         .unwrap(),
215/// );
216/// let my_s = S { time: time.clone() };
217///
218/// let as_string = serde_json::to_string(&my_s)?;
219/// assert_eq!(as_string, r#"{"time":1526522699918355733}"#);
220/// let my_s: S = serde_json::from_str(&as_string)?;
221/// assert_eq!(my_s.time, time);
222/// # Ok::<(), serde_json::Error>(())
223/// ```
224pub mod ts_nanoseconds_option {
225    use core::fmt;
226    use serde::{de, ser};
227
228    use super::ts_nanoseconds::NanoSecondsTimestampVisitor;
229    use crate::NaiveDateTime;
230
231    /// Serialize a datetime into an integer number of nanoseconds since the epoch or none
232    ///
233    /// Intended for use with `serde`s `serialize_with` attribute.
234    ///
235    /// # Errors
236    ///
237    /// An `i64` with nanosecond precision can span a range of ~584 years. This function returns an
238    /// error on an out of range `DateTime`.
239    ///
240    /// The dates that can be represented as nanoseconds are between 1677-09-21T00:12:44.0 and
241    /// 2262-04-11T23:47:16.854775804.
242    ///
243    /// # Example:
244    ///
245    /// ```rust
246    /// # use chrono::naive::{NaiveDate, NaiveDateTime};
247    /// # use serde_derive::Serialize;
248    /// use chrono::naive::serde::ts_nanoseconds_option::serialize as to_nano_tsopt;
249    /// #[derive(Serialize)]
250    /// struct S {
251    ///     #[serde(serialize_with = "to_nano_tsopt")]
252    ///     time: Option<NaiveDateTime>,
253    /// }
254    ///
255    /// let my_s = S {
256    ///     time: Some(
257    ///         NaiveDate::from_ymd_opt(2018, 5, 17)
258    ///             .unwrap()
259    ///             .and_hms_nano_opt(02, 04, 59, 918355733)
260    ///             .unwrap(),
261    ///     ),
262    /// };
263    /// let as_string = serde_json::to_string(&my_s)?;
264    /// assert_eq!(as_string, r#"{"time":1526522699918355733}"#);
265    /// # Ok::<(), serde_json::Error>(())
266    /// ```
267    pub fn serialize<S>(opt: &Option<NaiveDateTime>, serializer: S) -> Result<S::Ok, S::Error>
268    where
269        S: ser::Serializer,
270    {
271        match *opt {
272            Some(ref dt) => serializer.serialize_some(&dt.and_utc().timestamp_nanos_opt().ok_or(
273                ser::Error::custom("value out of range for a timestamp with nanosecond precision"),
274            )?),
275            None => serializer.serialize_none(),
276        }
277    }
278
279    /// Deserialize a `NaiveDateTime` from a nanosecond timestamp or none
280    ///
281    /// Intended for use with `serde`s `deserialize_with` attribute.
282    ///
283    /// # Example:
284    ///
285    /// ```rust
286    /// # use chrono::{DateTime, NaiveDateTime};
287    /// # use serde_derive::Deserialize;
288    /// use chrono::naive::serde::ts_nanoseconds_option::deserialize as from_nano_tsopt;
289    /// #[derive(Debug, PartialEq, Deserialize)]
290    /// struct S {
291    ///     #[serde(deserialize_with = "from_nano_tsopt")]
292    ///     time: Option<NaiveDateTime>,
293    /// }
294    ///
295    /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355733 }"#)?;
296    /// let expected = DateTime::from_timestamp(1526522699, 918355733).unwrap().naive_utc();
297    /// assert_eq!(my_s, S { time: Some(expected) });
298    ///
299    /// let my_s: S = serde_json::from_str(r#"{ "time": -1 }"#)?;
300    /// let expected = DateTime::from_timestamp(-1, 999_999_999).unwrap().naive_utc();
301    /// assert_eq!(my_s, S { time: Some(expected) });
302    /// # Ok::<(), serde_json::Error>(())
303    /// ```
304    pub fn deserialize<'de, D>(d: D) -> Result<Option<NaiveDateTime>, D::Error>
305    where
306        D: de::Deserializer<'de>,
307    {
308        d.deserialize_option(OptionNanoSecondsTimestampVisitor)
309    }
310
311    struct OptionNanoSecondsTimestampVisitor;
312
313    impl<'de> de::Visitor<'de> for OptionNanoSecondsTimestampVisitor {
314        type Value = Option<NaiveDateTime>;
315
316        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
317            formatter.write_str("a unix timestamp in nanoseconds or none")
318        }
319
320        /// Deserialize a timestamp in nanoseconds since the epoch
321        fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
322        where
323            D: de::Deserializer<'de>,
324        {
325            d.deserialize_i64(NanoSecondsTimestampVisitor).map(Some)
326        }
327
328        /// Deserialize a timestamp in nanoseconds since the epoch
329        fn visit_none<E>(self) -> Result<Self::Value, E>
330        where
331            E: de::Error,
332        {
333            Ok(None)
334        }
335
336        /// Deserialize a timestamp in nanoseconds since the epoch
337        fn visit_unit<E>(self) -> Result<Self::Value, E>
338        where
339            E: de::Error,
340        {
341            Ok(None)
342        }
343    }
344}
345
346/// Used to serialize/deserialize from microsecond-precision timestamps
347///
348/// # Example:
349///
350/// ```rust
351/// # use chrono::{NaiveDate, NaiveDateTime};
352/// # use serde_derive::{Deserialize, Serialize};
353/// use chrono::naive::serde::ts_microseconds;
354/// #[derive(Deserialize, Serialize)]
355/// struct S {
356///     #[serde(with = "ts_microseconds")]
357///     time: NaiveDateTime,
358/// }
359///
360/// let time = NaiveDate::from_ymd_opt(2018, 5, 17)
361///     .unwrap()
362///     .and_hms_micro_opt(02, 04, 59, 918355)
363///     .unwrap();
364/// let my_s = S { time: time.clone() };
365///
366/// let as_string = serde_json::to_string(&my_s)?;
367/// assert_eq!(as_string, r#"{"time":1526522699918355}"#);
368/// let my_s: S = serde_json::from_str(&as_string)?;
369/// assert_eq!(my_s.time, time);
370/// # Ok::<(), serde_json::Error>(())
371/// ```
372pub mod ts_microseconds {
373    use core::fmt;
374    use serde::{de, ser};
375
376    use crate::serde::invalid_ts;
377    use crate::{DateTime, NaiveDateTime};
378
379    /// Serialize a datetime into an integer number of microseconds since the epoch
380    ///
381    /// Intended for use with `serde`s `serialize_with` attribute.
382    ///
383    /// # Example:
384    ///
385    /// ```rust
386    /// # use chrono::{NaiveDate, NaiveDateTime};
387    /// # use serde_derive::Serialize;
388    /// use chrono::naive::serde::ts_microseconds::serialize as to_micro_ts;
389    /// #[derive(Serialize)]
390    /// struct S {
391    ///     #[serde(serialize_with = "to_micro_ts")]
392    ///     time: NaiveDateTime,
393    /// }
394    ///
395    /// let my_s = S {
396    ///     time: NaiveDate::from_ymd_opt(2018, 5, 17)
397    ///         .unwrap()
398    ///         .and_hms_micro_opt(02, 04, 59, 918355)
399    ///         .unwrap(),
400    /// };
401    /// let as_string = serde_json::to_string(&my_s)?;
402    /// assert_eq!(as_string, r#"{"time":1526522699918355}"#);
403    /// # Ok::<(), serde_json::Error>(())
404    /// ```
405    pub fn serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
406    where
407        S: ser::Serializer,
408    {
409        serializer.serialize_i64(dt.and_utc().timestamp_micros())
410    }
411
412    /// Deserialize a `NaiveDateTime` from a microseconds timestamp
413    ///
414    /// Intended for use with `serde`s `deserialize_with` attribute.
415    ///
416    /// # Example:
417    ///
418    /// ```rust
419    /// # use chrono::{DateTime, NaiveDateTime};
420    /// # use serde_derive::Deserialize;
421    /// use chrono::naive::serde::ts_microseconds::deserialize as from_micro_ts;
422    /// #[derive(Debug, PartialEq, Deserialize)]
423    /// struct S {
424    ///     #[serde(deserialize_with = "from_micro_ts")]
425    ///     time: NaiveDateTime,
426    /// }
427    ///
428    /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355 }"#)?;
429    /// let expected = DateTime::from_timestamp(1526522699, 918355000).unwrap().naive_utc();
430    /// assert_eq!(my_s, S { time: expected });
431    ///
432    /// let my_s: S = serde_json::from_str(r#"{ "time": -1 }"#)?;
433    /// let expected = DateTime::from_timestamp(-1, 999_999_000).unwrap().naive_utc();
434    /// assert_eq!(my_s, S { time: expected });
435    /// # Ok::<(), serde_json::Error>(())
436    /// ```
437    pub fn deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error>
438    where
439        D: de::Deserializer<'de>,
440    {
441        d.deserialize_i64(MicroSecondsTimestampVisitor)
442    }
443
444    pub(super) struct MicroSecondsTimestampVisitor;
445
446    impl<'de> de::Visitor<'de> for MicroSecondsTimestampVisitor {
447        type Value = NaiveDateTime;
448
449        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
450            formatter.write_str("a unix timestamp")
451        }
452
453        fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
454        where
455            E: de::Error,
456        {
457            DateTime::from_timestamp_micros(value)
458                .map(|dt| dt.naive_utc())
459                .ok_or_else(|| invalid_ts(value))
460        }
461
462        fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
463        where
464            E: de::Error,
465        {
466            DateTime::from_timestamp(
467                (value / 1_000_000) as i64,
468                ((value % 1_000_000) * 1_000) as u32,
469            )
470            .map(|dt| dt.naive_utc())
471            .ok_or_else(|| invalid_ts(value))
472        }
473    }
474}
475
476/// Ser/de to/from optional timestamps in microseconds
477///
478/// Intended for use with `serde`'s `with` attribute.
479///
480/// # Example:
481///
482/// ```rust
483/// # use chrono::naive::{NaiveDate, NaiveDateTime};
484/// # use serde_derive::{Deserialize, Serialize};
485/// use chrono::naive::serde::ts_microseconds_option;
486/// #[derive(Deserialize, Serialize)]
487/// struct S {
488///     #[serde(with = "ts_microseconds_option")]
489///     time: Option<NaiveDateTime>,
490/// }
491///
492/// let time = Some(
493///     NaiveDate::from_ymd_opt(2018, 5, 17)
494///         .unwrap()
495///         .and_hms_micro_opt(02, 04, 59, 918355)
496///         .unwrap(),
497/// );
498/// let my_s = S { time: time.clone() };
499///
500/// let as_string = serde_json::to_string(&my_s)?;
501/// assert_eq!(as_string, r#"{"time":1526522699918355}"#);
502/// let my_s: S = serde_json::from_str(&as_string)?;
503/// assert_eq!(my_s.time, time);
504/// # Ok::<(), serde_json::Error>(())
505/// ```
506pub mod ts_microseconds_option {
507    use core::fmt;
508    use serde::{de, ser};
509
510    use super::ts_microseconds::MicroSecondsTimestampVisitor;
511    use crate::NaiveDateTime;
512
513    /// Serialize a datetime into an integer number of microseconds since the epoch or none
514    ///
515    /// Intended for use with `serde`s `serialize_with` attribute.
516    ///
517    /// # Example:
518    ///
519    /// ```rust
520    /// # use chrono::naive::{NaiveDate, NaiveDateTime};
521    /// # use serde_derive::Serialize;
522    /// use chrono::naive::serde::ts_microseconds_option::serialize as to_micro_tsopt;
523    /// #[derive(Serialize)]
524    /// struct S {
525    ///     #[serde(serialize_with = "to_micro_tsopt")]
526    ///     time: Option<NaiveDateTime>,
527    /// }
528    ///
529    /// let my_s = S {
530    ///     time: Some(
531    ///         NaiveDate::from_ymd_opt(2018, 5, 17)
532    ///             .unwrap()
533    ///             .and_hms_micro_opt(02, 04, 59, 918355)
534    ///             .unwrap(),
535    ///     ),
536    /// };
537    /// let as_string = serde_json::to_string(&my_s)?;
538    /// assert_eq!(as_string, r#"{"time":1526522699918355}"#);
539    /// # Ok::<(), serde_json::Error>(())
540    /// ```
541    pub fn serialize<S>(opt: &Option<NaiveDateTime>, serializer: S) -> Result<S::Ok, S::Error>
542    where
543        S: ser::Serializer,
544    {
545        match *opt {
546            Some(ref dt) => serializer.serialize_some(&dt.and_utc().timestamp_micros()),
547            None => serializer.serialize_none(),
548        }
549    }
550
551    /// Deserialize a `NaiveDateTime` from a nanosecond timestamp or none
552    ///
553    /// Intended for use with `serde`s `deserialize_with` attribute.
554    ///
555    /// # Example:
556    ///
557    /// ```rust
558    /// # use chrono::{DateTime, NaiveDateTime};
559    /// # use serde_derive::Deserialize;
560    /// use chrono::naive::serde::ts_microseconds_option::deserialize as from_micro_tsopt;
561    /// #[derive(Debug, PartialEq, Deserialize)]
562    /// struct S {
563    ///     #[serde(deserialize_with = "from_micro_tsopt")]
564    ///     time: Option<NaiveDateTime>,
565    /// }
566    ///
567    /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355 }"#)?;
568    /// let expected = DateTime::from_timestamp(1526522699, 918355000).unwrap().naive_utc();
569    /// assert_eq!(my_s, S { time: Some(expected) });
570    ///
571    /// let my_s: S = serde_json::from_str(r#"{ "time": -1 }"#)?;
572    /// let expected = DateTime::from_timestamp(-1, 999_999_000).unwrap().naive_utc();
573    /// assert_eq!(my_s, S { time: Some(expected) });
574    /// # Ok::<(), serde_json::Error>(())
575    /// ```
576    pub fn deserialize<'de, D>(d: D) -> Result<Option<NaiveDateTime>, D::Error>
577    where
578        D: de::Deserializer<'de>,
579    {
580        d.deserialize_option(OptionMicroSecondsTimestampVisitor)
581    }
582
583    struct OptionMicroSecondsTimestampVisitor;
584
585    impl<'de> de::Visitor<'de> for OptionMicroSecondsTimestampVisitor {
586        type Value = Option<NaiveDateTime>;
587
588        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
589            formatter.write_str("a unix timestamp in microseconds or none")
590        }
591
592        /// Deserialize a timestamp in microseconds since the epoch
593        fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
594        where
595            D: de::Deserializer<'de>,
596        {
597            d.deserialize_i64(MicroSecondsTimestampVisitor).map(Some)
598        }
599
600        /// Deserialize a timestamp in microseconds since the epoch
601        fn visit_none<E>(self) -> Result<Self::Value, E>
602        where
603            E: de::Error,
604        {
605            Ok(None)
606        }
607
608        /// Deserialize a timestamp in microseconds since the epoch
609        fn visit_unit<E>(self) -> Result<Self::Value, E>
610        where
611            E: de::Error,
612        {
613            Ok(None)
614        }
615    }
616}
617
618/// Used to serialize/deserialize from millisecond-precision timestamps
619///
620/// # Example:
621///
622/// ```rust
623/// # use chrono::{NaiveDate, NaiveDateTime};
624/// # use serde_derive::{Deserialize, Serialize};
625/// use chrono::naive::serde::ts_milliseconds;
626/// #[derive(Deserialize, Serialize)]
627/// struct S {
628///     #[serde(with = "ts_milliseconds")]
629///     time: NaiveDateTime,
630/// }
631///
632/// let time =
633///     NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_milli_opt(02, 04, 59, 918).unwrap();
634/// let my_s = S { time: time.clone() };
635///
636/// let as_string = serde_json::to_string(&my_s)?;
637/// assert_eq!(as_string, r#"{"time":1526522699918}"#);
638/// let my_s: S = serde_json::from_str(&as_string)?;
639/// assert_eq!(my_s.time, time);
640/// # Ok::<(), serde_json::Error>(())
641/// ```
642pub mod ts_milliseconds {
643    use core::fmt;
644    use serde::{de, ser};
645
646    use crate::serde::invalid_ts;
647    use crate::{DateTime, NaiveDateTime};
648
649    /// Serialize a datetime into an integer number of milliseconds since the epoch
650    ///
651    /// Intended for use with `serde`s `serialize_with` attribute.
652    ///
653    /// # Example:
654    ///
655    /// ```rust
656    /// # use chrono::{NaiveDate, NaiveDateTime};
657    /// # use serde_derive::Serialize;
658    /// use chrono::naive::serde::ts_milliseconds::serialize as to_milli_ts;
659    /// #[derive(Serialize)]
660    /// struct S {
661    ///     #[serde(serialize_with = "to_milli_ts")]
662    ///     time: NaiveDateTime,
663    /// }
664    ///
665    /// let my_s = S {
666    ///     time: NaiveDate::from_ymd_opt(2018, 5, 17)
667    ///         .unwrap()
668    ///         .and_hms_milli_opt(02, 04, 59, 918)
669    ///         .unwrap(),
670    /// };
671    /// let as_string = serde_json::to_string(&my_s)?;
672    /// assert_eq!(as_string, r#"{"time":1526522699918}"#);
673    /// # Ok::<(), serde_json::Error>(())
674    /// ```
675    pub fn serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
676    where
677        S: ser::Serializer,
678    {
679        serializer.serialize_i64(dt.and_utc().timestamp_millis())
680    }
681
682    /// Deserialize a `NaiveDateTime` from a milliseconds timestamp
683    ///
684    /// Intended for use with `serde`s `deserialize_with` attribute.
685    ///
686    /// # Example:
687    ///
688    /// ```rust
689    /// # use chrono::{DateTime, NaiveDateTime};
690    /// # use serde_derive::Deserialize;
691    /// use chrono::naive::serde::ts_milliseconds::deserialize as from_milli_ts;
692    /// #[derive(Debug, PartialEq, Deserialize)]
693    /// struct S {
694    ///     #[serde(deserialize_with = "from_milli_ts")]
695    ///     time: NaiveDateTime,
696    /// }
697    ///
698    /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918 }"#)?;
699    /// let expected = DateTime::from_timestamp(1526522699, 918000000).unwrap().naive_utc();
700    /// assert_eq!(my_s, S { time: expected });
701    ///
702    /// let my_s: S = serde_json::from_str(r#"{ "time": -1 }"#)?;
703    /// let expected = DateTime::from_timestamp(-1, 999_000_000).unwrap().naive_utc();
704    /// assert_eq!(my_s, S { time: expected });
705    /// # Ok::<(), serde_json::Error>(())
706    /// ```
707    pub fn deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error>
708    where
709        D: de::Deserializer<'de>,
710    {
711        d.deserialize_i64(MilliSecondsTimestampVisitor)
712    }
713
714    pub(super) struct MilliSecondsTimestampVisitor;
715
716    impl<'de> de::Visitor<'de> for MilliSecondsTimestampVisitor {
717        type Value = NaiveDateTime;
718
719        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
720            formatter.write_str("a unix timestamp")
721        }
722
723        fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
724        where
725            E: de::Error,
726        {
727            DateTime::from_timestamp_millis(value)
728                .map(|dt| dt.naive_utc())
729                .ok_or_else(|| invalid_ts(value))
730        }
731
732        fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
733        where
734            E: de::Error,
735        {
736            DateTime::from_timestamp((value / 1000) as i64, ((value % 1000) * 1_000_000) as u32)
737                .map(|dt| dt.naive_utc())
738                .ok_or_else(|| invalid_ts(value))
739        }
740    }
741}
742
743/// Ser/de to/from optional timestamps in milliseconds
744///
745/// Intended for use with `serde`'s `with` attribute.
746///
747/// # Example:
748///
749/// ```rust
750/// # use chrono::naive::{NaiveDate, NaiveDateTime};
751/// # use serde_derive::{Deserialize, Serialize};
752/// use chrono::naive::serde::ts_milliseconds_option;
753/// #[derive(Deserialize, Serialize)]
754/// struct S {
755///     #[serde(with = "ts_milliseconds_option")]
756///     time: Option<NaiveDateTime>,
757/// }
758///
759/// let time = Some(
760///     NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_milli_opt(02, 04, 59, 918).unwrap(),
761/// );
762/// let my_s = S { time: time.clone() };
763///
764/// let as_string = serde_json::to_string(&my_s)?;
765/// assert_eq!(as_string, r#"{"time":1526522699918}"#);
766/// let my_s: S = serde_json::from_str(&as_string)?;
767/// assert_eq!(my_s.time, time);
768/// # Ok::<(), serde_json::Error>(())
769/// ```
770pub mod ts_milliseconds_option {
771    use core::fmt;
772    use serde::{de, ser};
773
774    use super::ts_milliseconds::MilliSecondsTimestampVisitor;
775    use crate::NaiveDateTime;
776
777    /// Serialize a datetime into an integer number of milliseconds since the epoch or none
778    ///
779    /// Intended for use with `serde`s `serialize_with` attribute.
780    ///
781    /// # Example:
782    ///
783    /// ```rust
784    /// # use chrono::naive::{NaiveDate, NaiveDateTime};
785    /// # use serde_derive::Serialize;
786    /// use chrono::naive::serde::ts_milliseconds_option::serialize as to_milli_tsopt;
787    /// #[derive(Serialize)]
788    /// struct S {
789    ///     #[serde(serialize_with = "to_milli_tsopt")]
790    ///     time: Option<NaiveDateTime>,
791    /// }
792    ///
793    /// let my_s = S {
794    ///     time: Some(
795    ///         NaiveDate::from_ymd_opt(2018, 5, 17)
796    ///             .unwrap()
797    ///             .and_hms_milli_opt(02, 04, 59, 918)
798    ///             .unwrap(),
799    ///     ),
800    /// };
801    /// let as_string = serde_json::to_string(&my_s)?;
802    /// assert_eq!(as_string, r#"{"time":1526522699918}"#);
803    /// # Ok::<(), serde_json::Error>(())
804    /// ```
805    pub fn serialize<S>(opt: &Option<NaiveDateTime>, serializer: S) -> Result<S::Ok, S::Error>
806    where
807        S: ser::Serializer,
808    {
809        match *opt {
810            Some(ref dt) => serializer.serialize_some(&dt.and_utc().timestamp_millis()),
811            None => serializer.serialize_none(),
812        }
813    }
814
815    /// Deserialize a `NaiveDateTime` from a millisecond timestamp or none
816    ///
817    /// Intended for use with `serde`s `deserialize_with` attribute.
818    ///
819    /// # Example:
820    ///
821    /// ```rust
822    /// # use chrono::{DateTime, NaiveDateTime};
823    /// # use serde_derive::Deserialize;
824    /// use chrono::naive::serde::ts_milliseconds_option::deserialize as from_milli_tsopt;
825    /// #[derive(Debug, PartialEq, Deserialize)]
826    /// struct S {
827    ///     #[serde(deserialize_with = "from_milli_tsopt")]
828    ///     time: Option<NaiveDateTime>,
829    /// }
830    ///
831    /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918 }"#)?;
832    /// let expected = DateTime::from_timestamp(1526522699, 918000000).unwrap().naive_utc();
833    /// assert_eq!(my_s, S { time: Some(expected) });
834    ///
835    /// let my_s: S = serde_json::from_str(r#"{ "time": -1 }"#)?;
836    /// let expected = DateTime::from_timestamp(-1, 999_000_000).unwrap().naive_utc();
837    /// assert_eq!(my_s, S { time: Some(expected) });
838    /// # Ok::<(), serde_json::Error>(())
839    /// ```
840    pub fn deserialize<'de, D>(d: D) -> Result<Option<NaiveDateTime>, D::Error>
841    where
842        D: de::Deserializer<'de>,
843    {
844        d.deserialize_option(OptionMilliSecondsTimestampVisitor)
845    }
846
847    struct OptionMilliSecondsTimestampVisitor;
848
849    impl<'de> de::Visitor<'de> for OptionMilliSecondsTimestampVisitor {
850        type Value = Option<NaiveDateTime>;
851
852        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
853            formatter.write_str("a unix timestamp in milliseconds or none")
854        }
855
856        /// Deserialize a timestamp in milliseconds since the epoch
857        fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
858        where
859            D: de::Deserializer<'de>,
860        {
861            d.deserialize_i64(MilliSecondsTimestampVisitor).map(Some)
862        }
863
864        /// Deserialize a timestamp in milliseconds since the epoch
865        fn visit_none<E>(self) -> Result<Self::Value, E>
866        where
867            E: de::Error,
868        {
869            Ok(None)
870        }
871
872        /// Deserialize a timestamp in milliseconds since the epoch
873        fn visit_unit<E>(self) -> Result<Self::Value, E>
874        where
875            E: de::Error,
876        {
877            Ok(None)
878        }
879    }
880}
881
882/// Used to serialize/deserialize from second-precision timestamps
883///
884/// # Example:
885///
886/// ```rust
887/// # use chrono::{NaiveDate, NaiveDateTime};
888/// # use serde_derive::{Deserialize, Serialize};
889/// use chrono::naive::serde::ts_seconds;
890/// #[derive(Deserialize, Serialize)]
891/// struct S {
892///     #[serde(with = "ts_seconds")]
893///     time: NaiveDateTime,
894/// }
895///
896/// let time = NaiveDate::from_ymd_opt(2015, 5, 15).unwrap().and_hms_opt(10, 0, 0).unwrap();
897/// let my_s = S { time: time.clone() };
898///
899/// let as_string = serde_json::to_string(&my_s)?;
900/// assert_eq!(as_string, r#"{"time":1431684000}"#);
901/// let my_s: S = serde_json::from_str(&as_string)?;
902/// assert_eq!(my_s.time, time);
903/// # Ok::<(), serde_json::Error>(())
904/// ```
905pub mod ts_seconds {
906    use core::fmt;
907    use serde::{de, ser};
908
909    use crate::serde::invalid_ts;
910    use crate::{DateTime, NaiveDateTime};
911
912    /// Serialize a datetime into an integer number of seconds since the epoch
913    ///
914    /// Intended for use with `serde`s `serialize_with` attribute.
915    ///
916    /// # Example:
917    ///
918    /// ```rust
919    /// # use chrono::{NaiveDate, NaiveDateTime};
920    /// # use serde_derive::Serialize;
921    /// use chrono::naive::serde::ts_seconds::serialize as to_ts;
922    /// #[derive(Serialize)]
923    /// struct S {
924    ///     #[serde(serialize_with = "to_ts")]
925    ///     time: NaiveDateTime,
926    /// }
927    ///
928    /// let my_s =
929    ///     S { time: NaiveDate::from_ymd_opt(2015, 5, 15).unwrap().and_hms_opt(10, 0, 0).unwrap() };
930    /// let as_string = serde_json::to_string(&my_s)?;
931    /// assert_eq!(as_string, r#"{"time":1431684000}"#);
932    /// # Ok::<(), serde_json::Error>(())
933    /// ```
934    pub fn serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
935    where
936        S: ser::Serializer,
937    {
938        serializer.serialize_i64(dt.and_utc().timestamp())
939    }
940
941    /// Deserialize a `NaiveDateTime` from a seconds timestamp
942    ///
943    /// Intended for use with `serde`s `deserialize_with` attribute.
944    ///
945    /// # Example:
946    ///
947    /// ```rust
948    /// # use chrono::{DateTime, NaiveDateTime};
949    /// # use serde_derive::Deserialize;
950    /// use chrono::naive::serde::ts_seconds::deserialize as from_ts;
951    /// #[derive(Debug, PartialEq, Deserialize)]
952    /// struct S {
953    ///     #[serde(deserialize_with = "from_ts")]
954    ///     time: NaiveDateTime,
955    /// }
956    ///
957    /// let my_s: S = serde_json::from_str(r#"{ "time": 1431684000 }"#)?;
958    /// let expected = DateTime::from_timestamp(1431684000, 0).unwrap().naive_utc();
959    /// assert_eq!(my_s, S { time: expected });
960    /// # Ok::<(), serde_json::Error>(())
961    /// ```
962    pub fn deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error>
963    where
964        D: de::Deserializer<'de>,
965    {
966        d.deserialize_i64(SecondsTimestampVisitor)
967    }
968
969    pub(super) struct SecondsTimestampVisitor;
970
971    impl<'de> de::Visitor<'de> for SecondsTimestampVisitor {
972        type Value = NaiveDateTime;
973
974        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
975            formatter.write_str("a unix timestamp")
976        }
977
978        fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
979        where
980            E: de::Error,
981        {
982            DateTime::from_timestamp(value, 0)
983                .map(|dt| dt.naive_utc())
984                .ok_or_else(|| invalid_ts(value))
985        }
986
987        fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
988        where
989            E: de::Error,
990        {
991            if value > i64::MAX as u64 {
992                Err(invalid_ts(value))
993            } else {
994                DateTime::from_timestamp(value as i64, 0)
995                    .map(|dt| dt.naive_utc())
996                    .ok_or_else(|| invalid_ts(value))
997            }
998        }
999    }
1000}
1001
1002/// Ser/de to/from optional timestamps in seconds
1003///
1004/// Intended for use with `serde`'s `with` attribute.
1005///
1006/// # Example:
1007///
1008/// ```rust
1009/// # use chrono::naive::{NaiveDate, NaiveDateTime};
1010/// # use serde_derive::{Deserialize, Serialize};
1011/// use chrono::naive::serde::ts_seconds_option;
1012/// #[derive(Deserialize, Serialize)]
1013/// struct S {
1014///     #[serde(with = "ts_seconds_option")]
1015///     time: Option<NaiveDateTime>,
1016/// }
1017///
1018/// let time = Some(NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_opt(02, 04, 59).unwrap());
1019/// let my_s = S { time: time.clone() };
1020///
1021/// let as_string = serde_json::to_string(&my_s)?;
1022/// assert_eq!(as_string, r#"{"time":1526522699}"#);
1023/// let my_s: S = serde_json::from_str(&as_string)?;
1024/// assert_eq!(my_s.time, time);
1025/// # Ok::<(), serde_json::Error>(())
1026/// ```
1027pub mod ts_seconds_option {
1028    use core::fmt;
1029    use serde::{de, ser};
1030
1031    use super::ts_seconds::SecondsTimestampVisitor;
1032    use crate::NaiveDateTime;
1033
1034    /// Serialize a datetime into an integer number of seconds since the epoch or none
1035    ///
1036    /// Intended for use with `serde`s `serialize_with` attribute.
1037    ///
1038    /// # Example:
1039    ///
1040    /// ```rust
1041    /// # use chrono::naive::{NaiveDate, NaiveDateTime};
1042    /// # use serde_derive::Serialize;
1043    /// use chrono::naive::serde::ts_seconds_option::serialize as to_tsopt;
1044    /// #[derive(Serialize)]
1045    /// struct S {
1046    ///     #[serde(serialize_with = "to_tsopt")]
1047    ///     time: Option<NaiveDateTime>,
1048    /// }
1049    ///
1050    /// let expected = NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_opt(02, 04, 59).unwrap();
1051    /// let my_s = S { time: Some(expected) };
1052    /// let as_string = serde_json::to_string(&my_s)?;
1053    /// assert_eq!(as_string, r#"{"time":1526522699}"#);
1054    /// # Ok::<(), serde_json::Error>(())
1055    /// ```
1056    pub fn serialize<S>(opt: &Option<NaiveDateTime>, serializer: S) -> Result<S::Ok, S::Error>
1057    where
1058        S: ser::Serializer,
1059    {
1060        match *opt {
1061            Some(ref dt) => serializer.serialize_some(&dt.and_utc().timestamp()),
1062            None => serializer.serialize_none(),
1063        }
1064    }
1065
1066    /// Deserialize a `NaiveDateTime` from a second timestamp or none
1067    ///
1068    /// Intended for use with `serde`s `deserialize_with` attribute.
1069    ///
1070    /// # Example:
1071    ///
1072    /// ```rust
1073    /// # use chrono::{DateTime, NaiveDateTime};
1074    /// # use serde_derive::Deserialize;
1075    /// use chrono::naive::serde::ts_seconds_option::deserialize as from_tsopt;
1076    /// #[derive(Debug, PartialEq, Deserialize)]
1077    /// struct S {
1078    ///     #[serde(deserialize_with = "from_tsopt")]
1079    ///     time: Option<NaiveDateTime>,
1080    /// }
1081    ///
1082    /// let my_s: S = serde_json::from_str(r#"{ "time": 1431684000 }"#)?;
1083    /// let expected = DateTime::from_timestamp(1431684000, 0).unwrap().naive_utc();
1084    /// assert_eq!(my_s, S { time: Some(expected) });
1085    /// # Ok::<(), serde_json::Error>(())
1086    /// ```
1087    pub fn deserialize<'de, D>(d: D) -> Result<Option<NaiveDateTime>, D::Error>
1088    where
1089        D: de::Deserializer<'de>,
1090    {
1091        d.deserialize_option(OptionSecondsTimestampVisitor)
1092    }
1093
1094    struct OptionSecondsTimestampVisitor;
1095
1096    impl<'de> de::Visitor<'de> for OptionSecondsTimestampVisitor {
1097        type Value = Option<NaiveDateTime>;
1098
1099        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1100            formatter.write_str("a unix timestamp in seconds or none")
1101        }
1102
1103        /// Deserialize a timestamp in seconds since the epoch
1104        fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
1105        where
1106            D: de::Deserializer<'de>,
1107        {
1108            d.deserialize_i64(SecondsTimestampVisitor).map(Some)
1109        }
1110
1111        /// Deserialize a timestamp in seconds since the epoch
1112        fn visit_none<E>(self) -> Result<Self::Value, E>
1113        where
1114            E: de::Error,
1115        {
1116            Ok(None)
1117        }
1118
1119        /// Deserialize a timestamp in seconds since the epoch
1120        fn visit_unit<E>(self) -> Result<Self::Value, E>
1121        where
1122            E: de::Error,
1123        {
1124            Ok(None)
1125        }
1126    }
1127}
1128
1129#[cfg(test)]
1130mod tests {
1131    use crate::serde::ts_nanoseconds_option;
1132    use crate::{DateTime, NaiveDate, NaiveDateTime, TimeZone, Utc};
1133
1134    use bincode::{deserialize, serialize};
1135    use serde_derive::{Deserialize, Serialize};
1136
1137    #[test]
1138    fn test_serde_serialize() {
1139        assert_eq!(
1140            serde_json::to_string(
1141                &NaiveDate::from_ymd_opt(2016, 7, 8)
1142                    .unwrap()
1143                    .and_hms_milli_opt(9, 10, 48, 90)
1144                    .unwrap()
1145            )
1146            .ok(),
1147            Some(r#""2016-07-08T09:10:48.090""#.into())
1148        );
1149        assert_eq!(
1150            serde_json::to_string(
1151                &NaiveDate::from_ymd_opt(2014, 7, 24).unwrap().and_hms_opt(12, 34, 6).unwrap()
1152            )
1153            .ok(),
1154            Some(r#""2014-07-24T12:34:06""#.into())
1155        );
1156        assert_eq!(
1157            serde_json::to_string(
1158                &NaiveDate::from_ymd_opt(0, 1, 1)
1159                    .unwrap()
1160                    .and_hms_milli_opt(0, 0, 59, 1_000)
1161                    .unwrap()
1162            )
1163            .ok(),
1164            Some(r#""0000-01-01T00:00:60""#.into())
1165        );
1166        assert_eq!(
1167            serde_json::to_string(
1168                &NaiveDate::from_ymd_opt(-1, 12, 31)
1169                    .unwrap()
1170                    .and_hms_nano_opt(23, 59, 59, 7)
1171                    .unwrap()
1172            )
1173            .ok(),
1174            Some(r#""-0001-12-31T23:59:59.000000007""#.into())
1175        );
1176        assert_eq!(
1177            serde_json::to_string(&NaiveDate::MIN.and_hms_opt(0, 0, 0).unwrap()).ok(),
1178            Some(r#""-262143-01-01T00:00:00""#.into())
1179        );
1180        assert_eq!(
1181            serde_json::to_string(
1182                &NaiveDate::MAX.and_hms_nano_opt(23, 59, 59, 1_999_999_999).unwrap()
1183            )
1184            .ok(),
1185            Some(r#""+262142-12-31T23:59:60.999999999""#.into())
1186        );
1187    }
1188
1189    #[test]
1190    fn test_serde_deserialize() {
1191        let from_str = serde_json::from_str::<NaiveDateTime>;
1192
1193        assert_eq!(
1194            from_str(r#""2016-07-08T09:10:48.090""#).ok(),
1195            Some(
1196                NaiveDate::from_ymd_opt(2016, 7, 8)
1197                    .unwrap()
1198                    .and_hms_milli_opt(9, 10, 48, 90)
1199                    .unwrap()
1200            )
1201        );
1202        assert_eq!(
1203            from_str(r#""2016-7-8T9:10:48.09""#).ok(),
1204            Some(
1205                NaiveDate::from_ymd_opt(2016, 7, 8)
1206                    .unwrap()
1207                    .and_hms_milli_opt(9, 10, 48, 90)
1208                    .unwrap()
1209            )
1210        );
1211        assert_eq!(
1212            from_str(r#""2014-07-24T12:34:06""#).ok(),
1213            Some(NaiveDate::from_ymd_opt(2014, 7, 24).unwrap().and_hms_opt(12, 34, 6).unwrap())
1214        );
1215        assert_eq!(
1216            from_str(r#""0000-01-01T00:00:60""#).ok(),
1217            Some(
1218                NaiveDate::from_ymd_opt(0, 1, 1)
1219                    .unwrap()
1220                    .and_hms_milli_opt(0, 0, 59, 1_000)
1221                    .unwrap()
1222            )
1223        );
1224        assert_eq!(
1225            from_str(r#""0-1-1T0:0:60""#).ok(),
1226            Some(
1227                NaiveDate::from_ymd_opt(0, 1, 1)
1228                    .unwrap()
1229                    .and_hms_milli_opt(0, 0, 59, 1_000)
1230                    .unwrap()
1231            )
1232        );
1233        assert_eq!(
1234            from_str(r#""-0001-12-31T23:59:59.000000007""#).ok(),
1235            Some(
1236                NaiveDate::from_ymd_opt(-1, 12, 31)
1237                    .unwrap()
1238                    .and_hms_nano_opt(23, 59, 59, 7)
1239                    .unwrap()
1240            )
1241        );
1242        assert_eq!(
1243            from_str(r#""-262143-01-01T00:00:00""#).ok(),
1244            Some(NaiveDate::MIN.and_hms_opt(0, 0, 0).unwrap())
1245        );
1246        assert_eq!(
1247            from_str(r#""+262142-12-31T23:59:60.999999999""#).ok(),
1248            Some(NaiveDate::MAX.and_hms_nano_opt(23, 59, 59, 1_999_999_999).unwrap())
1249        );
1250        assert_eq!(
1251            from_str(r#""+262142-12-31T23:59:60.9999999999997""#).ok(), // excess digits are ignored
1252            Some(NaiveDate::MAX.and_hms_nano_opt(23, 59, 59, 1_999_999_999).unwrap())
1253        );
1254
1255        // bad formats
1256        assert!(from_str(r#""""#).is_err());
1257        assert!(from_str(r#""2016-07-08""#).is_err());
1258        assert!(from_str(r#""09:10:48.090""#).is_err());
1259        assert!(from_str(r#""20160708T091048.090""#).is_err());
1260        assert!(from_str(r#""2000-00-00T00:00:00""#).is_err());
1261        assert!(from_str(r#""2000-02-30T00:00:00""#).is_err());
1262        assert!(from_str(r#""2001-02-29T00:00:00""#).is_err());
1263        assert!(from_str(r#""2002-02-28T24:00:00""#).is_err());
1264        assert!(from_str(r#""2002-02-28T23:60:00""#).is_err());
1265        assert!(from_str(r#""2002-02-28T23:59:61""#).is_err());
1266        assert!(from_str(r#""2016-07-08T09:10:48,090""#).is_err());
1267        assert!(from_str(r#""2016-07-08 09:10:48.090""#).is_err());
1268        assert!(from_str(r#""2016-007-08T09:10:48.090""#).is_err());
1269        assert!(from_str(r#""yyyy-mm-ddThh:mm:ss.fffffffff""#).is_err());
1270        assert!(from_str(r#"20160708000000"#).is_err());
1271        assert!(from_str(r#"{}"#).is_err());
1272        // pre-0.3.0 rustc-serialize format is now invalid
1273        assert!(from_str(r#"{"date":{"ymdf":20},"time":{"secs":0,"frac":0}}"#).is_err());
1274        assert!(from_str(r#"null"#).is_err());
1275    }
1276
1277    // Bincode is relevant to test separately from JSON because
1278    // it is not self-describing.
1279    #[test]
1280    fn test_serde_bincode() {
1281        let dt =
1282            NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_milli_opt(9, 10, 48, 90).unwrap();
1283        let encoded = serialize(&dt).unwrap();
1284        let decoded: NaiveDateTime = deserialize(&encoded).unwrap();
1285        assert_eq!(dt, decoded);
1286    }
1287
1288    #[test]
1289    fn test_serde_bincode_optional() {
1290        #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
1291        struct Test {
1292            one: Option<i64>,
1293            #[serde(with = "ts_nanoseconds_option")]
1294            two: Option<DateTime<Utc>>,
1295        }
1296
1297        let expected =
1298            Test { one: Some(1), two: Some(Utc.with_ymd_and_hms(1970, 1, 1, 0, 1, 1).unwrap()) };
1299        let bytes: Vec<u8> = serialize(&expected).unwrap();
1300        let actual = deserialize::<Test>(&(bytes)).unwrap();
1301
1302        assert_eq!(expected, actual);
1303    }
1304}