我想解析这个字符串:1595879159050208。这是我尝试过的。
use chrono::prelude::*;
fn main() {
let utc: DateTime<Utc> = Utc::now();
let format = "%s%6f";
let string = utc.format(format).to_string();
println!("{}", string); // 1595879159050208
let parsed = DateTime::parse_from_str(&string, format);
println!("{:?}", parsed); // Err(ParseError(TooShort))
}
Run Code Online (Sandbox Code Playgroud)
为什么这不起作用?
Chrono 0.4
rustc 1.41.0
Run Code Online (Sandbox Code Playgroud)
小智 6
您可以在解析函数文档中看到,该函数在遵守固有解析宽度的同时是贪婪的,这意味着当“匹配”您的格式时,它将尝试从左到右消耗最多的字符,尊重最大值。由于 unix 时间戳 (%s) 没有最大字符数,您可以在源代码中看到允许的最大字符数是 usize::MAX (至少为 65535)。在此示例中,整个字符串 (1595879159050208) 被用作时间戳Tue May 12 02:50:08 50573367 UTC(非常遥远的未来),而无法找到剩余的数字 (%6f)。
我们可以通过在您的格式中添加一个空格来测试这一点:"%s %6f"。在这种情况下,会出现一个新错误 ( ParseError(NotEnough)),使用DateTime::parse_from_str docs可以更好地解释该错误:
\n\n请注意,此方法需要字符串中包含时区。请参阅 NaiveDateTime::parse_from_str 了解不需要在要解析的 str 中包含时区的版本。
\n
所以使用 NaiveDateTime:
\nuse chrono::prelude::*;\n\nfn main() {\n let utc: DateTime<Utc> = Utc::now();\n let format = "%s %6f";\n let string = utc.format(format).to_string();\n println!("{}", string); // 1595902520 811515\n let parsed = NaiveDateTime::parse_from_str(&string, format);\n println!("{:?}", parsed); // Ok(2020-07-28T02:15:20.811515)\n}\nRun Code Online (Sandbox Code Playgroud)\n不幸的是,您想要解析不带空格的原始字符串。为此,我认为你可以:
\nparse_from_str,只需使用格式化%s使用第二个选项:
\nuse chrono::prelude::*;\n\nfn main() {\n let utc: DateTime<Utc> = Utc::now();\n let format = "%s%6f";\n let string = utc.format(format).to_string();\n println!("{}", string); // 1595904294646258\n\n let secs = string[..string.len() - 6].parse();\n let microsecs = string[string.len() - 6..].parse::<u32>();\n let parsed = match (secs, microsecs) {\n (Ok(s), Ok(us)) => NaiveDateTime::from_timestamp_opt(s, us * 1000),\n _ => None,\n };\n println!("{:?}", parsed); // Some(2020-07-28T02:44:54.646258)\n}\nRun Code Online (Sandbox Code Playgroud)\n