[英]Rust chrono::NaiveTime::parse_from_str() fails to parse PM
[英]Call to NaiveDateTime::parse_from_str fails when invoked at one place but works from other point
我正在嘗試實現一個例程,該例程讀取 JSON 中具有“@timestamp”鍵的文件。 我需要將時間戳從類似於“2022-01-19T18:15:36.283Z”的格式轉換為紀元時間(自 1970 年 1 月 1 日以來的毫秒)。 Rust代碼如下:
use chrono::*;
use serde_json::{Result, Value};
fn convert_to_epoch(ddd: &str) -> i64 {
println!(">>>> {}", ddd);
let tmp = NaiveDateTime::parse_from_str(ddd, "%Y-%m-%dT%H:%M:%S%.3fZ");
println!(">>>> {:?}", tmp);
let epoch_time = tmp.unwrap();
return epoch_time.timestamp_millis();
}
fn get_ts(v: &Value) -> (bool, String) {
if let Some(field) = v.get("@timestamp") {
return (true, field.to_string());
} else {
if let Some(field) = v.get("date") {
return (true, field.to_string());
} else {
if let Some(field) = v.get("timestamp") {
return (true, field.to_string());
} else {
if let Some(field) = v.get("time") {
return (true, field.to_string());
} else {
return (false, "".to_string());
}
}
}
}
}
fn parse_file() -> Result<()> {
let filepath = "/tmp/input.txt";
println!("######## filepath={}", filepath);
let data = std::fs::read_to_string(filepath).expect("file not found!");
let lines = data.lines();
for line in lines {
if line.starts_with('{') && line.ends_with('}') {
let v: Value = serde_json::from_str(line)?;
let (exists, ts) = get_ts(&v);
if !exists {
println!("ts not found");
} else {
println!("{}", ts);
}
let ddd = String::from(ts);
let epoch_time = convert_to_epoch(&ddd);
println!("{}", epoch_time);
} else {
println!("Found a non JSON line: {}", line);
}
}
let ddd = String::from("2022-01-19T18:15:36.283Z");
let epoch_time = convert_to_epoch(&ddd);
println!("{:?}", epoch_time);
Ok(())
}
fn main() {
let _result = parse_file();
}
當我按原樣運行代碼時,它會恐慌並打印以下內容:
Compiling p1 v0.1.0 (/Users/abc/rust/p1)
Finished dev [unoptimized + debuginfo] target(s) in 1.24s
Running `target/debug/p1`
######## filepath=/tmp/input.txt
"2022-01-19T18:15:36.283Z"
>>>> "2022-01-19T18:15:36.283Z"
>>>> Err(ParseError(Invalid))
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ParseError(Invalid)', src/main.rs:8:26
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
但是當我注釋掉第 46、47 和 48 行時,第 53、54 和 55 行的代碼執行得很好,並打印出以下內容:
Compiling p1 v0.1.0 (/Users/abc/rust/p1)
Finished dev [unoptimized + debuginfo] target(s) in 0.40s
Running `target/debug/p1`
######## filepath=/tmp/input.txt
"2022-01-19T18:15:36.283Z"
"2022-01-19T18:15:36.298Z"
"2022-01-19T18:15:41.161Z"
"2022-01-19T18:15:41.164Z"
"2022-01-19T18:16:38.281Z"
>>>> 2022-01-19T18:15:36.283Z
>>>> Ok(2022-01-19T18:15:36.283)
1642616136283
據我所知,第 46 到 48 行的代碼與第 53 到 55 行的代碼相同。第 53 到 55 行的調用有效,但第 46 到 48 行的調用失敗。
input.txt文件內容如下:
{"@timestamp":"2022-01-19T18:15:36.283Z"}
{"@timestamp":"2022-01-19T18:15:36.298Z"}
{"@timestamp":"2022-01-19T18:15:41.161Z"}
{"@timestamp":"2022-01-19T18:15:41.164Z"}
{"@timestamp":"2022-01-19T18:16:38.281Z"}
我能夠檢測並解決問題。 出於某種原因,行let ddd = String::from(ts);
導致 ddd 在字符串的開頭和結尾有雙引號。 當我修改該行以let ddd = String::from(ts).replace("\"", "");
時,它不再崩潰。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.