现在我用的是

use chrono::{DateTime, Utc};

pub fn today_three_years_earlier() -> DateTime<Utc> {
    let now = Utc::now();
    
    // this is February 29 and it doesn't work of course
    // let now = DateTime::from_timestamp(1_709_228_325, 0).unwrap();
    
    let from = now.with_year(now.year() - 3).unwrap();

    from
}

但如果现在(今天)是2月29日,它当然不起作用,因为我只是从今天起go 掉3年.

How can I subtract exactly 3 years from now's date?

It would also be enough for me to remove 365 days * 3 years (without considering leap years).

复制数:https://www.rustexplorer.com/b/wkqutm

推荐答案

TL;DR:你可以减go 36Months.结果将是2月28日.

结果将限制为结果月份中的有效天数,有关详细信息,请参阅CHECKED_ADD_MONTS.

now - Months::new(3 * 12);

但是,结果是将两天(2月28日和2月29日)映射到一天(2月28日).根据您的应用程序的不同,这可能会产生负面后果,就像调度软件将两天的工作堆积成一天.在这种情况下,您可能希望捕获None结果并询问用户要做什么(请参见@cdhowie's answer).

通常,您必须考虑日历计算可能会导致日期不存在.


日历是很难做的.我们的日程表上充满了例外、空白和周期,它们并不一致,但我们仍然试图强迫它.

"go 年的2月29日是什么日子?"是无法回答的.人类可能会随意决定说2月28日或3月1日,但铁 rust 不会为你决定这一点,它会返回None,告诉你它不存在.这在with_year中有记录.

在以下情况下返回None:结果日期不存在(非闰年的2月29日).

这是没有办法绕过的.您正在try 将366天映射到365;它不能整齐地将1对1映射.

其他日期更改也有类似的问题.如果你把12月31日改到4月的话.如果你问2024年3月10日周日凌晨2:30,在美国大部分地区(由于夏令时的原因,凌晨2:30到凌晨3:00是不存在的).如果你问UTC 2024年11月3日星期日凌晨1:30:00在美国(因为夏令时,凌晨1:30会发生两次).等.

101(或加上)12个月是可行的,因为chrono的维护人员已经决定,如果你要求在2月份减go 12个月,你想要的日期是2月份.

结果将被限制为结果月份中的有效天数,有关详细信息,请参阅DateTime::Checked_Sub_Monters.

Rust相关问答推荐

如何优化小型固定大小数组中的搜索?

通过解引用将值移出Box(以及它被脱糖到什么地方)?

防止cargo test 中的竞争条件

从Type::new()调用函数

如何在递归数据 struct 中移动所有权时变异引用?

你能在Rust中弃用一个属性吗?

Rust ndarray:如何从索引中 Select 数组的行

为什么将易错函数的泛型结果作为泛型参数传递 infer ()?不应该是暧昧的吗?

这个不安全的 Rust 代码有什么问题,所以它可以在 Windows 上运行,但不能在 Ubuntu 上运行?

无法将`&Vec>`转换为`&[&str]`

`tokio::pin` 如何改变变量的类型?

将原始可变指针传递给 C FFI 后出现意外值

仅在运行测试时生成调试输出

Rust 将特性传递给依赖项

为什么在 rust 中删除 vec 之前应该删除元素

试图理解 Rust 中的可变闭包

Rust,我如何正确释放堆分配的内存?

带有库+多个二进制文件的Cargo 项目,二进制文件由多个文件组成?

有没有办法在 Rust 中对 BigInt 进行正确的位移?

传递 Option<&mut T> 时何时需要 mut