return buf;
}
-char* format_timestamp_relative_full(char *buf, size_t l, usec_t t, bool implicit_left) {
+char* format_timestamp_relative_full(char *buf, size_t l, usec_t t, clockid_t clock, bool implicit_left) {
const char *s;
usec_t n, d;
if (!timestamp_is_set(t))
return NULL;
- n = now(CLOCK_REALTIME);
+ n = now(clock);
if (n > t) {
d = n - t;
s = " ago";
#define TIMEVAL_STORE(u) timeval_store(&(struct timeval) {}, (u))
char* format_timestamp_style(char *buf, size_t l, usec_t t, TimestampStyle style) _warn_unused_result_;
-char* format_timestamp_relative_full(char *buf, size_t l, usec_t t, bool implicit_left) _warn_unused_result_;
+char* format_timestamp_relative_full(char *buf, size_t l, usec_t t, clockid_t clock, bool implicit_left) _warn_unused_result_;
char* format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) _warn_unused_result_;
_warn_unused_result_
-static inline char* format_timestamp_relative(char *buf, size_t l, usec_t t) {
- return format_timestamp_relative_full(buf, l, t, false);
+static inline char* format_timestamp_relative(char *buf, size_t l, usec_t t) {
+ return format_timestamp_relative_full(buf, l, t, CLOCK_REALTIME, /* implicit_left = */ false);
+}
+_warn_unused_result_
+static inline char* format_timestamp_relative_monotonic(char *buf, size_t l, usec_t t) {
+ return format_timestamp_relative_full(buf, l, t, CLOCK_MONOTONIC, /* implicit_left = */ false);
}
_warn_unused_result_
#define FORMAT_TIMESTAMP(t) format_timestamp((char[FORMAT_TIMESTAMP_MAX]){}, FORMAT_TIMESTAMP_MAX, t)
#define FORMAT_TIMESTAMP_RELATIVE(t) \
format_timestamp_relative((char[FORMAT_TIMESTAMP_RELATIVE_MAX]){}, FORMAT_TIMESTAMP_RELATIVE_MAX, t)
+#define FORMAT_TIMESTAMP_RELATIVE_MONOTONIC(t) \
+ format_timestamp_relative_monotonic((char[FORMAT_TIMESTAMP_RELATIVE_MAX]){}, FORMAT_TIMESTAMP_RELATIVE_MAX, t)
#define FORMAT_TIMESPAN(t, accuracy) format_timespan((char[FORMAT_TIMESPAN_MAX]){}, FORMAT_TIMESPAN_MAX, t, accuracy)
#define FORMAT_TIMESTAMP_STYLE(t, style) \
format_timestamp_style((char[FORMAT_TIMESTAMP_MAX]){}, FORMAT_TIMESTAMP_MAX, t, style)
case TABLE_TIMESTAMP:
case TABLE_TIMESTAMP_UTC:
case TABLE_TIMESTAMP_RELATIVE:
+ case TABLE_TIMESTAMP_RELATIVE_MONOTONIC:
case TABLE_TIMESTAMP_LEFT:
case TABLE_TIMESTAMP_DATE:
case TABLE_TIMESPAN:
case TABLE_TIMESTAMP:
case TABLE_TIMESTAMP_UTC:
case TABLE_TIMESTAMP_RELATIVE:
+ case TABLE_TIMESTAMP_RELATIVE_MONOTONIC:
case TABLE_TIMESTAMP_LEFT:
case TABLE_TIMESTAMP_DATE:
case TABLE_TIMESPAN:
case TABLE_TIMESTAMP:
case TABLE_TIMESTAMP_UTC:
case TABLE_TIMESTAMP_RELATIVE:
+ case TABLE_TIMESTAMP_RELATIVE_MONOTONIC:
case TABLE_TIMESTAMP_LEFT:
case TABLE_TIMESTAMP_DATE:
return CMP(a->timestamp, b->timestamp);
case TABLE_TIMESTAMP:
case TABLE_TIMESTAMP_UTC:
case TABLE_TIMESTAMP_RELATIVE:
+ case TABLE_TIMESTAMP_RELATIVE_MONOTONIC:
case TABLE_TIMESTAMP_LEFT:
case TABLE_TIMESTAMP_DATE: {
_cleanup_free_ char *p = NULL;
char *ret;
p = new(char,
- IN_SET(d->type, TABLE_TIMESTAMP_RELATIVE, TABLE_TIMESTAMP_LEFT) ?
+ IN_SET(d->type, TABLE_TIMESTAMP_RELATIVE, TABLE_TIMESTAMP_RELATIVE_MONOTONIC, TABLE_TIMESTAMP_LEFT) ?
FORMAT_TIMESTAMP_RELATIVE_MAX : FORMAT_TIMESTAMP_MAX);
if (!p)
return NULL;
ret = format_timestamp_style(p, FORMAT_TIMESTAMP_MAX, d->timestamp, TIMESTAMP_UTC);
else if (d->type == TABLE_TIMESTAMP_DATE)
ret = format_timestamp_style(p, FORMAT_TIMESTAMP_MAX, d->timestamp, TIMESTAMP_DATE);
+ else if (d->type == TABLE_TIMESTAMP_RELATIVE_MONOTONIC)
+ ret = format_timestamp_relative_full(p, FORMAT_TIMESTAMP_RELATIVE_MAX,
+ d->timestamp, CLOCK_MONOTONIC,
+ /* implicit_left = */ false);
else
- ret = format_timestamp_relative_full(
- p, FORMAT_TIMESTAMP_RELATIVE_MAX, d->timestamp,
- /* implicit_left= */ d->type == TABLE_TIMESTAMP_LEFT);
+ ret = format_timestamp_relative_full(p, FORMAT_TIMESTAMP_RELATIVE_MAX,
+ d->timestamp, CLOCK_REALTIME,
+ /* implicit_left = */ d->type == TABLE_TIMESTAMP_LEFT);
if (!ret)
return "-";
case TABLE_TIMESTAMP:
case TABLE_TIMESTAMP_UTC:
case TABLE_TIMESTAMP_RELATIVE:
+ case TABLE_TIMESTAMP_RELATIVE_MONOTONIC:
case TABLE_TIMESTAMP_LEFT:
case TABLE_TIMESTAMP_DATE:
if (d->timestamp == USEC_INFINITY)
TABLE_TIMESTAMP,
TABLE_TIMESTAMP_UTC,
TABLE_TIMESTAMP_RELATIVE,
+ TABLE_TIMESTAMP_RELATIVE_MONOTONIC,
TABLE_TIMESTAMP_LEFT,
TABLE_TIMESTAMP_DATE,
TABLE_TIMESPAN,
/* Years and months */
x = now(CLOCK_REALTIME) - (1*USEC_PER_YEAR + 1*USEC_PER_MONTH);
- assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, true));
+ assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, CLOCK_REALTIME, true));
log_debug("%s", buf);
assert_se(streq(buf, "1 year 1 month ago"));
+ x = now(CLOCK_MONOTONIC) + (1*USEC_PER_YEAR + 1.5*USEC_PER_MONTH);
+ assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, CLOCK_MONOTONIC, false));
+ log_debug("%s", buf);
+ assert_se(streq(buf, "1 year 1 month left"));
+
x = now(CLOCK_REALTIME) - (1*USEC_PER_YEAR + 2*USEC_PER_MONTH);
- assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, true));
+ assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, CLOCK_REALTIME, true));
log_debug("%s", buf);
assert_se(streq(buf, "1 year 2 months ago"));
x = now(CLOCK_REALTIME) - (2*USEC_PER_YEAR + 1*USEC_PER_MONTH);
- assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, true));
+ assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, CLOCK_REALTIME, true));
log_debug("%s", buf);
assert_se(streq(buf, "2 years 1 month ago"));
x = now(CLOCK_REALTIME) - (2*USEC_PER_YEAR + 2*USEC_PER_MONTH);
- assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, true));
+ assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, CLOCK_REALTIME, true));
log_debug("%s", buf);
assert_se(streq(buf, "2 years 2 months ago"));
/* Months and days */
x = now(CLOCK_REALTIME) - (1*USEC_PER_MONTH + 1*USEC_PER_DAY);
- assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, true));
+ assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, CLOCK_REALTIME, true));
log_debug("%s", buf);
assert_se(streq(buf, "1 month 1 day ago"));
x = now(CLOCK_REALTIME) - (1*USEC_PER_MONTH + 2*USEC_PER_DAY);
- assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, true));
+ assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, CLOCK_REALTIME, true));
log_debug("%s", buf);
assert_se(streq(buf, "1 month 2 days ago"));
x = now(CLOCK_REALTIME) - (2*USEC_PER_MONTH + 1*USEC_PER_DAY);
- assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, true));
+ assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, CLOCK_REALTIME, true));
log_debug("%s", buf);
assert_se(streq(buf, "2 months 1 day ago"));
x = now(CLOCK_REALTIME) - (2*USEC_PER_MONTH + 2*USEC_PER_DAY);
- assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, true));
+ assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, CLOCK_REALTIME, true));
log_debug("%s", buf);
assert_se(streq(buf, "2 months 2 days ago"));
/* Weeks and days */
x = now(CLOCK_REALTIME) - (1*USEC_PER_WEEK + 1*USEC_PER_DAY);
- assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, true));
+ assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, CLOCK_REALTIME, true));
log_debug("%s", buf);
assert_se(streq(buf, "1 week 1 day ago"));
x = now(CLOCK_REALTIME) - (1*USEC_PER_WEEK + 2*USEC_PER_DAY);
- assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, true));
+ assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, CLOCK_REALTIME, true));
log_debug("%s", buf);
assert_se(streq(buf, "1 week 2 days ago"));
x = now(CLOCK_REALTIME) - (2*USEC_PER_WEEK + 1*USEC_PER_DAY);
- assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, true));
+ assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, CLOCK_REALTIME, true));
log_debug("%s", buf);
assert_se(streq(buf, "2 weeks 1 day ago"));
x = now(CLOCK_REALTIME) - (2*USEC_PER_WEEK + 2*USEC_PER_DAY);
- assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, true));
+ assert_se(format_timestamp_relative_full(buf, sizeof(buf), x, CLOCK_REALTIME, true));
log_debug("%s", buf);
assert_se(streq(buf, "2 weeks 2 days ago"));
}