我想解析以下字符串: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))
}
为什么不起作用?
Chrono 0.4
rustc 1.41.0
答案 0 :(得分:1)
您可以在parsing function documentation中看到该函数在遵循固有解析宽度的情况下是贪婪的,这意味着在“匹配”您的格式时,它将尝试使用尽可能多的字符(从左到右),尊重最大值。由于unix时间戳(%s)没有最大字符数,因此您可以看到in the source允许的最大字符数是usize :: MAX(至少65535)。在此示例中,整个字符串(1595879159050208)被用作时间戳Tue May 12 02:50:08 50573367 UTC
(将来很远的时间),而找不到剩余的数字(%6f)。
我们可以通过在您的格式中添加一个空格进行测试:"%s %6f"
。在这种情况下,将显示一个新错误(ParseError(NotEnough)
),使用DateTime::parse_from_str docs可以更好地解释该错误:
请注意,此方法在字符串中需要一个时区。请参见NaiveDateTime :: parse_from_str,以获取不需要在要解析的str中使用时区的版本。
因此使用NaiveDateTime:
use chrono::prelude::*;
fn main() {
let utc: DateTime<Utc> = Utc::now();
let format = "%s %6f";
let string = utc.format(format).to_string();
println!("{}", string); // 1595902520 811515
let parsed = NaiveDateTime::parse_from_str(&string, format);
println!("{:?}", parsed); // Ok(2020-07-28T02:15:20.811515)
}
不幸的是,您想解析原始字符串,没有空格。为此,我认为您可以:
parse_from_str
,仅用%s
进行格式化使用第二个选项:
use chrono::prelude::*;
fn main() {
let utc: DateTime<Utc> = Utc::now();
let format = "%s%6f";
let string = utc.format(format).to_string();
println!("{}", string); // 1595904294646258
let secs = string[..string.len() - 6].parse();
let microsecs = string[string.len() - 6..].parse::<u32>();
let parsed = match (secs, microsecs) {
(Ok(s), Ok(us)) => NaiveDateTime::from_timestamp_opt(s, us * 1000),
_ => None,
};
println!("{:?}", parsed); // Some(2020-07-28T02:44:54.646258)
}