axlibc/
mktime.rs

1use core::ffi::c_int;
2
3use crate::ctypes;
4
5const MONTH_DAYS: [[c_int; 12]; 2] = [
6    // Non-leap years:
7    [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
8    // Leap years:
9    [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
10];
11
12#[inline(always)]
13fn leap_year(year: c_int) -> bool {
14    year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)
15}
16
17/// Convert broken-down time into time since the Epoch.
18#[unsafe(no_mangle)]
19pub unsafe extern "C" fn mktime(t: *mut ctypes::tm) -> ctypes::time_t {
20    let mut year = (*t).tm_year + 1900;
21    let mut month = (*t).tm_mon;
22    let mut day = (*t).tm_mday as i64 - 1;
23
24    let leap = if leap_year(year) { 1 } else { 0 };
25
26    if year < 1970 {
27        day = MONTH_DAYS[if leap_year(year) { 1 } else { 0 }][(*t).tm_mon as usize] as i64 - day;
28
29        while year < 1969 {
30            year += 1;
31            day += if leap_year(year) { 366 } else { 365 };
32        }
33
34        while month < 11 {
35            month += 1;
36            day += MONTH_DAYS[leap][month as usize] as i64;
37        }
38
39        (-(day * (60 * 60 * 24)
40            - (((*t).tm_hour as i64) * (60 * 60) + ((*t).tm_min as i64) * 60 + (*t).tm_sec as i64)))
41            as ctypes::time_t
42    } else {
43        while year > 1970 {
44            year -= 1;
45            day += if leap_year(year) { 366 } else { 365 };
46        }
47
48        while month > 0 {
49            month -= 1;
50            day += MONTH_DAYS[leap][month as usize] as i64;
51        }
52
53        (day * (60 * 60 * 24)
54            + ((*t).tm_hour as i64) * (60 * 60)
55            + ((*t).tm_min as i64) * 60
56            + (*t).tm_sec as i64) as ctypes::time_t
57    }
58}