簡體   English   中英

在一個地方調用 NaiveDateTime::parse_from_str 失敗,但在另一點工作

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM