xref: /DragonOS/kernel/src/time/timeconv.rs (revision 840045af94ea3391f29e87e968db5d9c48316981)
136fd0130Shoumkh use super::syscall::PosixTimeT;
236fd0130Shoumkh /// 一小时所包含的秒数
336fd0130Shoumkh const SECS_PER_HOUR: i64 = 60 * 60;
436fd0130Shoumkh /// 一天所包含的秒数
536fd0130Shoumkh const SECS_PER_DAY: i64 = SECS_PER_HOUR * 24;
636fd0130Shoumkh /// 每年中每个月最后一天所对应天数
736fd0130Shoumkh const MON_OF_YDAY: [[i64; 13]; 2] = [
836fd0130Shoumkh     // 普通年
936fd0130Shoumkh     [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365],
1036fd0130Shoumkh     // 闰年
1136fd0130Shoumkh     [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366],
1236fd0130Shoumkh ];
1336fd0130Shoumkh #[derive(Debug)]
1436fd0130Shoumkh #[allow(dead_code)]
1536fd0130Shoumkh pub struct CalendarTime {
1636fd0130Shoumkh     tm_sec: i32,
1736fd0130Shoumkh     tm_min: i32,
1836fd0130Shoumkh     tm_hour: i32,
1936fd0130Shoumkh     tm_mday: i32,
2036fd0130Shoumkh     tm_mon: i32,
2136fd0130Shoumkh     tm_wday: i32,
2236fd0130Shoumkh     tm_yday: i32,
2336fd0130Shoumkh     tm_year: i32,
2436fd0130Shoumkh }
2536fd0130Shoumkh impl CalendarTime {
new() -> Self2636fd0130Shoumkh     pub fn new() -> Self {
2736fd0130Shoumkh         CalendarTime {
2836fd0130Shoumkh             tm_year: Default::default(),
2936fd0130Shoumkh             tm_sec: Default::default(),
3036fd0130Shoumkh             tm_min: Default::default(),
3136fd0130Shoumkh             tm_hour: Default::default(),
3236fd0130Shoumkh             tm_mday: Default::default(),
3336fd0130Shoumkh             tm_mon: Default::default(),
3436fd0130Shoumkh             tm_wday: Default::default(),
3536fd0130Shoumkh             tm_yday: Default::default(),
3636fd0130Shoumkh         }
3736fd0130Shoumkh     }
3836fd0130Shoumkh }
3936fd0130Shoumkh 
4036fd0130Shoumkh /// # 判断是否是闰年
4136fd0130Shoumkh ///
4236fd0130Shoumkh /// ## 参数
4336fd0130Shoumkh ///
4436fd0130Shoumkh /// * 'year' - 年份
is_leap(year: u32) -> bool4536fd0130Shoumkh fn is_leap(year: u32) -> bool {
4636fd0130Shoumkh     let mut flag = false;
4736fd0130Shoumkh     if (year % 4 == 0 && year % 100 != 0) || year % 400 == 0 {
4836fd0130Shoumkh         flag = true;
4936fd0130Shoumkh     }
5036fd0130Shoumkh     return flag;
5136fd0130Shoumkh }
5236fd0130Shoumkh 
5336fd0130Shoumkh /// # 计算除法
5436fd0130Shoumkh ///
5536fd0130Shoumkh /// # 参数
5636fd0130Shoumkh ///
5736fd0130Shoumkh /// * 'left' - 被除数
5836fd0130Shoumkh /// * 'right' - 除数
math_div(left: u32, right: u32) -> u325936fd0130Shoumkh fn math_div(left: u32, right: u32) -> u32 {
6036fd0130Shoumkh     return left / right;
6136fd0130Shoumkh }
6236fd0130Shoumkh 
6336fd0130Shoumkh /// # 计算两年之间的闰年数目
6436fd0130Shoumkh ///
6536fd0130Shoumkh /// ## 参数
6636fd0130Shoumkh ///
6736fd0130Shoumkh /// * 'y1' - 起始年份
6836fd0130Shoumkh /// * 'y2' - 结束年份
leaps_between(y1: u32, y2: u32) -> u326936fd0130Shoumkh fn leaps_between(y1: u32, y2: u32) -> u32 {
7036fd0130Shoumkh     // 算出y1之前的闰年数量
7136fd0130Shoumkh     let y1_leaps = math_div(y1 - 1, 4) - math_div(y1 - 1, 100) + math_div(y1 - 1, 400);
7236fd0130Shoumkh     // 算出y2之前的闰年数量
7336fd0130Shoumkh     let y2_leaps = math_div(y2 - 1, 4) - math_div(y2 - 1, 100) + math_div(y2 - 1, 400);
7436fd0130Shoumkh 
7536fd0130Shoumkh     y2_leaps - y1_leaps
7636fd0130Shoumkh }
7736fd0130Shoumkh 
7836fd0130Shoumkh /// # 将秒数转换成日期
7936fd0130Shoumkh ///
8036fd0130Shoumkh /// ## 参数
8136fd0130Shoumkh ///
8236fd0130Shoumkh /// * 'totalsecs' - 1970年1月1日 00:00:00 UTC到现在的秒数
8336fd0130Shoumkh /// * 'offset' - 指定的秒数对应的时间段(含)的偏移量(以秒为单位)
8436fd0130Shoumkh #[allow(dead_code)]
time_to_calendar(totalsecs: PosixTimeT, offset: i32) -> CalendarTime8536fd0130Shoumkh pub fn time_to_calendar(totalsecs: PosixTimeT, offset: i32) -> CalendarTime {
8636fd0130Shoumkh     let mut result = CalendarTime::new();
8736fd0130Shoumkh     // 计算对应的天数
8836fd0130Shoumkh     let mut days = totalsecs / SECS_PER_DAY;
8936fd0130Shoumkh     // 一天中剩余的秒数
9036fd0130Shoumkh     let mut rem = totalsecs % SECS_PER_DAY;
9136fd0130Shoumkh 
9236fd0130Shoumkh     // 加入偏移量
9336fd0130Shoumkh     rem += offset as i64;
9436fd0130Shoumkh     while rem < 0 {
9536fd0130Shoumkh         rem += SECS_PER_DAY;
9636fd0130Shoumkh         days -= 1;
9736fd0130Shoumkh     }
9836fd0130Shoumkh     while rem >= SECS_PER_DAY {
9936fd0130Shoumkh         rem -= SECS_PER_DAY;
10036fd0130Shoumkh         days += 1;
10136fd0130Shoumkh     }
10236fd0130Shoumkh     // 计算对应的小时数
10336fd0130Shoumkh     result.tm_hour = (rem / SECS_PER_HOUR) as i32;
104*840045afSLoGin     rem %= SECS_PER_HOUR;
10536fd0130Shoumkh 
10636fd0130Shoumkh     // 计算对应的分钟数
10736fd0130Shoumkh     result.tm_min = (rem / 60) as i32;
108*840045afSLoGin     rem %= 60;
10936fd0130Shoumkh 
11036fd0130Shoumkh     // 秒数
11136fd0130Shoumkh     result.tm_sec = rem as i32;
11236fd0130Shoumkh 
11336fd0130Shoumkh     // totalsec是从1970年1月1日 00:00:00 UTC到现在的秒数
11436fd0130Shoumkh     // 当时是星期四
11536fd0130Shoumkh     result.tm_wday = ((4 + days) % 7) as i32;
11636fd0130Shoumkh 
11736fd0130Shoumkh     let mut year = 1970;
11836fd0130Shoumkh     while days < 0 || (is_leap(year) && days >= 366) || (!is_leap(year) && days >= 365) {
11936fd0130Shoumkh         // 假设每一年都是365天,计算出大概的年份
12036fd0130Shoumkh         let guess_year = year + math_div(days.try_into().unwrap(), 365);
12136fd0130Shoumkh         // 将已经计算过的天数去掉
12236fd0130Shoumkh         days -= ((guess_year - year) * 365 + leaps_between(year, guess_year)) as i64;
12336fd0130Shoumkh         year = guess_year;
12436fd0130Shoumkh     }
12536fd0130Shoumkh     result.tm_year = (year - 1900) as i32;
12636fd0130Shoumkh     result.tm_yday = days as i32;
12736fd0130Shoumkh     let mut il = 0;
12836fd0130Shoumkh     if is_leap(year) {
12936fd0130Shoumkh         il = 1
13036fd0130Shoumkh     };
13136fd0130Shoumkh     let mut mon = 0;
13236fd0130Shoumkh     for i in MON_OF_YDAY[il] {
13336fd0130Shoumkh         if days < i {
13436fd0130Shoumkh             break;
13536fd0130Shoumkh         }
13636fd0130Shoumkh         mon += 1;
13736fd0130Shoumkh     }
13836fd0130Shoumkh     days -= MON_OF_YDAY[il][mon - 1];
13936fd0130Shoumkh     result.tm_mon = (mon - 1) as i32;
14036fd0130Shoumkh     result.tm_mday = (days + 1) as i32;
14136fd0130Shoumkh 
14236fd0130Shoumkh     result
14336fd0130Shoumkh }
144