Test fix for mktime
This commit is contained in:
1 parent
24005287f4
commit
ddad9618dc
1 file changed
+39
-24
@@ -936,6 +936,38 @@ static jv tm2jv(struct tm *tm) {
|
|||||||
jv_number(tm->tm_yday));
|
jv_number(tm->tm_yday));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mktime() has side-effects and anyways, returns time in the local
|
||||||
|
* timezone, not UTC. We want timegm(), which isn't standard.
|
||||||
|
*
|
||||||
|
* To make things worse, mktime() tells you what the timezone
|
||||||
|
* adjustment is, but you have to #define _BSD_SOURCE to get this
|
||||||
|
* field of struct tm on some systems.
|
||||||
|
*
|
||||||
|
* This is all to blame on POSIX, of course.
|
||||||
|
*
|
||||||
|
* Our wrapper tries to use timegm() if available, or mktime() and
|
||||||
|
* correct for its side-effects if possible.
|
||||||
|
*
|
||||||
|
* Returns (time_t)-2 if mktime()'s side-effects cannot be corrected.
|
||||||
|
*/
|
||||||
|
static time_t my_mktime(struct tm *tm) {
|
||||||
|
#ifdef HAVE_TIMEGM
|
||||||
|
return timegm(tm);
|
||||||
|
#else /* HAVE_TIMEGM */
|
||||||
|
time_t t = mktime(&tm);
|
||||||
|
if (t == (time_t)-1)
|
||||||
|
return t;
|
||||||
|
#ifdef HAVE_TM_TM_GMT_OFF
|
||||||
|
return t + tm.tm_gmtoff;
|
||||||
|
#elif defined(HAVE_TM_TM_GMT_OFF)
|
||||||
|
return t + tm.__tm_gmtoff;
|
||||||
|
#else
|
||||||
|
return (time_t)-2; /* Not supported */
|
||||||
|
#endif
|
||||||
|
#endif /* !HAVE_TIMEGM */
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_STRPTIME
|
#ifdef HAVE_STRPTIME
|
||||||
static jv f_strptime(jq_state *jq, jv a, jv b) {
|
static jv f_strptime(jq_state *jq, jv a, jv b) {
|
||||||
if (jv_get_kind(a) != JV_KIND_STRING || jv_get_kind(b) != JV_KIND_STRING)
|
if (jv_get_kind(a) != JV_KIND_STRING || jv_get_kind(b) != JV_KIND_STRING)
|
||||||
@@ -955,6 +987,8 @@ static jv f_strptime(jq_state *jq, jv a, jv b) {
|
|||||||
}
|
}
|
||||||
jv_free(a);
|
jv_free(a);
|
||||||
jv_free(b);
|
jv_free(b);
|
||||||
|
if (tm.tm_wday == 0 && tm.tm_yday == 0 && my_mktime(&tm) == (time_t)-2)
|
||||||
|
return jv_invalid_with_msg(jv_string("strptime/1 not supported on this platform"));
|
||||||
jv r = tm2jv(&tm);
|
jv r = tm2jv(&tm);
|
||||||
if (*end != '\0')
|
if (*end != '\0')
|
||||||
r = jv_array_append(r, jv_string(end));
|
r = jv_array_append(r, jv_string(end));
|
||||||
@@ -996,35 +1030,16 @@ static jv f_mktime(jq_state *jq, jv a) {
|
|||||||
if (jv_get_kind(a) != JV_KIND_ARRAY)
|
if (jv_get_kind(a) != JV_KIND_ARRAY)
|
||||||
return jv_invalid_with_msg(jv_string("mktime requires array inputs"));
|
return jv_invalid_with_msg(jv_string("mktime requires array inputs"));
|
||||||
if (jv_array_length(jv_copy(a)) < 6)
|
if (jv_array_length(jv_copy(a)) < 6)
|
||||||
return jv_invalid_with_msg(jv_string("mktime requires parsed datetime inputs")); \
|
return jv_invalid_with_msg(jv_string("mktime requires parsed datetime inputs"));
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
if (!jv2tm(a, &tm))
|
if (!jv2tm(a, &tm))
|
||||||
return jv_invalid_with_msg(jv_string("mktime requires parsed datetime inputs")); \
|
return jv_invalid_with_msg(jv_string("mktime requires parsed datetime inputs"));
|
||||||
/*
|
time_t t = my_mktime(&tm);
|
||||||
* mktime() has side-effects and anyways, returns time in the local
|
|
||||||
* timezone, not UTC. We want timegm(), which isn't standard.
|
|
||||||
*
|
|
||||||
* To make things worse, mktime() tells you what the timezone
|
|
||||||
* adjustment is, but you have to #define _BSD_SOURCE to get this
|
|
||||||
* field of struct tm on some systems.
|
|
||||||
*
|
|
||||||
* This is all to blame on POSIX, of course.
|
|
||||||
*/
|
|
||||||
#ifdef HAVE_TIMEGM
|
|
||||||
time_t t = timegm(&tm);
|
|
||||||
if (t == (time_t)-1)
|
if (t == (time_t)-1)
|
||||||
return jv_invalid_with_msg(jv_string("invalid gmtime representation"));
|
return jv_invalid_with_msg(jv_string("invalid gmtime representation"));
|
||||||
|
if (t == (time_t)-2)
|
||||||
|
return jv_invalid_with_msg(jv_string("mktime not supported on this platform"));
|
||||||
return jv_number(t);
|
return jv_number(t);
|
||||||
#else /* HAVE_TIMEGM */
|
|
||||||
time_t t = mktime(&tm);
|
|
||||||
if (t == (time_t)-1)
|
|
||||||
return jv_invalid_with_msg(jv_string("invalid gmtime representation"));
|
|
||||||
#ifdef HAVE_TM_TM_GMT_OFF
|
|
||||||
return jv_number(t + tm.tm_gmtoff);
|
|
||||||
#elif defined(HAVE_TM_TM_GMT_OFF)
|
|
||||||
return jv_number(t + tm.__tm_gmtoff);
|
|
||||||
#endif
|
|
||||||
#endif /* HAVE_TIMEGM */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_GMTIME_R
|
#ifdef HAVE_GMTIME_R
|
||||||
|
|||||||
Reference in new issue
Block a user