From: Petr Špaček Date: Wed, 2 Jan 2019 13:56:53 +0000 (+0100) Subject: utils: diff between two calendar times in strings X-Git-Tag: v3.2.1~5^2~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c487ecb5a3469b46e08e97c22d5eab749057da27;p=thirdparty%2Fknot-resolver.git utils: diff between two calendar times in strings --- diff --git a/daemon/lua/kres-gen.lua b/daemon/lua/kres-gen.lua index a041ed603..eeb8ff7ca 100644 --- a/daemon/lua/kres-gen.lua +++ b/daemon/lua/kres-gen.lua @@ -315,6 +315,7 @@ int kr_zonecut_add(struct kr_zonecut *, const knot_dname_t *, const void *, int) _Bool kr_zonecut_is_empty(struct kr_zonecut *); void kr_zonecut_set(struct kr_zonecut *, const knot_dname_t *); uint64_t kr_now(); +const char *kr_strptime_diff(const char *, const char *, const char *, double *); void lru_free_items_impl(struct lru *); struct lru *lru_create_impl(unsigned int, knot_mm_t *, knot_mm_t *); void *lru_get_impl(struct lru *, const char *, unsigned int, unsigned int, _Bool, _Bool *); diff --git a/daemon/lua/kres-gen.sh b/daemon/lua/kres-gen.sh index 661a001f1..538fe239e 100755 --- a/daemon/lua/kres-gen.sh +++ b/daemon/lua/kres-gen.sh @@ -169,6 +169,7 @@ EOF kr_zonecut_is_empty kr_zonecut_set kr_now + kr_strptime_diff lru_free_items_impl lru_create_impl lru_get_impl diff --git a/lib/utils.c b/lib/utils.c index 1d4be296f..fe9ab03b5 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -948,6 +948,38 @@ uint64_t kr_now() return uv_now(uv_default_loop()); } +const char *kr_strptime_diff(const char *format, const char *time1_str, + const char *time0_str, double *diff) { + assert(format != NULL); + assert(time1_str != NULL); + assert(time0_str != NULL); + assert(diff != NULL); + + struct tm time1_tm; + time_t time1_u; + struct tm time0_tm; + time_t time0_u; + + char *err = strptime(time1_str, format, &time1_tm); + if (err == NULL || err != time1_str + strlen(time1_str)) + return "strptime failed for time1"; + time1_tm.tm_isdst = -1; /* determine if DST is active or not */ + time1_u = mktime(&time1_tm); + if (time1_u == (time_t)-1) + return "mktime failed for time1"; + + err = strptime(time0_str, format, &time0_tm); + if (err == NULL || err != time0_str + strlen(time0_str)) + return "strptime failed for time0"; + time0_tm.tm_isdst = -1; /* determine if DST is active or not */ + time0_u = mktime(&time0_tm); + if (time0_u == (time_t)-1) + return "mktime failed for time0"; + *diff = difftime(time1_u, time0_u); + + return NULL; +} + int knot_dname_lf2wire(knot_dname_t * const dst, uint8_t len, const uint8_t *lf) { knot_dname_t *d = dst; /* moving "cursor" as we write it out */ diff --git a/lib/utils.h b/lib/utils.h index 8e4e1ad4b..21eabac80 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -476,6 +476,15 @@ static inline int kr_dname_lf(uint8_t *dst, const knot_dname_t *src, bool add_wi return KNOT_EOK; } +/** + * Difference between two calendar times specified as strings. + * \param format[in] format for strptime + * \param diff[out] result from C difftime(time1, time0) + */ +KR_EXPORT +const char *kr_strptime_diff(const char *format, const char *time1_str, + const char *time0_str, double *diff); + /* Trivial non-inline wrappers, to be used in lua. */ KR_EXPORT void kr_rrset_init(knot_rrset_t *rrset, knot_dname_t *owner, uint16_t type, uint16_t rclass, uint32_t ttl); diff --git a/tests/test_utils.c b/tests/test_utils.c index 07856560e..e6371c300 100644 --- a/tests/test_utils.c +++ b/tests/test_utils.c @@ -79,11 +79,44 @@ static void test_straddr(void **state) assert_int_not_equal(test_bitcmp(ip6_sub, ip6_out, 4), 0); } +static void test_strptime_diff(void **state) +{ + char *format = "%Y-%m-%dT%H:%M:%S"; + const char *errmsg = NULL; + double output; + + errmsg = kr_strptime_diff(format, + "2019-01-09T12:06:04", + "2019-01-09T12:06:04", &output); + assert_true(errmsg == NULL); + /* double type -> equality is not reliable */ + assert_true(output > -0.01 && output < 0.01); + + errmsg = kr_strptime_diff(format, + "2019-01-09T12:06:04", + "2019-01-09T11:06:04", &output); + assert_true(errmsg == NULL); + /* double type -> equality is not reliable */ + assert_true(output > -3600.01 && output < 3600.01); + + /* invalid inputs */ + errmsg = kr_strptime_diff(format, + "2019-01-09T25:06:04", + "2019-01-09T11:06:04", &output); + assert_true(errmsg != NULL); + + errmsg = kr_strptime_diff("fail", + "2019-01-09T23:06:04", + "2019-01-09T11:06:04", &output); + assert_true(errmsg != NULL); +} + int main(void) { const UnitTest tests[] = { unit_test(test_strcatdup), unit_test(test_straddr), + unit_test(test_strptime_diff), }; return run_tests(tests);