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.