Unix epoch to date 字符串 – 月日略有错误

Unix epoch to date String – Slightly wrong month day

我正在尝试将 SystemTime 格式化为 Rust 中的字符串,而不使用外部板条箱,但我遇到了一个关于 的奇怪问题day 字段。 任何人都可以解释为什么随着与 Thu, 01 Jan 1970 00:00:00 GMT 的时间距离增加,以“FIXME”注释开头的行会产生稍微错误的月份?

fn time_to_http_date_string(time: &SystemTime) -> String {
    const MINUTE: u64 = 60;
    const HOUR: u64 = 3600;
    const DAY: u64 = 86400;
    const WEEKDAYS: [&str; 7] = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
    const MONTH: u64 = 2629743;
    const MONTHS: [&str; 12] = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
    const YEAR: u64 = 31556926;

    let time = time.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs();
    let year = 1970 + (time / YEAR);
    let month = MONTHS[(time % YEAR / MONTH) as usize];
    let weekday = WEEKDAYS[((time / DAY + 4) % 7) as usize];

    // FIXME: Slightly wrong as time distance from the UNIX epoch increases.
    let day = (time % MONTH / DAY) + 1;

    let hour = time % DAY / HOUR;
    let minute = time % HOUR / MINUTE;
    let second = time % MINUTE;

    format!(
        "{weekday}, {day:02} {month} {year} {hour:02}:{minute:02}:{second:02} GMT",
        weekday = weekday,
        day = day,
        month = month,
        year = year,
        hour = hour,
        minute = minute,
        second = second,
    )
}

让我为您提供有关此问题的更多详细信息;这里有一些测试我 运行 这个函数通过:

Unix Timestamp Expected Mine OK
0 Thu, 01 Jan 1970 00:00:00 GMT Thu, 01 Jan 1970 00:00:00 GMT
68169600 Tue, 29 Feb 1972 00:00:00 GMT Tue, 29 Feb 1972 00:00:00 GMT
874540800 Thu, 18 Sep 1997 00:00:00 GMT Thu, 17 Sep 1997 00:00:00 GMT
1052790840 Tue, 13 May 2003 01:54:00 GMT Tue, 11 May 2003 01:54:00 GMT

您可能已经从我的测试用例中注意到,这一天是任何失败案例中 错误的字段。关于罪魁祸首有什么想法吗?

PS:我已经尝试使用 f64 而不是 u64 并对结果进行四舍五入......但它并没有解决所有的测试用例。

原来我在寻找一个不可能的解决方案。如果不考虑闰年和月份不共享以天为单位的相同持续时间这一简单事实,确实不可能执行这样的计算。尽管现在我对发布这个问题感到有点愚蠢,但我还是要感谢最先评论该主题的人。他们把我推向了正确的方向。