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