如何使用 Rust chrono 获得 1 天的持续时间?

Posted

技术标签:

【中文标题】如何使用 Rust chrono 获得 1 天的持续时间?【英文标题】:How to get a duration of 1 day with Rust chrono? 【发布时间】:2020-04-26 23:19:18 【问题描述】:

我正在处理一些适用于天数的 Rust 代码,但 Duration::days(n) 的实现是,根据文档 n * 24 * 60 * 60 秒,这不是 n 天,因为并非所有天都是 24 * 60 * 60 秒。

这种行为有据可查:

pub fn days(days: i64) -> Duration

用给定的天数创建一个新的Duration。相当于 Duration::seconds(days * 24 * 60 * 60) 带有溢出检查。恐慌 当持续时间超出范围时。

Rust Chrono 有没有办法获得严格来说是 1 天而不是秒数并且与 DateTime 类型兼容的持续时间?并非所有天的秒数都相同。 secondsdays 是完全不同的单位。如果有这样的函数,那么下面的结果总是会在第二天的同一时间得到结果?

let start = Local.now();
let one_day_later = start + function_that_returns_a_duration_of_days(1);

同样,Duration:days(1) 不是这样的函数,因为它返回 1 * 24 * 60 * 60 秒,而不是 1 天

例如,将 TZ 设置为 America/Denver 如下:

let start = Local.ymd(2019, 3, 10).and_hms(0, 0, 0);
println!("start: ", start);
let end = Local.ymd(2019, 3, 11).and_hms(0, 0, 0);
println!("end: ", end);
let elapsed_seconds = end.timestamp() - start.timestamp();
println!("elapsed_seconds: ", elapsed_seconds);
let end2 = start + Duration::days(1);
println!("end2: ", end2);
let elapsed_seconds2 = end2.timestamp() - start.timestamp();
println!("elapsed_seconds2: ", elapsed_seconds2);

返回:

start: 2019-03-10 00:00:00 -07:00
end: 2019-03-11 00:00:00 -06:00
elapsed_seconds: 82800
end2: 2019-03-11 01:00:00 -06:00
elapsed_seconds2: 86400

它增加了 86400 秒,而不是 1 天

我可以通过以下方式获得正确结果:

let one_day_later =
    (start.date() + Duration::days(1)).and_hms(start.hour(), start.minute(), start.second());

但我更喜欢一个返回持续时间的函数,并且通常想了解更多关于 Rust Chrono 处理持续时间的功能。它是否有单位不是秒的持续时间?几周、几个月和几年呢,它们的秒数也是可变的。

我可能应该说我不了解 Rust,现在才使用它几天,而且我没有太多阅读源代码。我确实看过它,但由于我对语言的熟悉程度有限,很难理解。

【问题讨论】:

【参考方案1】:

Duration 是一个时间量。没有多少时间在添加到某个瞬间时,总是会在第二天产生相同的时间,因为正如您所注意到的,日历日可能有不同的时间量。

不仅是年、周和日,甚至小时和分钟也不总是包含相同的时间量 (Leap second)。 Duration 是时间量,而不是“日历单位”。所以不,Duration 无法表达“下周同一时间”之类的想法。

表达“第二天同一时间”的最简单方法是使用Date 上的succand_time 方法:

let one_day_later = start.date().succ().and_time(start.time());

如果新日期的时间不存在,and_time 会恐慌。

【讨论】:

非常感谢。我没有看到 succ() 或 and_time() 方法。后者比 .ymd().and_hms() 简洁得多 如果我真的不关心闰秒怎么办?是否有任何图书馆可以让我进行01h45m - 0h55m + 2h37m 之类的计算,结果是一个小时不超过 60 分钟? @Philipp 当然,you can do that calculation with only Durations。夏令时和闰秒等日历问题仅在“三小时”等持续时间时间和“凌晨三点”等即时时间之间转换时才会出现2020 年 3 月 8 日”。 似乎不起作用;如果我执行Duration::minutes(50).checked_add(Duration.minutes(30)) 之类的操作,我会得到 80 分钟和 1 小时的持续时间。我预计 1 小时 20 分钟:Playground @Philipp num_hoursnum_minutes 方法在Duration 上返回持续时间小时或分钟的总数,所以是的,持续时间为 80分钟包含 1 小时(或 4800 秒,或 4800000 毫秒等)。如果你想要 20,你需要做一些数学来减去整个小时,比如(duration - Duration::hours(duration.num_hours())).num_minutes(),或者只是duration.num_minutes() % 60

以上是关于如何使用 Rust chrono 获得 1 天的持续时间?的主要内容,如果未能解决你的问题,请参考以下文章

rust-chrono 中的 ParseError(NotEnough) 是啥意思?

如何从 <chrono> 获取持续时间,如整数毫秒和浮点秒?

Rust Chrono 解析日期字符串、ParseError(NotEnough) 和 ParseError(TooShort)

Rust chrono 给出 ParseError(NotEnough) [重复]

Rust 实现简单区块链

Rust 获取当前系统时间戳