Search code examples
rustserderfc3339

(De)serialize RFC-3339 timestamp with serde to time-rs OffsetDateTime


My goal is to (de)serialize objects with RFC-3339 timestamps from Json to Rust structs (and vice versa) using serde and time-rs.

I would expect this ...

use serde::Deserialize;
use time::{OffsetDateTime};

#[derive(Deserialize)]
pub struct DtoTest {
    pub timestamp: OffsetDateTime,
}

fn main() {
    let deserialization_result = serde_json::from_str::<DtoTest>("{\"timestamp\": \"2022-07-08T09:10:11Z\"}");
    let dto = deserialization_result.expect("This should not panic");
    println!("{}", dto.timestamp);
}

... to create the struct and display the timestamp as the output, but I get ...

thread 'main' panicked at 'This should not panic: Error("invalid type: string \"2022-07-08T09:10:11Z\", expected an `OffsetDateTime`", line: 1, column: 36)', src/main.rs:12:38
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

My dependencies look like this:

[dependencies]
serde = { version = "1.0.138", features = ["derive"] }
serde_json = "1.0.82"
time = { version = "0.3.11", features = ["serde"] }

According to the documentation of the time-rs crate, this seems to be possible but I must be missing something.


Solution

  • The default serialization format for time is some internal format. If you want other formats, you should enable the serde-well-known feature and use the serde module to choose the format you want:

    #[derive(Deserialize)]
    pub struct DtoTest {
        #[serde(with = "time::serde::rfc3339")]
        pub timestamp: OffsetDateTime,
    }