1 use core::fmt;
2 use serde::{de, ser};
3 
4 use super::DateTime;
5 use crate::format::{write_rfc3339, SecondsFormat};
6 use crate::naive::datetime::serde::serde_from;
7 #[cfg(feature = "clock")]
8 use crate::offset::Local;
9 use crate::offset::{FixedOffset, Offset, TimeZone, Utc};
10 
11 #[doc(hidden)]
12 #[derive(Debug)]
13 pub struct SecondsTimestampVisitor;
14 
15 #[doc(hidden)]
16 #[derive(Debug)]
17 pub struct NanoSecondsTimestampVisitor;
18 
19 #[doc(hidden)]
20 #[derive(Debug)]
21 pub struct MicroSecondsTimestampVisitor;
22 
23 #[doc(hidden)]
24 #[derive(Debug)]
25 pub struct MilliSecondsTimestampVisitor;
26 
27 /// Serialize into an ISO 8601 formatted string.
28 ///
29 /// See [the `serde` module](./serde/index.html) for alternate
30 /// serializations.
31 impl<Tz: TimeZone> ser::Serialize for DateTime<Tz> {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,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 
52 struct DateTimeVisitor;
53 
54 impl<'de> de::Visitor<'de> for DateTimeVisitor {
55     type Value = DateTime<FixedOffset>;
56 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result57     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 
visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: de::Error,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.
76 impl<'de> de::Deserialize<'de> for DateTime<FixedOffset> {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: de::Deserializer<'de>,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.
91 impl<'de> de::Deserialize<'de> for DateTime<Utc> {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: de::Deserializer<'de>,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")]
108 impl<'de> de::Deserialize<'de> for DateTime<Local> {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: de::Deserializer<'de>,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 /// ```
144 pub 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     /// ```
serialize<S>(dt: &DateTime<Utc>, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,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     /// ```
deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error> where D: de::Deserializer<'de>,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 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result226         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
visit_i64<E>(self, value: i64) -> Result<Self::Value, E> where E: de::Error,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
visit_u64<E>(self, value: u64) -> Result<Self::Value, E> where E: de::Error,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 /// ```
284 pub 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     /// ```
serialize<S>(opt: &Option<DateTime<Utc>>, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,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     /// ```
deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error> where D: de::Deserializer<'de>,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 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result367         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
visit_some<D>(self, d: D) -> Result<Self::Value, D::Error> where D: de::Deserializer<'de>,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
visit_none<E>(self) -> Result<Self::Value, E> where E: de::Error,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
visit_unit<E>(self) -> Result<Self::Value, E> where E: de::Error,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 /// ```
424 pub 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     /// ```
serialize<S>(dt: &DateTime<Utc>, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,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     /// ```
deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error> where D: de::Deserializer<'de>,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 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result495         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
visit_i64<E>(self, value: i64) -> Result<Self::Value, E> where E: de::Error,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
visit_u64<E>(self, value: u64) -> Result<Self::Value, E> where E: de::Error,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 /// ```
553 pub 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     /// ```
serialize<S>(opt: &Option<DateTime<Utc>>, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,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     /// ```
deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error> where D: de::Deserializer<'de>,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 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result625         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
visit_some<D>(self, d: D) -> Result<Self::Value, D::Error> where D: de::Deserializer<'de>,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
visit_none<E>(self) -> Result<Self::Value, E> where E: de::Error,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
visit_unit<E>(self) -> Result<Self::Value, E> where E: de::Error,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 /// ```
682 pub 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     /// ```
serialize<S>(dt: &DateTime<Utc>, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,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     /// ```
deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error> where D: de::Deserializer<'de>,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 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result753         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
visit_i64<E>(self, value: i64) -> Result<Self::Value, E> where E: de::Error,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
visit_u64<E>(self, value: u64) -> Result<Self::Value, E> where E: de::Error,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 /// ```
805 pub 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     /// ```
serialize<S>(opt: &Option<DateTime<Utc>>, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,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     /// ```
deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error> where D: de::Deserializer<'de>,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 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result889         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
visit_some<D>(self, d: D) -> Result<Self::Value, D::Error> where D: de::Deserializer<'de>,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
visit_none<E>(self) -> Result<Self::Value, E> where E: de::Error,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
visit_unit<E>(self) -> Result<Self::Value, E> where E: de::Error,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 /// ```
946 pub 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     /// ```
serialize<S>(dt: &DateTime<Utc>, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,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     /// ```
deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error> where D: de::Deserializer<'de>,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 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result1013         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
visit_i64<E>(self, value: i64) -> Result<Self::Value, E> where E: de::Error,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
visit_u64<E>(self, value: u64) -> Result<Self::Value, E> where E: de::Error,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 /// ```
1069 pub 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     /// ```
serialize<S>(opt: &Option<DateTime<Utc>>, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,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     /// ```
deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error> where D: de::Deserializer<'de>,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 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result1141         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
visit_some<D>(self, d: D) -> Result<Self::Value, D::Error> where D: de::Deserializer<'de>,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
visit_none<E>(self) -> Result<Self::Value, E> where E: de::Error,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
visit_unit<E>(self) -> Result<Self::Value, E> where E: de::Error,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)]
1172 mod 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]
test_serde_serialize()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]
test_serde_deserialize()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]
test_serde_bincode()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]
test_serde_no_offset_debug()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 }
1257