Skip to content

Commit

Permalink
Fix localtime() and gmtime() with 64bit time_t (#17471)
Browse files Browse the repository at this point in the history
See: #17393
  • Loading branch information
tiran authored Jul 19, 2022
1 parent 73c1d12 commit 104a967
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -510,9 +510,10 @@ mergeInto(LibraryManager.library, {
return (date.getTime() / 1000)|0;
},

_gmtime_js__deps: ['$readI53FromI64'],
_gmtime_js__sig: 'ipp',
_gmtime_js: function(time, tmPtr) {
var date = new Date({{{ makeGetValue('time', 0, 'i32') }}}*1000);
var date = new Date({{{ makeGetValue('time', 0, 'i53') }}}*1000);
{{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_sec, 'date.getUTCSeconds()', 'i32') }}};
{{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_min, 'date.getUTCMinutes()', 'i32') }}};
{{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_hour, 'date.getUTCHours()', 'i32') }}};
Expand Down Expand Up @@ -544,9 +545,10 @@ mergeInto(LibraryManager.library, {
return (date.getTime() / 1000)|0;
},

_localtime_js__deps: ['$readI53FromI64'],
_localtime_js__sig: 'ipp',
_localtime_js: function(time, tmPtr) {
var date = new Date({{{ makeGetValue('time', 0, 'i32') }}}*1000);
var date = new Date({{{ makeGetValue('time', 0, 'i53') }}}*1000);
{{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_sec, 'date.getSeconds()', 'i32') }}};
{{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_min, 'date.getMinutes()', 'i32') }}};
{{{ makeSetValue('tmPtr', C_STRUCTS.tm.tm_hour, 'date.getHours()', 'i32') }}};
Expand Down
34 changes: 34 additions & 0 deletions tests/core/test_time.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,30 @@
#include <assert.h>
#include <math.h>

void
check_gmtime_localtime(time_t time)
{
char gmbuf[32], locbuf[32];
const char fmt[] = "%Y-%m-%d %H:%M:%S";
struct tm *gm;
struct tm *loc;

gm = gmtime(&time);
assert(gm);
assert(strftime(gmbuf, sizeof(gmbuf) - 1, fmt, gm) > 0);
loc = localtime(&time);
assert(loc);
assert(strftime(locbuf, sizeof(locbuf) - 1, fmt, loc) > 0);

// gmtime and localtime are only equal when timezone is UTC
if ((timezone == 0) && (strcmp(gmbuf, locbuf) != 0)) {
printf("time: %lld, gmtime: %s != localtime: %s\n", time, gmbuf, locbuf);
puts("failed");
} else {
printf("time: %lld, gmtime: %s\n", time, gmbuf);
}
}

int main() {
time_t xmas2002 = 1040786563ll;
time_t summer2002 = 1025528525ll;
Expand Down Expand Up @@ -216,5 +240,15 @@ int main() {
clock_gettime(CLOCK_REALTIME, &ts_clock_gettime);
printf("timespec_get test 6: %d\n", abs(ts_timespec_get.tv_sec - ts_clock_gettime.tv_sec) <= 2);

// verify gmtime() and localtime()
check_gmtime_localtime(0);
check_gmtime_localtime(2147483647); // int8_t max, Y2K38
check_gmtime_localtime(2147483648);
check_gmtime_localtime(-2147483648); // int8_t min
check_gmtime_localtime(-2147483649);
check_gmtime_localtime(253402300799); // end of year 9999
check_gmtime_localtime(-62135596800); // beginning of year 1

puts("success");
return 0;
}
8 changes: 8 additions & 0 deletions tests/core/test_time.out
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,11 @@ timespec_get test 3: 1
timespec_get test 4: 1
timespec_get test 5: 1
timespec_get test 6: 1
time: 0, gmtime: 1970-01-01 00:00:00
time: 2147483647, gmtime: 2038-01-19 03:14:07
time: 2147483648, gmtime: 2038-01-19 03:14:08
time: -2147483648, gmtime: 1901-12-13 20:45:52
time: -2147483649, gmtime: 1901-12-13 20:45:51
time: 253402300799, gmtime: 9999-12-31 23:59:59
time: -62135596800, gmtime: 1-01-01 00:00:00
success

0 comments on commit 104a967

Please sign in to comment.