Chrono + Serde in Rust
By default, serde
serializes its values (eg, Date
, DateTime
) as strings. To save space, particularly when using rmp_serde
, chrono::serde
lets you apply with = ...
to serialize as seconds, millisec, or nanosec from the epoch:
Cargo.toml
[dependencies]
chrono = { version = "0.4.19", features = ["serde"] }
rmp-serde = "0.15.5"
serde = {version = "1.0.106", features = ["derive"]}
serde_json = "1.0.51"
main.rs
use chrono::{serde::ts_seconds, DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct Record {
#[serde(with = "ts_seconds")]
ts: DateTime<Utc>,
}
fn main() {
// Input value
let s = "2021-08-28T02:58:17Z";
// Serialize
let d = chrono::DateTime::parse_from_rfc3339(s).unwrap();
let ts: DateTime<Utc> = d.into();
let rec = Record { ts };
let j = serde_json::to_string(&rec).unwrap();
// Using `ts_seconds`, the datetime is serialized to a number:
assert_eq!(r#"{"ts":1630119497}"#, j);
// Without `ts_seconds`, this would be serialized instead as: r#"{"ts":"2021-08-28T02:58:17Z"}"#
// Deserialize
let Record { ts } = serde_json::from_str(&j).unwrap();
let ss = ts.to_rfc3339();
// Explicit timezone is used instead of `Z` for UTC.
assert_eq!("2021-08-28T02:58:17+00:00", ss);
}