Fix gmtime and localtime on negative timestamps with fractional seconds (#3634)

The whole seconds were truncated toward zero while the fractional part
was measured from the floor, so any negative non-integral timestamp was
rendered one second late; gmtime was not monotonic across the epoch.
This commit is contained in:
itchyny authored and GitHub committed 2026-09-18 18:45:36 +09:00
1 parent 57f5976edf
commit 6aeafff056
2 files changed
+12 -4

No files matched your search

+4 -4
View File
@@ -1757,7 +1757,7 @@ static jv f_gmtime(jq_state *jq, jv a) {
struct tm tm, *tmp;
memset(&tm, 0, sizeof(tm));
double fsecs = jv_number_value(a);
time_t secs = fsecs;
time_t secs = floor(fsecs);
jv_free(a);
tmp = gmtime_r(&secs, &tm);
if (tmp == NULL)
@@ -1771,7 +1771,7 @@ static jv f_gmtime(jq_state *jq, jv a) {
struct tm tm, *tmp;
memset(&tm, 0, sizeof(tm));
double fsecs = jv_number_value(a);
time_t secs = fsecs;
time_t secs = floor(fsecs);
jv_free(a);
tmp = gmtime(&secs);
if (tmp == NULL)
@@ -1792,7 +1792,7 @@ static jv f_localtime(jq_state *jq, jv a) {
struct tm tm, *tmp;
memset(&tm, 0, sizeof(tm));
double fsecs = jv_number_value(a);
time_t secs = fsecs;
time_t secs = floor(fsecs);
jv_free(a);
tmp = localtime_r(&secs, &tm);
if (tmp == NULL)
@@ -1806,7 +1806,7 @@ static jv f_localtime(jq_state *jq, jv a) {
struct tm tm, *tmp;
memset(&tm, 0, sizeof(tm));
double fsecs = jv_number_value(a);
time_t secs = fsecs;
time_t secs = floor(fsecs);
jv_free(a);
tmp = localtime(&secs);
if (tmp == NULL)
+8
View File
@@ -10,3 +10,11 @@ strftime("%A, %B %e, %Y")
1435677542.822351
"Tuesday, June 30, 2015"
# Timestamps before the epoch are not supported on mingw/WIN32
gmtime
-1.25
[1969,11,31,23,59,58.75,3,364]
map(gmtime) | . == sort
[-1.5,-1,-0.5,0,0.5,1,1.5]
true