time/serde/timestamp/microseconds.rs
1//! Treat an [`OffsetDateTime`] as a [Unix timestamp] with microseconds for
2//! the purposes of serde.
3//!
4//! Use this module in combination with serde's [`#[with]`][with] attribute.
5//!
6//! When deserializing, the offset is assumed to be UTC.
7//!
8//! [Unix timestamp]: https://en.wikipedia.org/wiki/Unix_time
9//! [with]: https://serde.rs/field-attrs.html#with
10
11use serde_core::{Deserialize, Deserializer, Serialize, Serializer};
12
13use crate::OffsetDateTime;
14use crate::error::ComponentRange;
15
16/// Serialize an `OffsetDateTime` as its Unix timestamp with microseconds
17#[inline]
18pub fn serialize<S>(datetime: &OffsetDateTime, serializer: S) -> Result<S::Ok, S::Error>
19where
20 S: Serializer,
21{
22 let timestamp = datetime.unix_timestamp_nanos() / 1_000;
23 timestamp.serialize(serializer)
24}
25
26/// Deserialize an `OffsetDateTime` from its Unix timestamp with microseconds
27#[inline]
28pub fn deserialize<'a, D>(deserializer: D) -> Result<OffsetDateTime, D::Error>
29where
30 D: Deserializer<'a>,
31{
32 let value: i128 = <_>::deserialize(deserializer)?;
33 OffsetDateTime::from_unix_timestamp_nanos(value * 1_000).map_err(ComponentRange::into_de_error)
34}
35
36/// Treat an `Option<OffsetDateTime>` as a [Unix timestamp] with microseconds
37/// for the purposes of serde.
38///
39/// Use this module in combination with serde's [`#[with]`][with] attribute.
40///
41/// Note: Due to [serde-rs/serde#2878], you will need to apply `#[serde(default)]` if you want a
42/// missing field to deserialize as `None`.
43///
44/// When deserializing, the offset is assumed to be UTC.
45///
46/// [Unix timestamp]: https://en.wikipedia.org/wiki/Unix_time
47/// [with]: https://serde.rs/field-attrs.html#with
48/// [serde-rs/serde#2878]: https://github.com/serde-rs/serde/issues/2878
49pub mod option {
50 use super::*;
51
52 /// Serialize an `Option<OffsetDateTime>` as its Unix timestamp with microseconds
53 #[inline]
54 pub fn serialize<S>(option: &Option<OffsetDateTime>, serializer: S) -> Result<S::Ok, S::Error>
55 where
56 S: Serializer,
57 {
58 option
59 .map(|timestamp| timestamp.unix_timestamp_nanos() / 1_000)
60 .serialize(serializer)
61 }
62
63 /// Deserialize an `Option<OffsetDateTime>` from its Unix timestamp with microseconds
64 #[inline]
65 pub fn deserialize<'a, D>(deserializer: D) -> Result<Option<OffsetDateTime>, D::Error>
66 where
67 D: Deserializer<'a>,
68 {
69 Option::deserialize(deserializer)?
70 .map(|value: i128| OffsetDateTime::from_unix_timestamp_nanos(value * 1_000))
71 .transpose()
72 .map_err(ComponentRange::into_de_error)
73 }
74}