我现在正在使用
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年也够了(不考虑闰年)。
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)
而不是添加它。
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了解详细信息。