1 use super::syscall::PosixTimeT; 2 /// 一小时所包含的秒数 3 const SECS_PER_HOUR: i64 = 60 * 60; 4 /// 一天所包含的秒数 5 const SECS_PER_DAY: i64 = SECS_PER_HOUR * 24; 6 /// 每年中每个月最后一天所对应天数 7 const MON_OF_YDAY: [[i64; 13]; 2] = [ 8 // 普通年 9 [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365], 10 // 闰年 11 [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366], 12 ]; 13 #[derive(Debug)] 14 #[allow(dead_code)] 15 pub struct CalendarTime { 16 tm_sec: i32, 17 tm_min: i32, 18 tm_hour: i32, 19 tm_mday: i32, 20 tm_mon: i32, 21 tm_wday: i32, 22 tm_yday: i32, 23 tm_year: i32, 24 } 25 impl CalendarTime { 26 pub fn new() -> Self { 27 CalendarTime { 28 tm_year: Default::default(), 29 tm_sec: Default::default(), 30 tm_min: Default::default(), 31 tm_hour: Default::default(), 32 tm_mday: Default::default(), 33 tm_mon: Default::default(), 34 tm_wday: Default::default(), 35 tm_yday: Default::default(), 36 } 37 } 38 } 39 40 /// # 判断是否是闰年 41 /// 42 /// ## 参数 43 /// 44 /// * 'year' - 年份 45 fn is_leap(year: u32) -> bool { 46 let mut flag = false; 47 if (year % 4 == 0 && year % 100 != 0) || year % 400 == 0 { 48 flag = true; 49 } 50 return flag; 51 } 52 53 /// # 计算除法 54 /// 55 /// # 参数 56 /// 57 /// * 'left' - 被除数 58 /// * 'right' - 除数 59 fn math_div(left: u32, right: u32) -> u32 { 60 return left / right; 61 } 62 63 /// # 计算两年之间的闰年数目 64 /// 65 /// ## 参数 66 /// 67 /// * 'y1' - 起始年份 68 /// * 'y2' - 结束年份 69 fn leaps_between(y1: u32, y2: u32) -> u32 { 70 // 算出y1之前的闰年数量 71 let y1_leaps = math_div(y1 - 1, 4) - math_div(y1 - 1, 100) + math_div(y1 - 1, 400); 72 // 算出y2之前的闰年数量 73 let y2_leaps = math_div(y2 - 1, 4) - math_div(y2 - 1, 100) + math_div(y2 - 1, 400); 74 75 y2_leaps - y1_leaps 76 } 77 78 /// # 将秒数转换成日期 79 /// 80 /// ## 参数 81 /// 82 /// * 'totalsecs' - 1970年1月1日 00:00:00 UTC到现在的秒数 83 /// * 'offset' - 指定的秒数对应的时间段(含)的偏移量(以秒为单位) 84 #[allow(dead_code)] 85 pub fn time_to_calendar(totalsecs: PosixTimeT, offset: i32) -> CalendarTime { 86 let mut result = CalendarTime::new(); 87 // 计算对应的天数 88 let mut days = totalsecs / SECS_PER_DAY; 89 // 一天中剩余的秒数 90 let mut rem = totalsecs % SECS_PER_DAY; 91 92 // 加入偏移量 93 rem += offset as i64; 94 while rem < 0 { 95 rem += SECS_PER_DAY; 96 days -= 1; 97 } 98 while rem >= SECS_PER_DAY { 99 rem -= SECS_PER_DAY; 100 days += 1; 101 } 102 // 计算对应的小时数 103 result.tm_hour = (rem / SECS_PER_HOUR) as i32; 104 rem %= SECS_PER_HOUR; 105 106 // 计算对应的分钟数 107 result.tm_min = (rem / 60) as i32; 108 rem %= 60; 109 110 // 秒数 111 result.tm_sec = rem as i32; 112 113 // totalsec是从1970年1月1日 00:00:00 UTC到现在的秒数 114 // 当时是星期四 115 result.tm_wday = ((4 + days) % 7) as i32; 116 117 let mut year = 1970; 118 while days < 0 || (is_leap(year) && days >= 366) || (!is_leap(year) && days >= 365) { 119 // 假设每一年都是365天,计算出大概的年份 120 let guess_year = year + math_div(days.try_into().unwrap(), 365); 121 // 将已经计算过的天数去掉 122 days -= ((guess_year - year) * 365 + leaps_between(year, guess_year)) as i64; 123 year = guess_year; 124 } 125 result.tm_year = (year - 1900) as i32; 126 result.tm_yday = days as i32; 127 let mut il = 0; 128 if is_leap(year) { 129 il = 1 130 }; 131 let mut mon = 0; 132 for i in MON_OF_YDAY[il] { 133 if days < i { 134 break; 135 } 136 mon += 1; 137 } 138 days -= MON_OF_YDAY[il][mon - 1]; 139 result.tm_mon = (mon - 1) as i32; 140 result.tm_mday = (days + 1) as i32; 141 142 result 143 } 144