user2138149
user2138149

Reputation: 17384

How to deserialize a JSON encoded DateTime with a specified Timezone in Rust with serde?

Here is a JSON encoded object with a datetime and timezone. I believe this is an ISO 8601 format with 6 digits of precision for fractions of a second. (Microsecond precision.)

{
    "time": "2024-08-06T11:49:09.529856Z"
}

This is how I currently deserialize this structure in Rust code:

use std::str::FromStr;
use serde::Serialize;
use serde::Deserialize;

#[derive(Serialize, Deserialize, Clone)]
struct MyStruct {
    time: chrono::DateTime<chrono::offset::Utc>,
}

let serialized = r'{"time":"2024-08-06T11:49:09.529856Z"}';

let deserialized =
    serde_json::from_str::<MyStruct>(&serialized)
    .expect("failed to deserialize");

It seems strange to have to specify the datetime timezone offset as part of the chrono::DateTime type, considering that this information is part of the encoded string data, and not part of the DateTime type.

What am I doing wrong here?

Upvotes: 1

Views: 268

Answers (2)

Chayim Friedman
Chayim Friedman

Reputation: 71525

The DateTime will be converted to UTC, keeping the same time but changing the timezone.

If you want to keep the timezone, use FixedOffset instead:

#[derive(Serialize, Deserialize, Clone)]
struct MyStruct {
    time: chrono::DateTime<chrono::offset::FixedOffset>,
}

Upvotes: 0

gnasher729
gnasher729

Reputation: 52622

There is no standard JSON date time format. A commonly used one is the one you showed. The number of decimals for the seconds is usually some fixed number (in your case six digits = microseconds). The last letter Z is the time zone. Z stands for UTC but any letter is allowed and should be handled.

You might also get time since some starting date in milliseconds or nanoseconds, if the date is created by windows. So best is to have one method that tries different formats until you find one that matches, unless the format is clearly documented.

(As far as JSON is concerned you have a string, but windows time might be a large integer).

Upvotes: -2

Related Questions