<command>systemd-analyze</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="plain">calendar</arg>
- <arg choice="plain" rep="repeat"><replaceable>SPECS</replaceable></arg>
+ <arg choice="plain" rep="repeat"><replaceable>SPEC</replaceable></arg>
+ </cmdsynopsis>
+ <cmdsynopsis>
+ <command>systemd-analyze</command>
+ <arg choice="opt" rep="repeat">OPTIONS</arg>
+ <arg choice="plain">timestamp</arg>
+ <arg choice="plain" rep="repeat"><replaceable>TIMESTAMP</replaceable></arg>
</cmdsynopsis>
<cmdsynopsis>
<command>systemd-analyze</command>
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>. By
default, only the next time the calendar expression will elapse is shown; use
<option>--iterations=</option> to show the specified number of next times the expression
- elapses.</para>
+ elapses. Each time the expression elapses forms a timestamp, see the <command>timestamp</command>
+ verb below.</para>
<example>
<title>Show leap days in the near future</title>
</example>
</refsect2>
+ <refsect2>
+ <title><command>systemd-analyze timestamp <replaceable>TIMESTAMP</replaceable>...</command></title>
+
+ <para>This command parses a timestamp (i.e. a single point in time) and outputs the normalized form and
+ the difference between this timestamp and now. The timestamp should adhere to the syntax documented in
+ <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ section "PARSING TIMESTAMPS".</para>
+
+ <example>
+ <title>Show parsing of timestamps</title>
+
+ <programlisting>$ systemd-analyze timestamp yesterday now tomorrow
+ Original form: yesterday
+Normalized form: Thu 2019-05-16 00:00:00 CEST
+ (in UTC): Wed 2019-05-15 22:00:00 UTC
+ From now: 1 day 9h ago
+
+ Original form: now
+Normalized form: Fri 2019-05-17 09:34:14 CEST
+ (in UTC): Fri 2019-05-17 07:34:14 UTC
+ From now: 32us ago
+
+ Original form: tomorrow
+Normalized form: Sat 2019-05-18 00:00:00 CEST
+ (in UTC): Fri 2019-05-17 22:00:00 UTC
+ From now: 14h left
+</programlisting>
+ </example>
+ </refsect2>
+
<refsect2>
<title><command>systemd-analyze timespan <replaceable>EXPRESSION</replaceable>...</command></title>
- <para>This command parses a time span and outputs the normalized form and the equivalent value in
- microseconds. The time span should adhere to the same syntax documented in
- <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
- Values without associated magnitudes are parsed as seconds.</para>
+ <para>This command parses a time span (i.e. a difference between two timestamps) and outputs the
+ normalized form and the equivalent value in microseconds. The time span should adhere to the syntax
+ documented in
+ <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ section "PARSING TIME SPANS". Values without units are parsed as seconds.</para>
<example>
<title>Show parsing of timespans</title>
printf("Original: %s\n", *input_timespan);
printf(" %ss: %" PRIu64 "\n", special_glyph(SPECIAL_GLYPH_MU), output_usecs);
- printf(" Human: %s\n", format_timespan(ft_buf, sizeof(ft_buf), output_usecs, usec_magnitude));
+ printf(" Human: %s%s%s\n",
+ ansi_highlight(),
+ format_timespan(ft_buf, sizeof(ft_buf), output_usecs, usec_magnitude),
+ ansi_normal());
if (input_timespan[1])
putchar('\n');
return EXIT_SUCCESS;
}
+static int test_timestamp_one(const char *p) {
+ usec_t usec;
+ char buf[FORMAT_TIMESTAMP_MAX];
+ int r;
+
+ r = parse_timestamp(p, &usec);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse \"%s\": %m", p);
+
+ printf(" Original form: %s\n", p);
+ printf("Normalized form: %s%s%s\n",
+ ansi_highlight_blue(),
+ format_timestamp(buf, sizeof buf, usec),
+ ansi_normal());
+
+ if (!in_utc_timezone())
+ printf(" (in UTC): %s\n", format_timestamp_utc(buf, sizeof buf, usec));
+
+ printf(" From now: %s\n", format_timestamp_relative(buf, sizeof buf, usec));
+
+ return 0;
+}
+
+static int test_timestamp(int argc, char *argv[], void *userdata) {
+ int ret = 0, r;
+ char **p;
+
+ STRV_FOREACH(p, strv_skip(argv, 1)) {
+ r = test_timestamp_one(*p);
+ if (ret == 0 && r < 0)
+ ret = r;
+
+ if (*(p + 1))
+ putchar('\n');
+ }
+
+ return ret;
+}
+
static int test_calendar_one(usec_t n, const char *p) {
_cleanup_(calendar_spec_freep) CalendarSpec *spec = NULL;
_cleanup_free_ char *t = NULL;
" unit-paths List load directories for units\n"
" syscall-filter [NAME...] Print list of syscalls in seccomp filter\n"
" verify FILE... Check unit files for correctness\n"
- " calendar SPEC... Validate repetitive calendar time events\n"
" service-watchdogs [BOOL] Get/set service watchdog state\n"
+ " calendar SPEC... Validate repetitive calendar time events\n"
+ " timestamp TIMESTAMP... Validate a timestamp\n"
" timespan SPAN... Validate a time span\n"
" security [UNIT...] Analyze security of unit\n"
"\nSee the %s for details.\n"
{ "syscall-filter", VERB_ANY, VERB_ANY, 0, dump_syscall_filters },
{ "verify", 2, VERB_ANY, 0, do_verify },
{ "calendar", 2, VERB_ANY, 0, test_calendar },
- { "service-watchdogs", VERB_ANY, 2, 0, service_watchdogs },
+ { "timestamp", 2, VERB_ANY, 0, test_timestamp },
{ "timespan", 2, VERB_ANY, 0, dump_timespan },
+ { "service-watchdogs", VERB_ANY, 2, 0, service_watchdogs },
{ "security", VERB_ANY, VERB_ANY, 0, do_security },
{}
};