Merge branch 'fix-mktime' into 'master'

fix: mktime: stop using tm_gmtoff, use system timezone per POSIX

See merge request redox-os/relibc!1435
This commit is contained in:
Jeremy Soller
2026-06-08 06:37:09 -06:00
3 changed files with 24 additions and 17 deletions
+11 -17
View File
@@ -23,7 +23,7 @@ use crate::{
};
use alloc::collections::BTreeSet;
use chrono::{
DateTime, Datelike, FixedOffset, NaiveDate, NaiveDateTime, Offset, TimeZone, Timelike, Utc,
DateTime, Datelike, NaiveDate, NaiveDateTime, Offset, TimeZone, Timelike, Utc,
offset::MappedLocalTime,
};
use chrono_tz::{OffsetComponents, OffsetName, Tz};
@@ -451,19 +451,22 @@ pub unsafe extern "C" fn mktime(timeptr: *mut tm) -> time_t {
}
};
let offset = get_offset(unsafe { (*timeptr).tm_gmtoff }).unwrap();
let tz = time_zone();
// Create DateTime<FixedOffset>
let datetime = match offset.from_local_datetime(&naive_local) {
let isdst = unsafe { (*timeptr).tm_isdst };
let tz_datetime = match tz.from_local_datetime(&naive_local) {
MappedLocalTime::Single(datetime) => datetime,
_ => {
MappedLocalTime::Ambiguous(early, late) => {
if isdst > 0 {
early
} else {
late
}
}
MappedLocalTime::None => {
platform::ERRNO.set(EOVERFLOW);
return -1;
}
};
// Convert to UTC and get timestamp
let tz_datetime = datetime.with_timezone(&tz);
let timestamp = tz_datetime.timestamp();
unsafe { ptr::write(timeptr, datetime_to_tm(&tz_datetime)) };
@@ -859,15 +862,6 @@ unsafe fn set_timezone(
}
}
#[inline(always)]
pub const fn get_offset(off: c_long) -> Option<FixedOffset> {
if off < 0 {
FixedOffset::west_opt(off as _)
} else {
FixedOffset::east_opt(off as _)
}
}
const fn blank_tm() -> tm {
tm {
tm_year: 0,
+1
View File
@@ -4,3 +4,4 @@
-500 = -500
0 = 0
1531454950 = 1531454950
gmtoff_ignored = 1
+12
View File
@@ -57,4 +57,16 @@ int main(void) {
printf("Comparison %ld == %ld failed. Time: %s", input, output, asctime(time));
}
}
// mktime must not panic on out-of-range tm_gmtoff
{
struct tm tg = { 0 };
tg.tm_year = 124;
tg.tm_mon = 0;
tg.tm_mday = 1;
tg.tm_hour = 12;
tg.tm_gmtoff = 100000;
time_t result = mktime(&tg);
printf("gmtoff_ignored = %d\n", result != (time_t)-1);
}
}