【问题标题】:How to get the difference between two chrono dates?如何获得两个计时日期之间的差异?
【发布时间】:2020-11-08 13:32:03
【问题描述】:

我想以这种格式获得今天08/11/202001/01/1970 之间的“时间跨度”差异:

Timespan:
50 year(s) 10 month(s) 7 day(s)

下面的代码正确计算了:today - 01/01/1970。但是,对于像 23/12/1970 给予这样的输入,它会惨遭失败:

50 year(s) -1 month(s) -15 day(s)

而预期的结果是49 year(s) 10 month(s) 16 day(s)

更多测试日期:

  • 09/01/1985

    得到:35 year(s) 10 month(s) -1 day(s) 但预期为35 year(s) 9 month(s) 30 day(s)

  • 24/02/1936

    得到:84 year(s) 9 month(s) -16 day(s) 但预期为84 year(s) 8 month(s) 15 day(s)

Cargo.toml:

[package]
name = "relative-delta"
version = "0.1.0"
authors = ["baduker"]
edition = "2018"

[dependencies]
chrono = "0.4.19"

代码:

use chrono::{NaiveDateTime, DateTime, Utc, Datelike};

fn main() {
    let date_string = "23/12/1970";
    let naive_date = chrono::NaiveDate::parse_from_str(date_string, "%d/%m/%Y").unwrap();
    let naive_datetime: NaiveDateTime = naive_date.and_hms(0, 0, 0);
    let date = DateTime::<Utc>::from_utc(naive_datetime, Utc);

    let years = Utc::now().year() - date.year();
    let months = Utc::now().month() as i64 - date.month() as i64;
    let days = Utc::now().day() as i64 - date.day() as i64;

    println!("Timespan:\n{} year(s) {} month(s) {} day(s)", years, months, days);
}

【问题讨论】:

  • 注意:Utc::now() 可以在计算过程中切换日期。在玩弄时间时,重要的是要非常明确地说明何时创建一个新时间,并避免重复创建它们。
  • 我认为您的问题与以下问题有关,尚未实施。 github.com/chronotope/chrono/issues/416也许你可以和维护者一起在 GitHub 上参与。
  • Utc::now().month() as i64 - date.month() as i64; 你是否希望这总是非负数,如果是这样,应该用什么样的黑魔法来负责?

标签: date datetime rust


【解决方案1】:

您的计算对我来说没有意义,例如如果今天的日期是 2021 年 11 月 1 日,您的计算将返回 1 - 23 = -22 作为天数。今天是我学习 Rust 的第三天,因此我没有足够的专业知识来为您提供优化的解决方案。但是,如果您假设一年是 365 天,一个月是 30 天,那么下面的解决方案应该可以满足您的要求。

use chrono::{DateTime, Utc};

fn main() {
    // Tests
    print_diff("23/12/1970");
}

fn print_diff(date_string: &str) {
    let today = Utc::now();

    let datetime =
        DateTime::<Utc>::from_utc(chrono::NaiveDate::parse_from_str(date_string, "%d/%m/%Y")
            .unwrap()
            .and_hms(0, 0, 0), Utc);

    let diff = today.signed_duration_since(datetime);
    let days = diff.num_days();
    let years = days / 365;
    let remaining_days = days % 365;
    let months = remaining_days / 30;
    let days = remaining_days % 30;

    println!("{} years {} months {} days", years, months, days);
}

输出:

50 years 11 months 9 days

Playground

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-15
    • 1970-01-01
    相关资源
    最近更新 更多