• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use core::fmt;
2 use serde::{de, ser};
3 
4 use 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.
9 impl ser::Serialize for NaiveDateTime {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,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<D: fmt::Debug> fmt::Display for FormatWrapped<'_, 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 
28 struct NaiveDateTimeVisitor;
29 
30 impl de::Visitor<'_> for NaiveDateTimeVisitor {
31     type Value = NaiveDateTime;
32 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result33     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
34         formatter.write_str("a formatted date and time string")
35     }
36 
visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: de::Error,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 
45 impl<'de> de::Deserialize<'de> for NaiveDateTime {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: de::Deserializer<'de>,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 /// ```
80 pub 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     /// ```
serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,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     /// ```
deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error> where D: de::Deserializer<'de>,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::Visitor<'_> for NanoSecondsTimestampVisitor {
165         type Value = NaiveDateTime;
166 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result167         fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
168             formatter.write_str("a unix timestamp")
169         }
170 
visit_i64<E>(self, value: i64) -> Result<Self::Value, E> where E: de::Error,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 
visit_u64<E>(self, value: u64) -> Result<Self::Value, E> where E: de::Error,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 /// ```
224 pub 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     /// ```
serialize<S>(opt: &Option<NaiveDateTime>, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,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     /// ```
deserialize<'de, D>(d: D) -> Result<Option<NaiveDateTime>, D::Error> where D: de::Deserializer<'de>,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 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result316         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
visit_some<D>(self, d: D) -> Result<Self::Value, D::Error> where D: de::Deserializer<'de>,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
visit_none<E>(self) -> Result<Self::Value, E> where E: de::Error,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
visit_unit<E>(self) -> Result<Self::Value, E> where E: de::Error,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 /// ```
372 pub 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     /// ```
serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,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     /// ```
deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error> where D: de::Deserializer<'de>,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::Visitor<'_> for MicroSecondsTimestampVisitor {
447         type Value = NaiveDateTime;
448 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result449         fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
450             formatter.write_str("a unix timestamp")
451         }
452 
visit_i64<E>(self, value: i64) -> Result<Self::Value, E> where E: de::Error,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 
visit_u64<E>(self, value: u64) -> Result<Self::Value, E> where E: de::Error,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 /// ```
506 pub 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     /// ```
serialize<S>(opt: &Option<NaiveDateTime>, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,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     /// ```
deserialize<'de, D>(d: D) -> Result<Option<NaiveDateTime>, D::Error> where D: de::Deserializer<'de>,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 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result588         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
visit_some<D>(self, d: D) -> Result<Self::Value, D::Error> where D: de::Deserializer<'de>,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
visit_none<E>(self) -> Result<Self::Value, E> where E: de::Error,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
visit_unit<E>(self) -> Result<Self::Value, E> where E: de::Error,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 /// ```
642 pub 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     /// ```
serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,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     /// ```
deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error> where D: de::Deserializer<'de>,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::Visitor<'_> for MilliSecondsTimestampVisitor {
717         type Value = NaiveDateTime;
718 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result719         fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
720             formatter.write_str("a unix timestamp")
721         }
722 
visit_i64<E>(self, value: i64) -> Result<Self::Value, E> where E: de::Error,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 
visit_u64<E>(self, value: u64) -> Result<Self::Value, E> where E: de::Error,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 /// ```
770 pub 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     /// ```
serialize<S>(opt: &Option<NaiveDateTime>, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,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     /// ```
deserialize<'de, D>(d: D) -> Result<Option<NaiveDateTime>, D::Error> where D: de::Deserializer<'de>,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 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result852         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
visit_some<D>(self, d: D) -> Result<Self::Value, D::Error> where D: de::Deserializer<'de>,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
visit_none<E>(self) -> Result<Self::Value, E> where E: de::Error,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
visit_unit<E>(self) -> Result<Self::Value, E> where E: de::Error,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 /// ```
905 pub 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     /// ```
serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,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     /// ```
deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error> where D: de::Deserializer<'de>,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::Visitor<'_> for SecondsTimestampVisitor {
972         type Value = NaiveDateTime;
973 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result974         fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
975             formatter.write_str("a unix timestamp")
976         }
977 
visit_i64<E>(self, value: i64) -> Result<Self::Value, E> where E: de::Error,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 
visit_u64<E>(self, value: u64) -> Result<Self::Value, E> where E: de::Error,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 /// ```
1027 pub 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     /// ```
serialize<S>(opt: &Option<NaiveDateTime>, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,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     /// ```
deserialize<'de, D>(d: D) -> Result<Option<NaiveDateTime>, D::Error> where D: de::Deserializer<'de>,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 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result1099         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
visit_some<D>(self, d: D) -> Result<Self::Value, D::Error> where D: de::Deserializer<'de>,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
visit_none<E>(self) -> Result<Self::Value, E> where E: de::Error,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
visit_unit<E>(self) -> Result<Self::Value, E> where E: de::Error,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)]
1130 mod 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]
test_serde_serialize()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]
test_serde_deserialize()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]
test_serde_bincode()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]
test_serde_bincode_optional()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 }
1305