#include <time.h>
#include <string.h>
+#include <sys/timex.h>
#include "util.h"
#include "time-util.h"
if (u == (usec_t) -1) {
tv->tv_sec = (time_t) -1;
tv->tv_usec = (suseconds_t) -1;
- return tv;
+ } else {
+ tv->tv_sec = (time_t) (u / USEC_PER_SEC);
+ tv->tv_usec = (suseconds_t) (u % USEC_PER_SEC);
}
- tv->tv_sec = (time_t) (u / USEC_PER_SEC);
- tv->tv_usec = (suseconds_t) (u % USEC_PER_SEC);
-
return tv;
}
assert(buf);
assert(l > 0);
- if (t <= 0)
+ if (t <= 0 || t == (usec_t) -1)
return NULL;
sec = (time_t) (t / USEC_PER_SEC);
return buf;
}
+char *format_timestamp_us(char *buf, size_t l, usec_t t) {
+ struct tm tm;
+ time_t sec;
+
+ assert(buf);
+ assert(l > 0);
+
+ if (t <= 0 || t == (usec_t) -1)
+ return NULL;
+
+ sec = (time_t) (t / USEC_PER_SEC);
+ localtime_r(&sec, &tm);
+
+ if (strftime(buf, l, "%a %Y-%m-%d %H:%M:%S", &tm) <= 0)
+ return NULL;
+ snprintf(buf + strlen(buf), l - strlen(buf), ".%06llu", t % USEC_PER_SEC);
+ if (strftime(buf + strlen(buf), l - strlen(buf), " %Z", &tm) <= 0)
+ return NULL;
+
+ return buf;
+}
+
char *format_timestamp_relative(char *buf, size_t l, usec_t t) {
+ const char *s;
usec_t n, d;
n = now(CLOCK_REALTIME);
- if (t <= 0 || t > n || t + USEC_PER_DAY*7 <= t)
+ if (t <= 0 || (t == (usec_t) -1))
return NULL;
- d = n - t;
+ if (n > t) {
+ d = n - t;
+ s = "ago";
+ } else {
+ d = t - n;
+ s = "left";
+ }
if (d >= USEC_PER_YEAR)
- snprintf(buf, l, "%llu years %llu months ago",
+ snprintf(buf, l, "%llu years %llu months %s",
(unsigned long long) (d / USEC_PER_YEAR),
- (unsigned long long) ((d % USEC_PER_YEAR) / USEC_PER_MONTH));
+ (unsigned long long) ((d % USEC_PER_YEAR) / USEC_PER_MONTH), s);
else if (d >= USEC_PER_MONTH)
- snprintf(buf, l, "%llu months %llu days ago",
+ snprintf(buf, l, "%llu months %llu days %s",
(unsigned long long) (d / USEC_PER_MONTH),
- (unsigned long long) ((d % USEC_PER_MONTH) / USEC_PER_DAY));
+ (unsigned long long) ((d % USEC_PER_MONTH) / USEC_PER_DAY), s);
else if (d >= USEC_PER_WEEK)
- snprintf(buf, l, "%llu weeks %llu days ago",
+ snprintf(buf, l, "%llu weeks %llu days %s",
(unsigned long long) (d / USEC_PER_WEEK),
- (unsigned long long) ((d % USEC_PER_WEEK) / USEC_PER_DAY));
+ (unsigned long long) ((d % USEC_PER_WEEK) / USEC_PER_DAY), s);
else if (d >= 2*USEC_PER_DAY)
- snprintf(buf, l, "%llu days ago", (unsigned long long) (d / USEC_PER_DAY));
+ snprintf(buf, l, "%llu days %s", (unsigned long long) (d / USEC_PER_DAY), s);
else if (d >= 25*USEC_PER_HOUR)
- snprintf(buf, l, "1 day %lluh ago",
- (unsigned long long) ((d - USEC_PER_DAY) / USEC_PER_HOUR));
+ snprintf(buf, l, "1 day %lluh %s",
+ (unsigned long long) ((d - USEC_PER_DAY) / USEC_PER_HOUR), s);
else if (d >= 6*USEC_PER_HOUR)
- snprintf(buf, l, "%lluh ago",
- (unsigned long long) (d / USEC_PER_HOUR));
+ snprintf(buf, l, "%lluh %s",
+ (unsigned long long) (d / USEC_PER_HOUR), s);
else if (d >= USEC_PER_HOUR)
- snprintf(buf, l, "%lluh %llumin ago",
+ snprintf(buf, l, "%lluh %llumin %s",
(unsigned long long) (d / USEC_PER_HOUR),
- (unsigned long long) ((d % USEC_PER_HOUR) / USEC_PER_MINUTE));
+ (unsigned long long) ((d % USEC_PER_HOUR) / USEC_PER_MINUTE), s);
else if (d >= 5*USEC_PER_MINUTE)
- snprintf(buf, l, "%llumin ago",
- (unsigned long long) (d / USEC_PER_MINUTE));
+ snprintf(buf, l, "%llumin %s",
+ (unsigned long long) (d / USEC_PER_MINUTE), s);
else if (d >= USEC_PER_MINUTE)
- snprintf(buf, l, "%llumin %llus ago",
+ snprintf(buf, l, "%llumin %llus %s",
(unsigned long long) (d / USEC_PER_MINUTE),
- (unsigned long long) ((d % USEC_PER_MINUTE) / USEC_PER_SEC));
+ (unsigned long long) ((d % USEC_PER_MINUTE) / USEC_PER_SEC), s);
else if (d >= USEC_PER_SEC)
- snprintf(buf, l, "%llus ago",
- (unsigned long long) (d / USEC_PER_SEC));
+ snprintf(buf, l, "%llus %s",
+ (unsigned long long) (d / USEC_PER_SEC), s);
else if (d >= USEC_PER_MSEC)
- snprintf(buf, l, "%llums ago",
- (unsigned long long) (d / USEC_PER_MSEC));
+ snprintf(buf, l, "%llums %s",
+ (unsigned long long) (d / USEC_PER_MSEC), s);
else if (d > 0)
- snprintf(buf, l, "%lluus ago",
- (unsigned long long) d);
+ snprintf(buf, l, "%lluus %s",
+ (unsigned long long) d, s);
else
snprintf(buf, l, "now");
/* The result of this function can be parsed with parse_sec */
for (i = 0; i < ELEMENTSOF(table); i++) {
- int k;
+ int k = 0;
size_t n;
bool done = false;
usec_t a, b;
assert(value);
assert(t);
- if (sscanf(value, "%lli %llu", &a, &b) != 2)
+ if (sscanf(value, "%llu %llu", &a, &b) != 2)
log_debug("Failed to parse finish timestamp value %s", value);
else {
t->realtime = a;
if (r < 0)
return r;
+ goto finish;
+ } else if (endswith(t, " left")) {
+ _cleanup_free_ char *z;
+
+ z = strndup(t, strlen(t) - 4);
+ if (!z)
+ return -ENOMEM;
+
+ r = parse_sec(z, &plus);
+ if (r < 0)
+ return r;
+
goto finish;
}
return 0;
}
+
+bool ntp_synced(void) {
+ struct timex txc = {};
+
+ if (adjtimex(&txc) < 0)
+ return false;
+
+ if (txc.status & STA_UNSYNC)
+ return false;
+
+ return true;
+}