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