lib/timeutils: parse_timestamp: parse usecs
Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
This commit is contained in:
parent
2abb8394fa
commit
c061d1a774
1 changed files with 70 additions and 25 deletions
|
@ -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"))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue