Skip to content
Snippets Groups Projects
Commit 63711f6c authored by Peter Limkilde Svendsen's avatar Peter Limkilde Svendsen
Browse files

Formatting

parent 845c74a8
No related branches found
No related tags found
No related merge requests found
......@@ -195,7 +195,7 @@ pub unsafe extern "C" fn gmtime_r(clock: *const time_t, result: *mut tm) -> *mut
* Note that we need 0-based months here, though.
* Overall, this implementation should generate correct results as
* long as the tm_year value will fit in a c_int. */
const SECS_PER_DAY: time_t = 24*60*60;
const SECS_PER_DAY: time_t = 24 * 60 * 60;
const DAYS_PER_ERA: time_t = 146097;
let unix_secs = *clock;
......@@ -203,38 +203,48 @@ pub unsafe extern "C" fn gmtime_r(clock: *const time_t, result: *mut tm) -> *mut
/* Day number here is possibly negative, remainder will always be
* nonnegative when using Euclidean division */
let unix_days: time_t = unix_secs.div_euclid(SECS_PER_DAY);
/* In range [0, 86399]. Needs a u32 since this is larger (at least
* theoretically) than the guaranteed range of c_int */
let secs_of_day: u32 = unix_secs.rem_euclid(SECS_PER_DAY).try_into().unwrap();
/* Shift origin from 1970-01-01 to 0000-03-01 and find out where we
* are in terms of 400-year eras since then */
let days_since_origin = unix_days + 719468;
let era = days_since_origin.div_euclid(DAYS_PER_ERA);
let day_of_era = days_since_origin.rem_euclid(DAYS_PER_ERA);
let year_of_era = (day_of_era - day_of_era/1460 + day_of_era/36524 - day_of_era/146096) / 365;
let year_of_era =
(day_of_era - day_of_era / 1460 + day_of_era / 36524 - day_of_era / 146096) / 365;
/* "transformed" here refers to dates in a calendar where years
* start on March 1 */
let year_transformed = year_of_era + 400*era; // retain large range, don't convert to c_int yet
let day_of_year_transformed: c_int = (day_of_era - (365*year_of_era + year_of_era/4 - year_of_era/100)).try_into().unwrap();
let month_transformed: c_int = (5*day_of_year_transformed + 2)/153;
let year_transformed = year_of_era + 400 * era; // retain large range, don't convert to c_int yet
let day_of_year_transformed: c_int = (day_of_era
- (365 * year_of_era + year_of_era / 4 - year_of_era / 100))
.try_into()
.unwrap();
let month_transformed: c_int = (5 * day_of_year_transformed + 2) / 153;
// Convert back to calendar with year starting on January 1
let month: c_int = (month_transformed + 2) % 12; // adapted to 0-based months
let year: time_t = if month < 2 {year_transformed + 1} else {year_transformed};
let year: time_t = if month < 2 {
year_transformed + 1
} else {
year_transformed
};
/* Subtract 1900 *before* converting down to c_int in order to
* maximize the range of input timestamps that will succeed */
match c_int::try_from(year - 1900) {
Ok(year_less_1900) => {
let mday: c_int = (day_of_year_transformed - (153*month_transformed+2)/5 + 1).try_into().unwrap();
let mday: c_int = (day_of_year_transformed - (153 * month_transformed + 2) / 5 + 1)
.try_into()
.unwrap();
/* 1970-01-01 was a Thursday. Again, Euclidean division is
* used to ensure a nonnegative remainder (range [0, 6]). */
let wday: c_int = ((unix_days + 4).rem_euclid(7)).try_into().unwrap();
/* Yes, duplicated code for now (to work on non-c_int-values
* so that we are not constrained by the subtraction of
* 1900) */
......@@ -246,15 +256,15 @@ pub unsafe extern "C" fn gmtime_r(clock: *const time_t, result: *mut tm) -> *mut
* year is a leap year. Therefore, we use the already
* computed date for those two months. */
let yday: c_int = match month {
0 => mday - 1, // January
0 => mday - 1, // January
1 => 31 + mday - 1, // February
_ => day_of_year_transformed + if is_leap_year {60} else {59},
_ => day_of_year_transformed + if is_leap_year { 60 } else { 59 },
};
let hour: c_int = (secs_of_day / (60*60)).try_into().unwrap();
let hour: c_int = (secs_of_day / (60 * 60)).try_into().unwrap();
let min: c_int = ((secs_of_day / 60) % 60).try_into().unwrap();
let sec: c_int = (secs_of_day % 60).try_into().unwrap();
*result = tm {
tm_sec: sec,
tm_min: min,
......@@ -268,7 +278,7 @@ pub unsafe extern "C" fn gmtime_r(clock: *const time_t, result: *mut tm) -> *mut
tm_gmtoff: 0,
tm_zone: UTC,
};
result
}
Err(_) => {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment