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