rust 使用serde从字符串毫秒时间戳反序列化DateTime

8dtrkrch  于 2022-12-19  发布在  其他
关注(0)|答案(1)|浏览(364)

我从外部API接收毫秒时间戳作为JSON字符串属性。

{"time":"1526522699918"}

使用Serde将毫秒时间戳解析为字符串的最佳方法是什么?
ts_milliseconds选项将毫秒时间戳作为整数使用,但在使用字符串时会引发错误。
示例-Rust Playground

#[macro_use]
extern crate serde_derive;
extern crate chrono;
use chrono::serde::ts_milliseconds;
use chrono::{DateTime, Utc};

#[derive(Deserialize, Serialize)]
struct S {
    #[serde(with = "ts_milliseconds")]
    time: DateTime<Utc>,
}

fn main() {
    serde_json::from_str::<S>(r#"{"time":1526522699918}"#).unwrap(); // millisecond timestamp as a integer
    serde_json::from_str::<S>(r#"{"time":"1526522699918"}"#).unwrap(); // millisecond timestamp as an string
}

错误信息:

Error("invalid type: string \"1526522699918\", expected a unix timestamp in milliseconds", line: 1, column: 23)'
vhmi4jdf

vhmi4jdf1#

可以使用serde_with中的TimestampMilliSeconds类型对DateTime的序列化进行抽象。使用该类型,您可以从浮点数、整数或字符串进行序列化/反序列化。您需要为serde_with启用chrono功能。
第一个参数(这里是String)配置序列化行为,在String的情况下,这意味着DateTime将被序列化为一个包含Unix时间戳(毫秒)的字符串。
第二个论点(这里是Flexible)允许配置反序列化行为。Flexible意味着它将从浮点数、整数和字符串反序列化而不返回错误。您可以使用它从问题中获取main函数以运行。另一个选项是Strict,它只反序列化第一个参数的格式。对于这个例子来说,这意味着它只反序列化时间为字符串,但是当遇到整数时会返回一个错误。

use ::chrono::{DateTime, Utc};
use serde_with::TimestampMilliSeconds;
use serde_with::formats::Flexible;

#[serde_with::serde_as]
#[derive(serde::Deserialize, serde::Serialize)]
struct S {
    #[serde_as(as = "TimestampMilliSeconds<String, Flexible>")]
    time: DateTime<Utc>,
}

fn main() {
    serde_json::from_str::<S>(r#"{"time":1526522699918}"#).unwrap(); // millisecond timestamp as a integer
    serde_json::from_str::<S>(r#"{"time":"1526522699918"}"#).unwrap(); // millisecond timestamp as an string
}

相关问题