time-util: add timestamp output style that shows dates only, no times

This commit is contained in:
Lennart Poettering 2023-01-20 13:47:11 +01:00
parent 9b9ea806ad
commit 64f3419ec1
3 changed files with 47 additions and 17 deletions

View file

@ -326,14 +326,15 @@ char *format_timestamp_style(
return snprintf_ok(buf, l, "@" USEC_FMT, t / USEC_PER_SEC); /* round down µs → s */
}
utc = IN_SET(style, TIMESTAMP_UTC, TIMESTAMP_US_UTC);
utc = IN_SET(style, TIMESTAMP_UTC, TIMESTAMP_US_UTC, TIMESTAMP_DATE);
us = IN_SET(style, TIMESTAMP_US, TIMESTAMP_US_UTC);
if (l < (size_t) (3 + /* week day */
1 + 10 + /* space and date */
1 + 8 + /* space and time */
(us ? 1 + 6 : 0) + /* "." and microsecond part */
1 + (utc ? 3 : 1) + /* space and shortest possible zone */
if (l < (size_t) (3 + /* week day */
1 + 10 + /* space and date */
style == TIMESTAMP_DATE ? 0 :
(1 + 8 + /* space and time */
(us ? 1 + 6 : 0) + /* "." and microsecond part */
1 + (utc ? 3 : 1)) + /* space and shortest possible zone */
1))
return NULL; /* Not enough space even for the shortest form. */
@ -344,6 +345,7 @@ char *format_timestamp_style(
[TIMESTAMP_US] = "--- XXXX-XX-XX XX:XX:XX.XXXXXX",
[TIMESTAMP_UTC] = "--- XXXX-XX-XX XX:XX:XX UTC",
[TIMESTAMP_US_UTC] = "--- XXXX-XX-XX XX:XX:XX.XXXXXX UTC",
[TIMESTAMP_DATE] = "--- XXXX-XX-XX",
};
assert(l >= strlen(xxx[style]) + 1);
@ -359,6 +361,14 @@ char *format_timestamp_style(
assert((size_t) tm.tm_wday < ELEMENTSOF(weekdays));
memcpy(buf, weekdays[tm.tm_wday], 4);
if (style == TIMESTAMP_DATE) {
/* Special format string if only date should be shown. */
if (strftime(buf + 3, l - 3, " %Y-%m-%d", &tm) <= 0)
return NULL; /* Doesn't fit */
return buf;
}
/* Add the main components */
if (strftime(buf + 3, l - 3, " %Y-%m-%d %H:%M:%S", &tm) <= 0)
return NULL; /* Doesn't fit */

View file

@ -35,6 +35,7 @@ typedef enum TimestampStyle {
TIMESTAMP_UTC,
TIMESTAMP_US_UTC,
TIMESTAMP_UNIX,
TIMESTAMP_DATE,
_TIMESTAMP_STYLE_MAX,
_TIMESTAMP_STYLE_INVALID = -EINVAL,
} TimestampStyle;

View file

@ -365,6 +365,11 @@ TEST(format_timestamp) {
assert_se(parse_timestamp(buf, &y) >= 0);
assert_se(x == y);
assert_se(format_timestamp_style(buf, sizeof(buf), x, TIMESTAMP_DATE));
log_debug("%s", buf);
assert_se(parse_timestamp(buf, &y) >= 0);
assert_se(y > usec_sub_unsigned(x, 2 * USEC_PER_DAY) && y < usec_add(x, 2* USEC_PER_DAY));
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
log_debug("%s", buf);
assert_se(parse_timestamp(buf, &y) >= 0);
@ -466,28 +471,42 @@ TEST(format_timestamp_relative) {
assert_se(streq(buf, "2 weeks 2 days ago"));
}
static void test_format_timestamp_utc_one(usec_t val, const char *result) {
static void test_format_timestamp_one(usec_t val, TimestampStyle style, const char *result) {
char buf[FORMAT_TIMESTAMP_MAX];
const char *t;
t = format_timestamp_style(buf, sizeof(buf), val, TIMESTAMP_UTC);
t = format_timestamp_style(buf, sizeof(buf), val, style);
assert_se(streq_ptr(t, result));
}
TEST(format_timestamp_utc) {
test_format_timestamp_utc_one(0, NULL);
test_format_timestamp_utc_one(1, "Thu 1970-01-01 00:00:00 UTC");
test_format_timestamp_utc_one(USEC_PER_SEC, "Thu 1970-01-01 00:00:01 UTC");
TEST(format_timestamp_range) {
test_format_timestamp_one(0, TIMESTAMP_UTC, NULL);
test_format_timestamp_one(0, TIMESTAMP_DATE, NULL);
test_format_timestamp_one(0, TIMESTAMP_US_UTC, NULL);
test_format_timestamp_one(1, TIMESTAMP_UTC, "Thu 1970-01-01 00:00:00 UTC");
test_format_timestamp_one(1, TIMESTAMP_DATE, "Thu 1970-01-01");
test_format_timestamp_one(1, TIMESTAMP_US_UTC, "Thu 1970-01-01 00:00:00.000001 UTC");
test_format_timestamp_one(USEC_PER_SEC, TIMESTAMP_UTC, "Thu 1970-01-01 00:00:01 UTC");
test_format_timestamp_one(USEC_PER_SEC, TIMESTAMP_DATE, "Thu 1970-01-01");
test_format_timestamp_one(USEC_PER_SEC, TIMESTAMP_US_UTC, "Thu 1970-01-01 00:00:01.000000 UTC");
#if SIZEOF_TIME_T == 8
test_format_timestamp_utc_one(USEC_TIMESTAMP_FORMATTABLE_MAX, "Thu 9999-12-30 23:59:59 UTC");
test_format_timestamp_utc_one(USEC_TIMESTAMP_FORMATTABLE_MAX + 1, "--- XXXX-XX-XX XX:XX:XX UTC");
test_format_timestamp_one(USEC_TIMESTAMP_FORMATTABLE_MAX, TIMESTAMP_UTC, "Thu 9999-12-30 23:59:59 UTC");
test_format_timestamp_one(USEC_TIMESTAMP_FORMATTABLE_MAX, TIMESTAMP_DATE, "Thu 9999-12-30");
test_format_timestamp_one(USEC_TIMESTAMP_FORMATTABLE_MAX + 1, TIMESTAMP_UTC, "--- XXXX-XX-XX XX:XX:XX UTC");
test_format_timestamp_one(USEC_TIMESTAMP_FORMATTABLE_MAX + 1, TIMESTAMP_US_UTC, "--- XXXX-XX-XX XX:XX:XX.XXXXXX UTC");
test_format_timestamp_one(USEC_TIMESTAMP_FORMATTABLE_MAX + 1, TIMESTAMP_DATE, "--- XXXX-XX-XX");
#elif SIZEOF_TIME_T == 4
test_format_timestamp_utc_one(USEC_TIMESTAMP_FORMATTABLE_MAX, "Tue 2038-01-19 03:14:07 UTC");
test_format_timestamp_utc_one(USEC_TIMESTAMP_FORMATTABLE_MAX + 1, "--- XXXX-XX-XX XX:XX:XX UTC");
test_format_timestamp_one(USEC_TIMESTAMP_FORMATTABLE_MAX, TIMESTAMP_UTC, "Tue 2038-01-19 03:14:07 UTC");
test_format_timestamp_one(USEC_TIMESTAMP_FORMATTABLE_MAX, TIMESTAMP_DATE, "Tue 2038-01-19");
test_format_timestamp_one(USEC_TIMESTAMP_FORMATTABLE_MAX + 1, TIMESTAMP_UTC, "--- XXXX-XX-XX XX:XX:XX UTC");
test_format_timestamp_one(USEC_TIMESTAMP_FORMATTABLE_MAX + 1, TIMESTAMP_US_UTC, "--- XXXX-XX-XX XX:XX:XX.XXXXXX UTC");
test_format_timestamp_one(USEC_TIMESTAMP_FORMATTABLE_MAX + 1, TIMESTAMP_DATE, "--- XXXX-XX-XX");
#endif
test_format_timestamp_utc_one(USEC_INFINITY, NULL);
test_format_timestamp_one(USEC_INFINITY, TIMESTAMP_UTC, NULL);
}
TEST(deserialize_dual_timestamp) {