mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-21 03:55:24 +00:00
LibC: Make mktime() and timegm() handle years before 1970
And also years that don't fit in 32-bit. Lovingly tested via LibJS's Date.UTC(), which happens to call timegm().
This commit is contained in:
parent
96891669c3
commit
c399caf27f
Notes:
sideshowbarker
2024-07-19 03:18:55 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/c399caf27f9 Pull-request: https://github.com/SerenityOS/serenity/pull/3258
2 changed files with 30 additions and 6 deletions
|
@ -93,21 +93,28 @@ static void time_to_tm(struct tm* tm, time_t t)
|
|||
tm->tm_mday += days;
|
||||
}
|
||||
|
||||
static time_t tm_to_time(struct tm* tm, long timezone_adjust)
|
||||
static time_t tm_to_time(struct tm* tm, long timezone_adjust_seconds)
|
||||
{
|
||||
int days = 0;
|
||||
int seconds = tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec;
|
||||
for (int year = 70; year < tm->tm_year; ++year)
|
||||
days += 365 + __is_leap_year(1900 + year);
|
||||
if (tm->tm_year >= 70) {
|
||||
for (int year = 70; year < tm->tm_year; ++year)
|
||||
days += 365 + __is_leap_year(1900 + year);
|
||||
} else {
|
||||
for (int year = tm->tm_year; year < 70; ++year)
|
||||
days -= 365 + __is_leap_year(1900 + year);
|
||||
}
|
||||
|
||||
tm->tm_yday = tm->tm_mday - 1;
|
||||
// FIXME: What if tm->tm_mon < 0 or tm->tm_mon > 12?
|
||||
for (int month = 0; month < tm->tm_mon; ++month)
|
||||
tm->tm_yday += __days_per_month[month];
|
||||
if (tm->tm_mon > 1 && __is_leap_year(1900 + tm->tm_year))
|
||||
++tm->tm_yday;
|
||||
|
||||
days += tm->tm_yday;
|
||||
return days * __seconds_per_day + seconds + timezone_adjust;
|
||||
|
||||
int seconds = tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec;
|
||||
return static_cast<time_t>(days) * __seconds_per_day + seconds + timezone_adjust_seconds;
|
||||
}
|
||||
|
||||
time_t mktime(struct tm* tm)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
test("basic functionality", () => {
|
||||
// FIXME: Years before 1970 don't work. Once they do, add a test. Also add a test with a year before 1900 then.
|
||||
expect(Date.UTC(2020)).toBe(1577836800000);
|
||||
expect(Date.UTC(2000, 10)).toBe(973036800000);
|
||||
expect(Date.UTC(1980, 5, 30)).toBe(331171200000);
|
||||
|
@ -7,4 +6,22 @@ test("basic functionality", () => {
|
|||
expect(Date.UTC(1970, 5, 30, 13, 30)).toBe(15600600000);
|
||||
expect(Date.UTC(1970, 0, 1, 0, 0, 59)).toBe(59000);
|
||||
expect(Date.UTC(1970, 0, 1, 0, 0, 0, 999)).toBe(999);
|
||||
|
||||
expect(Date.UTC(1969, 11, 31, 23, 59, 59, 817)).toBe(-183);
|
||||
|
||||
expect(Date.UTC(1799, 0)).toBe(-5396198400000);
|
||||
expect(Date.UTC(1800, 0)).toBe(-5364662400000);
|
||||
expect(Date.UTC(1801, 0)).toBe(-5333126400000);
|
||||
expect(Date.UTC(1802, 0)).toBe(-5301590400000);
|
||||
expect(Date.UTC(1803, 0)).toBe(-5270054400000);
|
||||
expect(Date.UTC(1804, 0)).toBe(-5238518400000);
|
||||
|
||||
expect(Date.UTC(1999, 0)).toBe(915148800000);
|
||||
expect(Date.UTC(2000, 0)).toBe(946684800000);
|
||||
expect(Date.UTC(2001, 0)).toBe(978307200000);
|
||||
expect(Date.UTC(2002, 0)).toBe(1009843200000);
|
||||
expect(Date.UTC(2003, 0)).toBe(1041379200000);
|
||||
expect(Date.UTC(2004, 0)).toBe(1072915200000);
|
||||
|
||||
expect(Date.UTC(20000, 0)).toBe(568971820800000);
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue