lib/timeutils: parse_timestamp: parse usecs

Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
This commit is contained in:
Thomas Weißschuh 2023-01-20 02:18:30 +00:00
parent 2abb8394fa
commit c061d1a774

View file

@ -147,6 +147,26 @@ static int parse_sec(const char *t, usec_t *usec)
return 0;
}
static int parse_subseconds(const char *t, usec_t *usec)
{
usec_t ret = 0;
int factor = USEC_PER_SEC / 10;
if (*t != '.' && *t != ',')
return -1;
while (*(++t)) {
if (!isdigit(*t) || factor < 1)
return -1;
ret += ((usec_t) *t - '0') * factor;
factor /= 10;
}
*usec = ret;
return 0;
}
static int parse_timestamp_reference(time_t x, const char *t, usec_t *usec)
{
static const struct {
@ -171,27 +191,35 @@ static int parse_timestamp_reference(time_t x, const char *t, usec_t *usec)
const char *k;
struct tm tm, copy;
usec_t plus = 0, minus = 0, ret;
usec_t plus = 0, minus = 0, ret = 0;
int r, weekday = -1;
unsigned i;
/*
* Allowed syntaxes:
*
* 2012-09-22 16:34:22
* 2012-09-22T16:34:22
* @1348331662 (seconds since the Epoch (1970-01-01 00:00 UTC))
* 2012-09-22 16:34 (seconds will be set to 0)
* 2012-09-22 (time will be set to 00:00:00)
* 16:34:22 (date will be set to today)
* 16:34 (date will be set to today, seconds to 0)
* 2012-09-22 16:34:22 !
* 2012-09-22T16:34:22 !
* 20120922163422 !
* @1348331662 ! (seconds since the Epoch (1970-01-01 00:00 UTC))
* 2012-09-22 16:34 (seconds will be set to 0)
* 2012-09-22 (time will be set to 00:00:00)
* 16:34:22 ! (date will be set to today)
* 16:34 (date will be set to today, seconds to 0)
* now
* yesterday (time is set to 00:00:00)
* today (time is set to 00:00:00)
* tomorrow (time is set to 00:00:00)
* yesterday (time is set to 00:00:00)
* today (time is set to 00:00:00)
* tomorrow (time is set to 00:00:00)
* +5min
* -5days
*
* Syntaxes marked with '!' also optionally allow up to six digits of
* subsecond granularity, separated by '.' or ',':
*
* 2012-09-22 16:34:22.12
* 2012-09-22 16:34:22.123456
*
*
*/
assert(t);
@ -235,6 +263,8 @@ static int parse_timestamp_reference(time_t x, const char *t, usec_t *usec)
k = strptime(t + 1, "%s", &tm);
if (k && *k == 0)
goto finish;
else if (k && parse_subseconds(k, &ret) == 0)
goto finish;
return -EINVAL;
} else if (endswith(t, " ago")) {
@ -271,16 +301,22 @@ static int parse_timestamp_reference(time_t x, const char *t, usec_t *usec)
k = strptime(t, "%y-%m-%d %H:%M:%S", &tm);
if (k && *k == 0)
goto finish;
else if (k && parse_subseconds(k, &ret) == 0)
goto finish;
tm = copy;
k = strptime(t, "%Y-%m-%d %H:%M:%S", &tm);
if (k && *k == 0)
goto finish;
else if (k && parse_subseconds(k, &ret) == 0)
goto finish;
tm = copy;
k = strptime(t, "%Y-%m-%dT%H:%M:%S", &tm);
if (k && *k == 0)
goto finish;
else if (k && parse_subseconds(k, &ret) == 0)
goto finish;
tm = copy;
k = strptime(t, "%y-%m-%d %H:%M", &tm);
@ -314,6 +350,8 @@ static int parse_timestamp_reference(time_t x, const char *t, usec_t *usec)
k = strptime(t, "%H:%M:%S", &tm);
if (k && *k == 0)
goto finish;
else if (k && parse_subseconds(k, &ret) == 0)
goto finish;
tm = copy;
k = strptime(t, "%H:%M", &tm);
@ -326,6 +364,8 @@ static int parse_timestamp_reference(time_t x, const char *t, usec_t *usec)
k = strptime(t, "%Y%m%d%H%M%S", &tm);
if (k && *k == 0)
goto finish;
else if (k && parse_subseconds(k, &ret) == 0)
goto finish;
return -EINVAL;
@ -337,7 +377,7 @@ static int parse_timestamp_reference(time_t x, const char *t, usec_t *usec)
if (weekday >= 0 && tm.tm_wday != weekday)
return -EINVAL;
ret = (usec_t) x *USEC_PER_SEC;
ret += (usec_t) x * USEC_PER_SEC;
ret += plus;
if (ret > minus)
@ -586,19 +626,24 @@ static int run_unittest_timestamp(void)
const char * const input;
usec_t expected;
} testcases[] = {
{ "2012-09-22 16:34:22", 1348331662000000 },
{ "@1348331662" , 1348331662000000 },
{ "2012-09-22 16:34" , 1348331640000000 },
{ "2012-09-22" , 1348272000000000 },
{ "16:34:22" , 1674232462000000 },
{ "16:34" , 1674232440000000 },
{ "now" , 1674180427000000 },
{ "yesterday" , 1674086400000000 },
{ "today" , 1674172800000000 },
{ "tomorrow" , 1674259200000000 },
{ "+5min" , 1674180727000000 },
{ "-5days" , 1673748427000000 },
{ "20120922163422" , 1348331662000000 },
{ "2012-09-22 16:34:22" , 1348331662000000 },
{ "2012-09-22 16:34:22,012", 1348331662012000 },
{ "2012-09-22 16:34:22.012", 1348331662012000 },
{ "@1348331662" , 1348331662000000 },
{ "@1348331662.234567" , 1348331662234567 },
{ "2012-09-22 16:34" , 1348331640000000 },
{ "2012-09-22" , 1348272000000000 },
{ "16:34:22" , 1674232462000000 },
{ "16:34:22,123456" , 1674232462123456 },
{ "16:34:22.123456" , 1674232462123456 },
{ "16:34" , 1674232440000000 },
{ "now" , 1674180427000000 },
{ "yesterday" , 1674086400000000 },
{ "today" , 1674172800000000 },
{ "tomorrow" , 1674259200000000 },
{ "+5min" , 1674180727000000 },
{ "-5days" , 1673748427000000 },
{ "20120922163422" , 1348331662000000 },
};
if (unsetenv("TZ"))