`chrono::DateTime<chrono::Utc>` 没有实现特征`std::ops::Add<std::time::Duration>`

Posted

技术标签:

【中文标题】`chrono::DateTime<chrono::Utc>` 没有实现特征`std::ops::Add<std::time::Duration>`【英文标题】:The trait `std::ops::Add<std::time::Duration>` is not implemented for `chrono::DateTime<chrono::Utc>` 【发布时间】:2018-10-11 22:52:13 【问题描述】:
extern crate chrono;
use chrono::DateTime, Utc;
use std::time::Duration;

pub fn after(start: DateTime<Utc>) -> DateTime<Utc> 
    start + Duration::from_secs(1)

失败:

error[E0277]: cannot add `std::time::Duration` to `chrono::DateTime<chrono::Utc>`
 --> src/lib.rs:7:11
  |
7 |     start + Duration::from_secs(1_000_000_000)
  |           ^ no implementation for `chrono::DateTime<chrono::Utc> + std::time::Duration`
  |
  = help: the trait `std::ops::Add<std::time::Duration>` is not implemented for `chrono::DateTime<chrono::Utc>`

我找不到要导入的 Add 的实现。 use chrono::* 无济于事。

我看到 datetime.rs 有一个 Add&lt;chrono::oldtime::Duration&gt; 的 impl,但 oldtime 是私有的,所以我不知道如何创建一个 oldtime::Duration

如何获得我需要的 Add impl?如何将std::time::Duration 转换为chrono::oldtime::Duration?有什么我可以导入来隐式转换的吗?

我正在使用rustc 1.25.0 (84203cac6 2018-03-25)

【问题讨论】:

【参考方案1】:

有函数可以转换from 和to std::time::Duration 所以你可以这样做:

start + ::chrono::Duration::from_std(Duration::from_secs(1)).expect("1s can't overflow")

但如果你可以坚持使用chrono,那就坚持使用chrono

use chrono::DateTime, Utc, Duration;
start + Duration::seconds(1)

【讨论】:

你是对的!我以某种方式假设没有chrono::Duration 顺便说一句,如果“Chrono 当前使用 time::Duration”(@E_net4 的回答),我不明白它是如何在 chrono 命名空间中结束的。我什至可以在std::timechrono::oldtime 的源代码中找到定义的持续时间(IDE 将我带到那里)。但我无法直接在chrono 中看到它。关于 rust 模块的工作原理,我缺少一些东西,我会再次犯这个错误。 @Vituel Crates 可以(并且经常)使用pub use 重新导出内容。 Here 是 Durationchrono 的根中结束的方式。我已经相应地更新了我的答案。【参考方案2】:

这几乎可以用chronodocumentation 的引用来回答:

Chrono 目前使用时间箱中的time::Duration 类型来表示时间跨度的大小。由于它与较新的标准类型具有相同的名称,因此参考将这种类型称为OldDuration。 [...]

Chrono 尚不原生支持标准的Duration 类型,但未来会支持。同时,您可以使用Duration::from_stdDuration::to_std 方法在两种类型之间进行转换。

因此,必须使用 OldDuration 为 Chrono 日期时间添加持续时间,实际上是 exported from the root of the crate,名称为 Duration

use chrono::DateTime, Utc, Duration as OldDuration;

然后,可以通过直接创建OldDuration 来添加持续时间:

pub fn after(start: DateTime<Utc>) -> DateTime<Utc> 
    start + OldDuration::seconds(1)

或者通过转换标准持续时间。

pub fn after(start: DateTime<Utc>) -> DateTime<Utc> 
    start + OldDuration::from_std(Duration::from_secs(1)).unwrap()

这种体验可能会在chrono 达到 1.0.0 之前得到改善。

【讨论】:

该死的,你以更好的答案击败了我 10 秒 :) @mcarton 我通常不是西部最快的枪。但当我是时,我仍然坚持我的标准。 ^_^ 最好拿起我的牛仔帽。

以上是关于`chrono::DateTime<chrono::Utc>` 没有实现特征`std::ops::Add<std::time::Duration>`的主要内容,如果未能解决你的问题,请参考以下文章

如何计算两个 chrono::DateTime 之间的持续时间?

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

如何为计时时间戳使用自定义 serde 反序列化器?

完善tab页面定位

生产者-消费者问题(进程同步问题)

阅读带有以“##”开头的注释行的表格