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