对NaiveDateTime::parse_from_str的调用在一个地方调用时失败,但在另一个地方可以工作



我正在尝试实现一个例程,该例程读取一个具有@时间戳";JSON中的键。我需要将时间戳从类似于";2022-01-19T18:15:36283Z";转换为历元时间(自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在String的开头和结尾都有一个双引号。当我将线路修改为let ddd = String::from(ts).replace(""", "");时,它不再崩溃。

最新更新