Add localtime and strflocaltime (fix #1349)
This commit is contained in:
1 parent
607a9e3912
commit
06f20603f6
2 files changed
+69
No files matched your search
@@ -127,6 +127,8 @@ AC_FIND_FUNC([strftime], [c], [#include <time.h>], [0, 0, 0, 0])
|
|||||||
AC_FIND_FUNC([timegm], [c], [#include <time.h>], [0])
|
AC_FIND_FUNC([timegm], [c], [#include <time.h>], [0])
|
||||||
AC_FIND_FUNC([gmtime_r], [c], [#include <time.h>], [0, 0])
|
AC_FIND_FUNC([gmtime_r], [c], [#include <time.h>], [0, 0])
|
||||||
AC_FIND_FUNC([gmtime], [c], [#include <time.h>], [0])
|
AC_FIND_FUNC([gmtime], [c], [#include <time.h>], [0])
|
||||||
|
AC_FIND_FUNC([localtime_r], [c], [#include <time.h>], [0, 0])
|
||||||
|
AC_FIND_FUNC([localtime], [c], [#include <time.h>], [0])
|
||||||
AC_FIND_FUNC([gettimeofday], [c], [#include <time.h>], [0, 0])
|
AC_FIND_FUNC([gettimeofday], [c], [#include <time.h>], [0, 0])
|
||||||
AC_CHECK_MEMBER([struct tm.tm_gmtoff], [AC_DEFINE([HAVE_TM_TM_GMT_OFF],1,[Define to 1 if the system has the tm_gmt_off field in struct tm])],
|
AC_CHECK_MEMBER([struct tm.tm_gmtoff], [AC_DEFINE([HAVE_TM_TM_GMT_OFF],1,[Define to 1 if the system has the tm_gmt_off field in struct tm])],
|
||||||
[], [[#include <time.h>]])
|
[], [[#include <time.h>]])
|
||||||
|
|||||||
@@ -1283,6 +1283,43 @@ static jv f_gmtime(jq_state *jq, jv a) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LOCALTIME_R
|
||||||
|
static jv f_localtime(jq_state *jq, jv a) {
|
||||||
|
if (jv_get_kind(a) != JV_KIND_NUMBER)
|
||||||
|
return jv_invalid_with_msg(jv_string("localtime() requires numeric inputs"));
|
||||||
|
struct tm tm, *tmp;
|
||||||
|
memset(&tm, 0, sizeof(tm));
|
||||||
|
double fsecs = jv_number_value(a);
|
||||||
|
time_t secs = fsecs;
|
||||||
|
jv_free(a);
|
||||||
|
tmp = localtime_r(&secs, &tm);
|
||||||
|
if (tmp == NULL)
|
||||||
|
return jv_invalid_with_msg(jv_string("errror converting number of seconds since epoch to datetime"));
|
||||||
|
a = tm2jv(tmp);
|
||||||
|
return jv_array_set(a, 5, jv_number(jv_number_value(jv_array_get(jv_copy(a), 5)) + (fsecs - floor(fsecs))));
|
||||||
|
}
|
||||||
|
#elif defined HAVE_GMTIME
|
||||||
|
static jv f_localtime(jq_state *jq, jv a) {
|
||||||
|
if (jv_get_kind(a) != JV_KIND_NUMBER)
|
||||||
|
return jv_invalid_with_msg(jv_string("localtime requires numeric inputs"));
|
||||||
|
struct tm tm, *tmp;
|
||||||
|
memset(&tm, 0, sizeof(tm));
|
||||||
|
double fsecs = jv_number_value(a);
|
||||||
|
time_t secs = fsecs;
|
||||||
|
jv_free(a);
|
||||||
|
tmp = localtime(&secs);
|
||||||
|
if (tmp == NULL)
|
||||||
|
return jv_invalid_with_msg(jv_string("errror converting number of seconds since epoch to datetime"));
|
||||||
|
a = tm2jv(tmp);
|
||||||
|
return jv_array_set(a, 5, jv_number(jv_number_value(jv_array_get(jv_copy(a), 5)) + (fsecs - floor(fsecs))));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static jv f_localtime(jq_state *jq, jv a) {
|
||||||
|
jv_free(a);
|
||||||
|
return jv_invalid_with_msg(jv_string("localtime not implemented on this platform"));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_STRFTIME
|
#ifdef HAVE_STRFTIME
|
||||||
static jv f_strftime(jq_state *jq, jv a, jv b) {
|
static jv f_strftime(jq_state *jq, jv a, jv b) {
|
||||||
if (jv_get_kind(a) == JV_KIND_NUMBER) {
|
if (jv_get_kind(a) == JV_KIND_NUMBER) {
|
||||||
@@ -1311,6 +1348,34 @@ static jv f_strftime(jq_state *jq, jv a) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_STRFTIME
|
||||||
|
static jv f_strflocaltime(jq_state *jq, jv a, jv b) {
|
||||||
|
if (jv_get_kind(a) == JV_KIND_NUMBER) {
|
||||||
|
a = f_localtime(jq, a);
|
||||||
|
} else if (jv_get_kind(a) != JV_KIND_ARRAY) {
|
||||||
|
return jv_invalid_with_msg(jv_string("strflocaltime/1 requires parsed datetime inputs"));
|
||||||
|
}
|
||||||
|
struct tm tm;
|
||||||
|
if (!jv2tm(a, &tm))
|
||||||
|
return jv_invalid_with_msg(jv_string("strflocaltime/1 requires parsed datetime inputs")); \
|
||||||
|
const char *fmt = jv_string_value(b);
|
||||||
|
size_t alloced = strlen(fmt) + 100;
|
||||||
|
char *buf = alloca(alloced);
|
||||||
|
size_t n = strftime(buf, alloced, fmt, &tm);
|
||||||
|
jv_free(b);
|
||||||
|
/* POSIX doesn't provide errno values for strftime() failures; weird */
|
||||||
|
if (n == 0 || n > alloced)
|
||||||
|
return jv_invalid_with_msg(jv_string("strflocaltime/1: unknown system failure"));
|
||||||
|
return jv_string(buf);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static jv f_strflocaltime(jq_state *jq, jv a) {
|
||||||
|
jv_free(a);
|
||||||
|
jv_free(b);
|
||||||
|
return jv_invalid_with_msg(jv_string("strflocaltime/1 not implemented on this platform"));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_GETTIMEOFDAY
|
#ifdef HAVE_GETTIMEOFDAY
|
||||||
static jv f_now(jq_state *jq, jv a) {
|
static jv f_now(jq_state *jq, jv a) {
|
||||||
jv_free(a);
|
jv_free(a);
|
||||||
@@ -1413,8 +1478,10 @@ static const struct cfunction function_list[] = {
|
|||||||
{(cfunction_ptr)f_stderr, "stderr", 1},
|
{(cfunction_ptr)f_stderr, "stderr", 1},
|
||||||
{(cfunction_ptr)f_strptime, "strptime", 2},
|
{(cfunction_ptr)f_strptime, "strptime", 2},
|
||||||
{(cfunction_ptr)f_strftime, "strftime", 2},
|
{(cfunction_ptr)f_strftime, "strftime", 2},
|
||||||
|
{(cfunction_ptr)f_strflocaltime, "strflocaltime", 2},
|
||||||
{(cfunction_ptr)f_mktime, "mktime", 1},
|
{(cfunction_ptr)f_mktime, "mktime", 1},
|
||||||
{(cfunction_ptr)f_gmtime, "gmtime", 1},
|
{(cfunction_ptr)f_gmtime, "gmtime", 1},
|
||||||
|
{(cfunction_ptr)f_localtime, "localtime", 1},
|
||||||
{(cfunction_ptr)f_now, "now", 1},
|
{(cfunction_ptr)f_now, "now", 1},
|
||||||
{(cfunction_ptr)f_current_filename, "input_filename", 1},
|
{(cfunction_ptr)f_current_filename, "input_filename", 1},
|
||||||
{(cfunction_ptr)f_current_line, "input_line_number", 1},
|
{(cfunction_ptr)f_current_line, "input_line_number", 1},
|
||||||
|
|||||||
Reference in new issue
Block a user