如何在 Rust 中删除 3 年的日期?

问题描述 投票:0回答:2

我现在正在使用

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 日,那当然不起作用,因为我只是从今天的年份中减去 3 年。

如何从现在的日期减去 3 年?

我去掉365天*3年也够了(不考虑闰年)。

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

date datetime rust rust-chrono
2个回答
0
投票

with_year
的文档明确指出,当“结果日期不存在(非闰年的2月29日)”时,此操作可以返回
None
。还有其他几种情况也会返回
None

很简单,您请求的日期不在日历上,并且没有一种方法可以比任何其他方法更正确地响应此请求。例如,您可能会认为该函数应该只使用 3 月 1 日,但没有特别的理由选择 3 月 1 日而不是 2 月 28 日。

如果您想要 3 月 1 日,那么您只需在日期为 2 月 29 日的情况下提前一天

now
重试该操作即可:

pub fn today_three_years_earlier() -> DateTime<Utc> {
    let now = DateTime::from_timestamp(1_709_228_325, 0).unwrap();

    let from = now
        .with_year(now.year() - 3)
        .unwrap_or_else(|| match (now.month(), now.day()) {
            (2, 29) => (now + Days::new(1)).with_year(now.year() - 3).unwrap(),
            _ => panic!("Cannot subtract 3 years from {now}"),
        });

    from
}

(游乐场)

如果您想要 2 月 28 日,那么只需减去

Days::new(1)
而不是添加它。


0
投票

tl;dr:改为添加 36 个。结果将于2月28日出结果。

结果将被限制为结果月份中的有效天数,请参阅checked_add_months了解详细信息。

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

日历很难。我们的日历充满了不排队的周期,但我们无论如何都试图强迫它。

“去年2月29日是什么日子?”是无法回答的。人类可能会任意决定说 2 月 28 日或 3 月 1 日,但 Rust 不会为你决定,它会返回

None
告诉你它不存在。这记录在
with_year

如果出现以下情况,则返回 None:结果日期不存在(非闰年的 2 月 29 日)。

其他日期更改也有类似问题。如果你把12月31日改成4月。如果您询问美国大部分地区 2024 年 3 月 10 日星期日凌晨 2:30(由于夏令时,凌晨 2 点至凌晨 3 点不存在)。如果您向 UTC 询问美国 2024 年 11 月 3 日星期日凌晨 1:30:00(由于夏令时,凌晨 1:30 出现两次)。等等

添加 12 个月是有效的,因为 Rust 已经决定,如果您要求在 2 月添加 12 个月,您需要在 2 月添加一个日期。

结果将被限制为结果月份中的有效天数,请参阅checked_add_months了解详细信息。

© www.soinside.com 2019 - 2024. All rights reserved.