diff --git a/src/header/time/helpers.rs b/src/header/time/helpers.rs deleted file mode 100644 index 70ff5f3afe3e7dcb84e7d48edfe0b62cb6b4135f..0000000000000000000000000000000000000000 --- a/src/header/time/helpers.rs +++ /dev/null @@ -1,41 +0,0 @@ -use platform::types::*; - -use super::constants::*; - -// compute year, month, day & day of year -// for description of this algorithm see -// http://howardhinnant.github.io/date_algorithms.html#civil_from_days -#[inline(always)] -pub(crate) fn civil_from_days(days: c_long) -> (c_int, c_int, c_int, c_int) { - let (era, year): (c_int, c_int); - let (erayear, mut yearday, mut month, day): (c_int, c_int, c_int, c_int); - let eraday: c_ulong; - - era = (if days >= 0 { - days - } else { - days - (DAYS_PER_ERA - 1) - } / DAYS_PER_ERA) as c_int; - eraday = (days - era as c_long * DAYS_PER_ERA) as c_ulong; - let a = eraday / (DAYS_PER_4_YEARS - 1); - let b = eraday / DAYS_PER_CENTURY; - let c = eraday / (DAYS_PER_ERA as c_ulong - 1); - erayear = ((eraday - a + b - c) / 365) as c_int; - let d = DAYS_PER_YEAR * erayear + erayear / 4 - erayear / 100; - yearday = (eraday - d as c_ulong) as c_int; - month = (5 * yearday + 2) / 153; - day = yearday - (153 * month + 2) / 5 + 1; - month += if month < 10 { 2 } else { -10 }; - year = ADJUSTED_EPOCH_YEAR + erayear + era * YEARS_PER_ERA + (month <= 1) as c_int; - yearday += if yearday >= DAYS_PER_YEAR - DAYS_IN_JANUARY - DAYS_IN_FEBRUARY { - -(DAYS_PER_YEAR - DAYS_IN_JANUARY - DAYS_IN_FEBRUARY) - } else { - DAYS_IN_JANUARY + DAYS_IN_FEBRUARY + is_leap(erayear) - }; - return (year, month, day, yearday); -} - -#[inline(always)] -fn is_leap(y: c_int) -> c_int { - ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) as c_int -} diff --git a/src/header/time/mod.rs b/src/header/time/mod.rs index ad6830d82230e1d73fe9761eeb43de195457546a..cbe291bf2fefad280356a145c4d58c9acc199be6 100644 --- a/src/header/time/mod.rs +++ b/src/header/time/mod.rs @@ -8,10 +8,8 @@ use platform::types::*; use platform::{Pal, Sys}; use self::constants::*; -use self::helpers::*; pub mod constants; -mod helpers; mod strftime; #[repr(C)] @@ -158,54 +156,10 @@ pub extern "C" fn getdate(string: *const c_char) -> tm { } #[no_mangle] -pub extern "C" fn gmtime(timer: *const time_t) -> *mut tm { +pub unsafe extern "C" fn gmtime(timer: *const time_t) -> *mut tm { unsafe { gmtime_r(timer, &mut TM) } } -#[no_mangle] -pub extern "C" fn gmtime_r(clock: *const time_t, result: *mut tm) -> *mut tm { - let (mut days, mut rem): (c_long, c_long); - let mut weekday: c_int; - let lcltime = unsafe { *clock }; - - days = lcltime / SECSPERDAY + EPOCH_ADJUSTMENT_DAYS; - rem = lcltime % SECSPERDAY; - if rem < 0 { - rem += SECSPERDAY; - days -= 1; - } - unsafe { - (*result).tm_hour = (rem / SECSPERHOUR) as c_int; - rem %= SECSPERHOUR; - (*result).tm_min = (rem / SECSPERMIN) as c_int; - (*result).tm_sec = (rem % SECSPERMIN) as c_int; - } - - weekday = ((ADJUSTED_EPOCH_WDAY + days) % DAYSPERWEEK as c_long) as c_int; - if weekday < 0 { - weekday += DAYSPERWEEK; - } - unsafe { (*result).tm_wday = weekday }; - - let (year, month, day, yearday) = civil_from_days(days); - unsafe { - (*result).tm_yday = yearday; - (*result).tm_year = year - YEAR_BASE; - (*result).tm_mon = month; - (*result).tm_mday = day; - - (*result).tm_isdst = 0; - (*result).tm_gmtoff = 0; - (*result).tm_zone = UTC; - } - result -} - -#[no_mangle] -pub unsafe extern "C" fn localtime(clock: *const time_t) -> *mut tm { - localtime_r(clock, &mut TM) -} - const MONTH_DAYS: [[c_int; 12]; 2] = [ // Non-leap years: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], @@ -213,12 +167,13 @@ const MONTH_DAYS: [[c_int; 12]; 2] = [ [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], ]; +#[inline(always)] fn leap_year(year: c_int) -> bool { year % 4 == 0 && (year % 100 != 0 || year % 400 == 0) } #[no_mangle] -pub unsafe extern "C" fn localtime_r(clock: *const time_t, t: *mut tm) -> *mut tm { +pub unsafe extern "C" fn gmtime_r(clock: *const time_t, t: *mut tm) -> *mut tm { let clock = *clock; let mut day = (clock / (60 * 60 * 24)) as c_int; @@ -288,11 +243,25 @@ pub unsafe extern "C" fn localtime_r(clock: *const time_t, t: *mut tm) -> *mut t (*t).tm_mon += 1; } (*t).tm_mday = 1 + day as c_int; + (*t).tm_isdst = 0; + (*t).tm_gmtoff = 0; + (*t).tm_zone = UTC; t } +#[no_mangle] +pub unsafe extern "C" fn localtime(clock: *const time_t) -> *mut tm { + localtime_r(clock, &mut TM) +} + +#[no_mangle] +pub unsafe extern "C" fn localtime_r(clock: *const time_t, t: *mut tm) -> *mut tm { + // TODO: Change tm_isdst, tm_gmtoff, tm_zone + gmtime_r(clock, t) +} + #[no_mangle] pub unsafe extern "C" fn mktime(t: *mut tm) -> time_t { let mut year = (*t).tm_year + 1900; diff --git a/tests/expected/time/localtime.stdout b/tests/expected/time/localtime.stdout index 12a3072c69a462b1c99a1be6b8c9854a45d56571..e79e0fb873aa1f6d53f72a3c9b0227940d1617a8 100644 --- a/tests/expected/time/localtime.stdout +++ b/tests/expected/time/localtime.stdout @@ -1,6 +1,8 @@ Year 69, Day of year: 333, Month 10, Day of month: 29, Day of week: 6, 0:0:0 Year 69, Day of year: 365, Month 11, Day of month: 31, Day of week: 3, 0:0:0 +Year 69, Day of year: 365, Month 11, Day of month: 31, Day of week: 3, 23:59:59 Year 69, Day of year: 365, Month 11, Day of month: 31, Day of week: 3, 23:51:40 Year 70, Day of year: 0, Month 0, Day of month: 1, Day of week: 4, 0:0:0 +Year 70, Day of year: 0, Month 0, Day of month: 1, Day of week: 4, 0:0:1 Year 118, Day of year: 193, Month 6, Day of month: 13, Day of week: 5, 4:9:10 Fri Jul 13 06:03:43 2018 diff --git a/tests/time/localtime.c b/tests/time/localtime.c index edce6cf64e84c7d90ff9fa0a9d8003047ff07f80..3792531b95e6f6b3c48388c393bafab18e95f82c 100644 --- a/tests/time/localtime.c +++ b/tests/time/localtime.c @@ -3,8 +3,8 @@ int main() { int day = 60 * 60 * 24; - time_t inputs[] = { -(day * 33), -day, -500, 0, 1531454950 }; - for (int i = 0; i < 5; i += 1) { + time_t inputs[] = { -(day * 33), -day, -1, -500, 0, 1, 1531454950 }; + for (int i = 0; i < (sizeof(inputs) / sizeof(time_t)); i += 1) { struct tm* t = localtime(&inputs[i]); printf(