Commit c487ecb5 authored by Petr Špaček's avatar Petr Špaček

utils: diff between two calendar times in strings

parent ee65b8a2
......@@ -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 *);
......
......@@ -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
......
......@@ -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 */
......
......@@ -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);
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment