The difference of 1 day

use std::time::SystemTime;

fn main() {
    let no_leap_second = [
        1970, 1971, 1980, 1984, 1986, 1988, 1991, 1996, 1999, 2000, 2001, 2002, 2003, 2004, 2006,
        2007, 2009, 2010, 2011, 2013, 2014,
    ];
    let sys_time = SystemTime::now();
    println!("Time:{:?}", sys_time); //Time:SystemTime { tv_sec: 1718014136, tv_nsec: 591331000 }
    let duration_since_epoch = sys_time
        .duration_since(SystemTime::UNIX_EPOCH)
        .expect("Time went backwards");

    let mut total_seconds = duration_since_epoch.as_secs();

    let beijing_time = 28800;

    total_seconds += beijing_time;

    let one_year = 365 * 86400;
    let one_leap_year = 366 * 86400;

    let mut year = 1970;

    loop {
        if is_leap_year(year) {
            if total_seconds >= one_leap_year {
                total_seconds -= one_leap_year;
            } else {
                break;
            }
        } else {
            if total_seconds >= one_year {
                total_seconds -= one_year;
            } else {
                break;
            }
        }
        if year == 1972 {
            total_seconds -= 2;
        } else if no_leap_second.contains(&year) {
        } else {
            total_seconds -= 1;
        }
        year += 1;
    }

    let big_month = 31 * 86400;
    let small_month = 30 * 86400;
    let no_leap_month = 28 * 86400;
    let leap_month = 29 * 86400;
    let mut month = 1;
    loop {
        if (is_leap_year(year)) && (month == 2) {
            if total_seconds >= leap_month {
                total_seconds -= leap_month;
            } else {
                break;
            }
        } else if (!is_leap_year(year)) && (month == 2) {
            if total_seconds >= no_leap_month {
                total_seconds -= no_leap_month;
            } else {
                break;
            }
        } else if (month == 4) && (month == 6) && (month == 9) && (month == 11) {
            if total_seconds >= small_month {
                total_seconds -= small_month;
            } else {
                break;
            }
        } else {
            if total_seconds >= big_month {
                total_seconds -= big_month;
            } else {
                break;
            }
        }
        month += 1;
    }

    // 计算日
    let day = total_seconds / 86400 + 1; // 直接计算日,注意加一

    println!("year:{year}");
    println!("month:{month}");
    println!("day:{day}");
}

fn is_leap_year(year: i32) -> bool {
    (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
}

douxiaobo@192 Rust % rustc read_now1.rs
douxiaobo@192 Rust % ./read_now1       
Time:SystemTime { tv_sec: 1718024261, tv_nsec: 366448000 }
year:2024
month:6
day:9

This is Beijing_time, In fact Today is June 10, 2024. I am confused that I can not find any problem in My Rust code.

You have a logic bug

- else if (month == 4) && (month == 6) && (month == 9) && (month == 11) {
+ else if (month == 4) || (month == 6) || (month == 9) || (month == 11) {

This would be more idiomatically written with a match, probably, which may make these kinds of mistakes less likely.

If you need precise time down to the leap second, I wish you good luck. Hopefully there is some library that does this for you, time is incredibly complicated. Also, if I understand correctly, SystemTime does not include leap seconds so you should not have to adjust each year for leap seconds if you are just looking for a date as opposed to an accurate count of how many seconds have passed.

7 Likes

But in Rust every if is a mini-match so you can write:

else if let 4 | 6 | 9 | 11 = month {
3 Likes
douxiaobo@192 Rust % rustc read_now1.rs
douxiaobo@192 Rust % ./read_now1   
Time:SystemTime { tv_sec: 1718027750, tv_nsec: 218054000 }
year:2024
month:6
day:10
douxiaobo@192 Rust % 

I see. I checked that it is Okay. Thank you very much.

Okay, it is simpler, Thank you very much.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.