![](/img/trans.png)
[英]Rust Chrono parse date String, ParseError(NotEnough) and ParseError(TooShort)
[英]Rust: DateTime::parse_from_rfc3339 gives ParseError(Invalid)
我正在嘗試使用 Bungie API 獲取一些數據。 json 響應中有上次播放日期,格式為“2022-09-18T02:17:59Z”。 我想解析它並創建 DateTime object。
我有以下代碼(個人數據替換為 XXX):
const API_ROOT: &str = "https://www.bungie.net/Platform";
const API_KEY_HEADER: &str = "X-API-Key";
const MY_API_KEY: &str = "XXX";
const MEMBERSHIP_TYPE: &str = "XXX";
const MEMBERSHIP_ID: &str = "XXX";
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let url = format!("{}/Destiny2/{}/Profile/{}/?components=100", API_ROOT, MEMBERSHIP_TYPE, MEMBERSHIP_ID);
let req = reqwest::Client::new()
.get(url)
.header(API_KEY_HEADER, MY_API_KEY)
.send()
.await?
.text()
.await?;
let data: JsonValue = serde_json::from_str(&req).expect("Failed to read json from response!");
let name = &data["Response"]["profile"]["data"]["userInfo"]["displayName"].to_string();
println!("Name: {}", name);
let last_played_raw = &data["Response"]["profile"]["data"]["dateLastPlayed"].to_string();
println!("{}", last_played_raw);
let last_played_raw = last_played_raw.replace("Z", "+00:00");
println!("{}", last_played_raw);
let last_played = DateTime::parse_from_rfc3339(&last_played_raw).unwrap();
println!("Last played: {}", last_played);
Ok(())
}
問題是解析 last_played_raw 字符串恐慌:
"2022-09-18T02:17:59Z"
"2022-09-18T02:17:59+00:00"
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ParseError(Invalid)', src\main.rs:37:70
有人可以告訴我,有什么問題嗎?
發生這種情況的原因相當簡單。 發生這種情況是因為前導引號和尾隨引號 ( "
) 包含在您傳遞給DateTime::parse_from_rfc3339()
的字符串中。可能解決此問題的最不尖銳的更改是將這些替換為空字符串文字,如下所示:
extern crate serde_json;
extern crate serde;
use serde_json::Value as JsonValue;
use chrono::DateTime;
fn main() {
let json_string = r#"{"dateLastPlayed": "2022-09-18T02:17:59Z"}"#;
let data: JsonValue = serde_json::from_str(json_string).unwrap();
let last_played = data["dateLastPlayed"].to_string().replace("\"", "");
println!("{}", last_played.as_str());
let datetime = DateTime::parse_from_rfc3339(last_played.as_str()).expect("Failed to parse");
println!("{}", datetime);
}
這是指向操場的鏈接,您可以在其中輕松查看。
但是在serde
中,您通常不使用原始Value
,而是像這樣處理反序列化:
use serde::Deserialize;
use chrono::DateTime;
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct MyData {
date_last_played: String,
}
fn main() {
let json_string = r#"{"dateLastPlayed": "2022-09-18T02:17:59Z"}"#;
let data: MyData = serde_json::from_str(json_string).unwrap();
let datetime = DateTime::parse_from_rfc3339(data.date_last_played.as_str()).expect("Failed to parse");
println!("{}", datetime);
}
這是上面的操場。
您還應該能夠使用此結構直接解析 JSON
struct MyData {
date_last_played: DateTime,
}
這將是首選,但您需要一個自定義的 serde Deserializer
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.