From 9983cbb4cef92d68ffde87dcc91913cc2fed3da5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Martti=20Rannanj=C3=A4rvi?= Date: Thu, 8 Dec 2016 13:01:48 +0200 Subject: [PATCH] lib: add t_strfgmtime and t_strftime --- src/lib/test-time-util.c | 60 ++++++++++++++++++++++++++++++++++++++++ src/lib/time-util.c | 19 +++++++++++-- src/lib/time-util.h | 4 ++- 3 files changed, 79 insertions(+), 4 deletions(-) diff --git a/src/lib/test-time-util.c b/src/lib/test-time-util.c index 4a9a74d177..9dfd573585 100644 --- a/src/lib/test-time-util.c +++ b/src/lib/test-time-util.c @@ -3,6 +3,8 @@ #include "test-lib.h" #include "time-util.h" +#include + static void test_timeval_cmp(void) { static struct timeval input[] = { @@ -68,8 +70,66 @@ static void test_timeval_diff(void) test_end(); } +static void test_timestamp(const char *ts, int idx) +{ + /* %G:%H:%M:%S */ + const char **t = t_strsplit(ts, ":"); + unsigned len = str_array_length(t); + test_assert_idx(len == 4, idx); + + /* %G - ISO 8601 year */ + test_assert_idx(strlen(t[0]) == 4, idx); + unsigned v; + test_assert_idx(str_to_uint(t[0], &v) == 0, idx); + test_assert_idx(1000 <= v, idx); + test_assert_idx(v <= 3000, idx); + + /* %H - hour from 00 to 23 */ + test_assert_idx(strlen(t[1]) == 2, idx); + test_assert_idx(str_to_uint(t[1], &v) == 0, idx); + test_assert_idx(v <= 23, idx); + + /* %M - minute from 00 to 59 */ + test_assert_idx(strlen(t[2]) == 2, idx); + test_assert_idx(str_to_uint(t[2], &v) == 0, idx); + test_assert_idx(v <= 59, idx); + + /* %S - second from 00 to 60 */ + test_assert_idx(strlen(t[3]) == 2, idx); + test_assert_idx(str_to_uint(t[3], &v) == 0, idx); + test_assert_idx(v <= 60, idx); +} + +#define TS_FMT "%G:%H:%M:%S" +static void test_strftime_now(void) +{ + test_begin("t_strftime and variants now"); + + time_t now = time(NULL); + test_timestamp(t_strftime(TS_FMT, gmtime(&now)), 0); + test_timestamp(t_strfgmtime(TS_FMT, now), 1); + test_timestamp(t_strflocaltime(TS_FMT, now), 2); + + test_end(); +} + +#define RFC2822_FMT "%a, %d %b %Y %T %z" +static void test_strftime_fixed(void) +{ + test_begin("t_strftime and variants fixed timestamp"); + + time_t ts = 1481222536; + const char *exp = "Thu, 08 Dec 2016 18:42:16 +0000"; + test_assert(strcmp(t_strftime(RFC2822_FMT, gmtime(&ts)), exp) == 0); + test_assert(strcmp(t_strfgmtime(RFC2822_FMT, ts), exp) == 0); + + test_end(); +} + void test_time_util(void) { test_timeval_cmp(); test_timeval_diff(); + test_strftime_now(); + test_strftime_fixed(); } diff --git a/src/lib/time-util.c b/src/lib/time-util.c index 3ab1a86821..eebc1f738b 100644 --- a/src/lib/time-util.c +++ b/src/lib/time-util.c @@ -55,14 +55,12 @@ long long timeval_diff_usecs(const struct timeval *tv1, return ((long long)secs * 1000000LL) + usecs; } -const char *t_strflocaltime(const char *fmt, time_t t) +static const char *strftime_real(const char *fmt, const struct tm *tm) { - const struct tm *tm; size_t bufsize = strlen(fmt) + 32; char *buf = t_buffer_get(bufsize); size_t ret; - tm = localtime(&t); while ((ret = strftime(buf, bufsize, fmt, tm)) == 0) { bufsize *= 2; i_assert(bufsize <= STRFTIME_MAX_BUFSIZE); @@ -71,3 +69,18 @@ const char *t_strflocaltime(const char *fmt, time_t t) t_buffer_alloc(ret + 1); return buf; } + +const char *t_strftime(const char *fmt, const struct tm *tm) +{ + return strftime_real(fmt, tm); +} + +const char *t_strflocaltime(const char *fmt, time_t t) +{ + return strftime_real(fmt, localtime(&t)); +} + +const char *t_strfgmtime(const char *fmt, time_t t) +{ + return strftime_real(fmt, gmtime(&t)); +} diff --git a/src/lib/time-util.h b/src/lib/time-util.h index befeebb40c..ef3643ce64 100644 --- a/src/lib/time-util.h +++ b/src/lib/time-util.h @@ -36,7 +36,9 @@ timeval_sub_msecs(struct timeval *tv, unsigned int msecs) } } -/* Wrapper to strftime() */ +/* Wrappers to strftime() */ +const char *t_strftime(const char *fmt, const struct tm *tm) ATTR_STRFTIME(1); const char *t_strflocaltime(const char *fmt, time_t t) ATTR_STRFTIME(1); +const char *t_strfgmtime(const char *fmt, time_t t) ATTR_STRFTIME(1); #endif -- 2.47.3