time - 如何解析自纪元以来格式为微秒的时间戳?
问题描述
我想解析这个字符串: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
解决方案
您可以在解析函数文档中看到该函数在遵守内在解析宽度的同时是贪婪的,这意味着当“匹配”您的格式时,它将尝试从左到右消耗最多的字符,同时尊重最大值。由于 unix 时间戳 (%s) 没有最大字符数,您可以在源代码中看到允许的最大字符数是 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)
}
不幸的是,您想解析没有空格的原始字符串。为此,我认为您可以:
- 使用标准库将字符串解析为 i64 作为 µs 并使用 NaiveDateTime::from_timestamp 从那里计算秒数/纳秒数
- 对字符串进行切片并分别解析秒/微秒
- 如果您不关心亚秒级精度,请将原始字符串的一部分传递给
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)
}
推荐阅读
- c# - 在 Bootstrap 选项卡之间切换
- caching - Travis CI 在指定位置缓存单个文件
- r - ggplot2的并排饼图
- kendo-ui - Angular 中的 KendoUI Grid 聚合
- java - Apache Camel 如何获取输入的 xml 有效负载大小?
- c# - ASP.NET Web 应用程序在另一个项目上异步调用 Main() 方法 C#
- sql - 如何根据variationID获取每个分类帐的最新记录
- python - 如何使用 python 烧瓶从路线返回日期时间
- sql - SQL更新表依赖于另一个表
- vb.net - 如何在文本文件中搜索两个都是可选的但您必须至少需要其中一个的东西?