chrono/datetime/
serde.rs

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