{"id":3869,"date":"2024-02-19T06:20:16","date_gmt":"2024-02-19T11:20:16","guid":{"rendered":"https:\/\/www.both.org\/?p=3869"},"modified":"2024-02-19T06:20:16","modified_gmt":"2024-02-19T11:20:16","slug":"systemd-8-analyzing-systemd-calendar-and-timespans","status":"publish","type":"post","link":"https:\/\/www.both.org\/?p=3869","title":{"rendered":"systemd &#8212; #8: Analyzing systemd calendar and timespans"},"content":{"rendered":"<div class=\"pld-like-dislike-wrap pld-template-1\">\r\n    <div class=\"pld-like-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-like-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"3869\" data-trigger-type=\"like\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-up\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-like-count-wrap pld-count-wrap\">    <\/span>\r\n<\/div><\/div>\n<p class=\"has-small-font-size\">Image from Pexels.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Learn how systemd uses calendar time, timestamps, and timespans to control when things happen.<\/h2>\n\n\n\n<p>In my previous articles in this series about systemd, and especially in the <a href=\"https:\/\/opensource.com\/article\/20\/6\/systemd-timers\">most recent<\/a> article, time and date have come up in multiple contexts. systemd uses calendar time, specifying one or more moments in time to trigger events (such as a backup program), as well as timestamped entries in the journal. It can also use timespans, which define the amount of time between two events but are not directly tied to specific calendar times.<\/p>\n\n\n\n<p>In this article, I will look&nbsp;in more detail at how time and date are used and specified in systemd. Also, because systemd uses two slightly different, non-compatible time formats, I will explain how and when they are used.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"definitions\">Definitions<\/h2>\n\n\n\n<p>Following are some important time- and calendar-related systemd terms to understand:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Absolute timestamp:<\/strong> A single unambiguous and unique point in time defined in the format <code>YYYY-MM-DD HH:MM:SS<\/code>. The timestamp format specifies points in time when events are triggered by timers. An absolute timestamp can represent only a single point in time, such as <code>2025-04-15 13:21:05<\/code>.<\/li>\n\n\n\n<li><strong>Accuracy<\/strong> is the quality of closeness to the true time; in other words, how close to the specified calendar time an event is triggered by a timer. The default accuracy for systemd timers is defined as a one-minute timespan that starts at the defined calendar time. For example, an event specified to occur at the <code>OnCalendar<\/code> time of 09:52:17 might be triggered at any time between then and 09:53:17.<\/li>\n\n\n\n<li><strong>Calendar events<\/strong> are one or more specific times specified by a systemd timestamp in the format <code>YYYY-MM-DD HH:MM:SS<\/code>. It can be a single point in time or a series of points that are well-defined and for which the exact times can be calculated. systemd journals use timestamps to mark each event with the exact time it occurred. In systemd, exact time is specified in the timestamp format <code>YYYY-MM-DD HH:MM:SS<\/code>. When only the <code>YYYY-MM-DD<\/code> portion is specified, the time defaults to 00:00:00. When only the <code>HH:MM:SS<\/code> portion is specified, the date is the next calendar instance of that time. If the time specified is before the current time, the next instance will be tomorrow, and if the specified time is later than the current time, the next instance will be today. This is the format systemd timers use to express <code>OnCalendar<\/code> times. Recurring calendar events can be specified using special characters and formats that represent fields with multiple value matches. For example, <code>2026-08-15..25 12:15:00<\/code> represents 12:15pm&nbsp;on the 15th through the 25th of August 2026 and would trigger 11 matches. Calendar events can also be specified with an absolute timestamp.<\/li>\n\n\n\n<li><strong>Timespan<\/strong> is the amount of time between two events or the duration of something like an event or the time between two events. Timespans can be used to specify the desired accuracy for an event to be triggered by a timer and to define the time to elapse between events. systemd recognizes the following time units:\n<ul class=\"wp-block-list\">\n<li>usec, us, \u00b5s<\/li>\n\n\n\n<li>msec, ms<\/li>\n\n\n\n<li>seconds, second, sec, s<\/li>\n\n\n\n<li>minutes, minute, min, m<\/li>\n\n\n\n<li>hours, hour, hr, h<\/li>\n\n\n\n<li>days, day, d<\/li>\n\n\n\n<li>weeks, week, w<\/li>\n\n\n\n<li>months, month, M (defined as 30.44 days)<\/li>\n\n\n\n<li>years, year, y (defined as 365.25 days)<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>The <code>systemd.time(7)<\/code> man page has a complete description of time and date expressions in timers and other systemd tools.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"calendar-event-expressions\">Calendar event expressions<\/h2>\n\n\n\n<p>Calendar event expressions are a key part of triggering timers at repetitive times. systemd and its timers don&#8217;t use the same style for time and date expressions as crontab uses. systemd is also more flexible than crontab and allows fuzzy dates and times similar to the <code>at<\/code> command.<\/p>\n\n\n\n<p>The format <code>OnCalendar=<\/code> uses for calendar event expressions is <code>DOW YYYY-MM-DD HH:MM:SS<\/code>. DOW (day of the week) is optional, and other fields can use an asterisk (<code>*<\/code>) to match any value for that position. If the time is not specified, it is assumed to be 00:00:00. If the date is not specified but the time is, the next match might be today or tomorrow, depending upon the current time. All the various calendar time-expression formats are converted to a normalized form, and the <code>systemd-analyze calendar<\/code> command shows the normalized form of the time expression.<\/p>\n\n\n\n<p>systemd provides an excellent tool for validating and examining calendar events used in an expression. The <code>systemd-analyze calendar<\/code> tool parses a calendar time event expression and provides the normalized form and other information, such as the date and time of the next &#8220;elapse&#8221; (i.e., match) and the approximate amount of time before it reaches the trigger time.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><em><strong>Note:<\/strong> All the following commands can be performed by non-root users and the times for &#8220;Next elapse&#8221; and &#8220;UTC&#8221; will differ based on your local time zone.<\/em><\/p>\n<\/blockquote>\n\n\n\n<p>First, look at the syntax of the <code>systemd-analyze calendar<\/code> command. Start with a date in the future without a time. Because all the date unit fields are explicitly specified, this is a one-time event:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;student@testvm1 ~]$ <strong>systemd-analyze calendar 2030-06-17<\/strong>\n  Original form: 2030-06-17                 \nNormalized form: 2030-06-17 00:00:00        \n    Next elapse: Mon 2030-06-17 00:00:00 EDT\n       (in UTC): Mon 2030-06-17 04:00:00 UTC\n       From now: 10 years 0 months left    <\/code><\/pre>\n\n\n\n<p>Add a time (in this example, the date and time are analyzed separately as non-related entities):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;root@testvm1 system]# <strong>systemd-analyze calendar 2030-06-17 15:21:16<\/strong>\n  Original form: 2030-06-17                 \nNormalized form: 2030-06-17 00:00:00        \n    Next elapse: Mon 2030-06-17 00:00:00 EDT\n       (in UTC): Mon 2030-06-17 04:00:00 UTC\n       From now: 10 years 0 months left     \n\n  Original form: 15:21:16                   \nNormalized form: *-*-* 15:21:16             \n    Next elapse: Mon 2020-06-15 15:21:16 EDT\n       (in UTC): Mon 2020-06-15 19:21:16 UTC\n       From now: 3h 55min left <\/code><\/pre>\n\n\n\n<p>To analyze the date and time as a single entity, enclose them together in quotes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;student@testvm1 system]# <strong>systemd-analyze calendar \"2030-06-17 15:21:16\"<\/strong>\nNormalized form: 2030-06-17 15:21:16        \n    Next elapse: Mon 2030-06-17 15:21:16 EDT\n       (in UTC): Mon 2030-06-17 19:21:16 UTC\n       From now: 10 years 0 months left  <\/code><\/pre>\n\n\n\n<p>Specify one time earlier than the current time and one later. In this example, the current time is 16:16 on 2019-05-15:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;student@testvm1 ~]$ systemd-analyze calendar 15:21:16 22:15\n  Original form: 15:21:16\nNormalized form: *-*-* 15:21:16\n    Next elapse: Fri 2019-05-17 15:21:16 EDT\n       (in UTC): Fri 2019-05-17 19:21:16 UTC\n       From now: 23h left\n\n  Original form: 22:15\nNormalized form: *-*-* 22:15:00\n    Next elapse: Thu 2019-05-16 22:15:00 EDT\n       (in UTC): Fri 2019-05-17 02:15:00 UTC\n       From now: 5h 59min left<\/code><\/pre>\n\n\n\n<p>The <code>systemd-analyze calendar<\/code> tool does not work on timestamps. So things like &#8220;tomorrow&#8221; or &#8220;today&#8221; will cause errors if you use them with the calendar sub-command because they are timestamps rather than <code>OnCalendar<\/code> time formats:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;student@testvm1 ~]$ <strong>systemd-analyze calendar \"tomorrow\"<\/strong>\nFailed to parse calendar expression 'tomorrow': Invalid argument\nHint: this expression is a valid timestamp. Use 'systemd-analyze timestamp \"tomorrow\"' instead?<\/code><\/pre>\n\n\n\n<p>The term &#8220;tomorrow&#8221; will always resolve to tomorrow&#8217;s date and a time of 00:00:00. You must use the normalized expression format, <code>YYYY-MM-DD HH:MM:SS<\/code>, for this tool to work in calendar mode. Despite this, the <code>systemd-analyze calendar<\/code> tool can still help you understand the structure of the calendar time expressions used by systemd timers. I recommend reading the <code>systemd.time(7)<\/code> man page for a better understanding of the time formats that can be used with systemd timers.<\/p>\n\n\n\n<p>Why would using a statement like <code>OnCalendar=tomorrow<\/code> fail when used in a timer?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"timestamps\">Timestamps<\/h2>\n\n\n\n<p>Whereas calendar times can be used to match single or multiple points in time, timestamps unambiguously represent a single point in time. For example, timestamps in the systemd journal refer to a precise moment when each logged event occurs:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;student@testvm1 ~]$ <strong>journalctl -S today<\/strong>\nHint: You are currently not seeing messages from other users and the system.\n      Users in groups 'adm', 'systemd-journal', 'wheel' can see all messages.\n      Pass -q to turn off this notice.\n-- Logs begin at Wed 2020-06-17 10:08:41 EDT, end at Wed 2020-06-17 10:13:55 EDT. --\nJun 17 10:08:41 testvm1.both.org systemd&#91;1137785]: Started Mark boot as successful after the user session has run 2 minutes.\nJun 17 10:08:41 testvm1.both.org systemd&#91;1137785]: Started Daily Cleanup of User's Temporary Directories.\nJun 17 10:08:41 testvm1.both.org systemd&#91;1137785]: Reached target Paths.\nJun 17 10:08:41 testvm1.both.org systemd&#91;1137785]: Reached target Timers.\n&lt;SNIP>\nJun 17 10:13:55 testvm1.both.org systemd&#91;1137785]: systemd-tmpfiles-clean.service: Succeeded.\nJun 17 10:13:55 testvm1.both.org systemd&#91;1137785]: Finished Cleanup of User's Temporary Files and Directories.<\/code><\/pre>\n\n\n\n<p>The <code>systemd-analyze timestamp<\/code> command can be used to analyze timestamp expressions the same way it analyzes calendar expressions. Here is an example from the journal data stream:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;student@testvm1 ~]$ <strong>systemd-analyze timestamp \"Jun 17 10:08:41\"<\/strong>\nFailed to parse \"Jun 17 10:08:41\": Invalid argument\n&#91;student@testvm1 ~]$ systemd-analyze timestamp Jun 17 10:08:41\nFailed to parse \"Jun\": Invalid argument\n\nFailed to parse \"17\": Invalid argument\nHint: this expression is a valid timespan. Use 'systemd-analyze timespan \"17\"' instead?\n\n  Original form: 10:08:41                   \nNormalized form: Wed 2020-06-17 10:08:41 EDT\n       (in UTC): Wed 2020-06-17 14:08:41 UTC\n   UNIX seconds: @1592402921                \n       From now: 11min ago<\/code><\/pre>\n\n\n\n<p>Why is the data copied from the journal not considered to be a valid timestamp? I have no idea. It seems pretty dumb to print the timestamps for the journal in a format that cannot be used by the tool designed to analyze timestamps. But look at the time specified as the beginning of the log:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;student@testvm1 ~]$ <strong>systemd-analyze timestamp \"Wed 2020-06-17 10:08:41\"<\/strong>\n  Original form: Wed 2020-06-17 10:08:41    \nNormalized form: Wed 2020-06-17 10:08:41 EDT\n       (in UTC): Wed 2020-06-17 14:08:41 UTC\n   UNIX seconds: @1592402921                \n       From now: 15min ago                  \n&#91;student@testvm1 ~]$<\/code><\/pre>\n\n\n\n<p>OK, so that time is a valid timestamp. The key is that the <code>systemd-analyze<\/code> tool only recognizes the <code>DOW YYYY-MM-DD HH:MM:SS<\/code> format. As the error messages state, it does not recognize month names or standalone days of the month, such as 17. It is very exacting because the only way to ensure events are triggered by timers at desired points in time or intervals is to be completely accurate with how they are specified.<\/p>\n\n\n\n<p>Any unambiguously expressed time, such as <code>2020-06-17 10:08:41<\/code>, is a timestamp because it can only occur once. A timestamp that will occur in the future can also be used in a systemd timer, and that timer will only trigger its defined action once.<\/p>\n\n\n\n<p>A time expressed somewhat more ambiguously, such as <code>2025-*-* 22:15:00<\/code>, can only be a calendar time used in the <code>OnCalendar<\/code> statement in a timer unit file. This expression will trigger an event every day in the year 2025 at 22:15:00 (10:15:00pm).<\/p>\n\n\n\n<p>But still\u2014why not use valid timestamps in the journal output? I <em>still<\/em> don&#8217;t know, but with a bit of command-line manipulation, you can convert the default time display into valid timestamps. The <code>journalctl<\/code> command tool has some options that can display the timestamps in a format you can easily use with the <code>systemd-analyze<\/code> tool:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;root@testvm1 ~]# <strong>journalctl -o short-full<\/strong>\n&lt;SNIP>\nFri 2020-06-26 12:51:36 EDT testvm1.both.org systemd&#91;1]: Finished Update UTMP about System Runlevel Changes.\nFri 2020-06-26 12:51:36 EDT testvm1.both.org systemd&#91;1]: Startup finished in 2.265s (kernel) + 4.883s (initrd) + 22.645s (userspace) = 29.793s.\nFri 2020-06-26 12:51:36 EDT testvm1.both.org audit&#91;1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=systemd-update-utmp-runlevel>\nFri 2020-06-26 12:51:36 EDT testvm1.both.org audit&#91;1]: SERVICE_STOP pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=systemd-update-utmp-runlevel >\nFri 2020-06-26 12:51:36 EDT testvm1.both.org crond&#91;959]: (CRON) INFO (running with inotify support)\nFri 2020-06-26 12:51:36 EDT testvm1.both.org ModemManager&#91;759]: &lt;info>  Couldn't check support for device '\/sys\/devices\/pci0000:00\/0000:00:03.0': not >\nFri 2020-06-26 12:51:37 EDT testvm1.both.org VBoxService&#91;804]: 16:51:37.196960 timesync vgsvcTimeSyncWorker: Radical guest time change: -14 388 436 32>\nFri 2020-06-26 12:51:39 EDT testvm1.both.org chronyd&#91;827]: Selected source 192.168.0.52\nFri 2020-06-26 12:51:39 EDT testvm1.both.org chronyd&#91;827]: System clock TAI offset set to 37 seconds\n&lt;SNIP><\/code><\/pre>\n\n\n\n<p>You can now use the timestamps like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;root@testvm1 ~]# <strong>systemd-analyze timestamp \"2020-06-26 12:51:36\"<\/strong>\n  Original form: 2020-06-26 12:51:36        \nNormalized form: Fri 2020-06-26 12:51:36 EDT\n       (in UTC): Fri 2020-06-26 16:51:36 UTC\n   UNIX seconds: @1593190296                \n       From now: 2h 37min ago               \n&#91;root@testvm1 ~]#<\/code><\/pre>\n\n\n\n<p>You can also display the journal timestamps in a monotonic format that shows the number of seconds since boot:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;root@testvm1 ~]# <strong>journalctl -o short-monotonic<\/strong>\n&#91;    0.000000] testvm1.both.org kernel: Linux version 5.6.6-300.fc32.x86_64 (mockbuild@bkernel03.phx2.fedoraproject.org) (gcc version 10.0.1 20200328 >\n&#91;    0.000000] testvm1.both.org kernel: Command line: BOOT_IMAGE=(hd0,msdos1)\/vmlinuz-5.6.6-300.fc32.x86_64 root=\/dev\/mapper\/VG01-root ro resume=\/dev\/>\n&#91;    0.000000] testvm1.both.org kernel: x86\/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers'\n&#91;    0.000000] testvm1.both.org kernel: x86\/fpu: Supporting XSAVE feature 0x002: 'SSE registers'\n&#91;    0.000000] testvm1.both.org kernel: x86\/fpu: Supporting XSAVE feature 0x004: 'AVX registers'\n&#91;    0.000000] testvm1.both.org kernel: x86\/fpu: xstate_offset&#91;2]:  576, xstate_sizes&#91;2]:  256\n&#91;    0.000000] testvm1.both.org kernel: x86\/fpu: Enabled xstate features 0x7, context size is 832 bytes, using 'standard' format.\n&#91;    0.000000] testvm1.both.org kernel: BIOS-provided physical RAM map:\n&#91;    0.000000] testvm1.both.org kernel: BIOS-e820: &#91;mem 0x0000000000000000-0x000000000009fbff] usable\n&#91;    0.000000] testvm1.both.org kernel: BIOS-e820: &#91;mem 0x000000000009fc00-0x000000000009ffff] reserved\n&#91;    0.000000] testvm1.both.org kernel: BIOS-e820: &#91;mem 0x00000000000f0000-0x00000000000fffff] reserved\n&#91;    0.000000] testvm1.both.org kernel: BIOS-e820: &#91;mem 0x0000000000100000-0x00000000dffeffff] usable\n&#91;    0.000000] testvm1.both.org kernel: BIOS-e820: &#91;mem 0x00000000dfff0000-0x00000000dfffffff] ACPI data\n&#91;    0.000000] testvm1.both.org kernel: BIOS-e820: &#91;mem 0x00000000fec00000-0x00000000fec00fff] reserved\n&#91;    0.000000] testvm1.both.org kernel: BIOS-e820: &#91;mem 0x00000000fee00000-0x00000000fee00fff] reserved\n&#91;    0.000000] testvm1.both.org kernel: BIOS-e820: &#91;mem 0x00000000fffc0000-0x00000000ffffffff] reserved\n&#91;    0.000000] testvm1.both.org kernel: BIOS-e820: &#91;mem 0x0000000100000000-0x00000003373fffff] usable\n&#91;    0.000000] testvm1.both.org kernel: NX (Execute Disable) protection: active\n&#91;    0.000000] testvm1.both.org kernel: SMBIOS 2.5 present.\n&#91;    0.000000] testvm1.both.org kernel: DMI: innotek GmbH VirtualBox\/VirtualBox, BIOS VirtualBox 12\/01\/2006\n&#91;    0.000000] testvm1.both.org kernel: Hypervisor detected: KVM\n&lt;SNIP>\n&#91;28829.016018] testvm1.both.org NetworkManager&#91;760]: &lt;info>  &#91;1593219095.3936] dhcp4 (enp0s3): option requested_time_offset => '1'\n&#91;28829.016062] testvm1.both.org NetworkManager&#91;760]: &lt;info>  &#91;1593219095.3936] dhcp4 (enp0s3): option requested_wpad       => '1'\n&#91;28829.016106] testvm1.both.org NetworkManager&#91;760]: &lt;info>  &#91;1593219095.3936] dhcp4 (enp0s3): option routers              => '192.168.0.254'\n&#91;28829.016155] testvm1.both.org NetworkManager&#91;760]: &lt;info>  &#91;1593219095.3936] dhcp4 (enp0s3): option subnet_mask          => '255.255.255.0'\n&#91;28829.016201] testvm1.both.org NetworkManager&#91;760]: &lt;info>  &#91;1593219095.3936] dhcp4 (enp0s3): state changed extended -> extended\n&#91;28829.019332] testvm1.both.org systemd&#91;1]: Starting Network Manager Script Dispatcher Service...\n&#91;28829.028205] testvm1.both.org audit&#91;1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=NetworkManager-dispatcher comm=\"systemd\" >\n&#91;28829.028406] testvm1.both.org systemd&#91;1]: Started Network Manager Script Dispatcher Service.\n&#91;28839.014035] testvm1.both.org systemd&#91;1]: NetworkManager-dispatcher.service: Succeeded.\n&#91;28839.014496] testvm1.both.org audit&#91;1]: SERVICE_STOP pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=NetworkManager-dispatcher comm=\"systemd\" e>\n&#91;29336.998580] testvm1.both.org systemd&#91;1]: Starting system activity accounting tool...\n&#91;29337.443114] testvm1.both.org audit&#91;1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=sysstat-collect comm=\"systemd\" exe=\"\/usr\/>\n&#91;29337.443347] testvm1.both.org audit&#91;1]: SERVICE_STOP pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=sysstat-collect comm=\"systemd\" exe=\"\/usr\/l>\n&#91;29337.443404] testvm1.both.org systemd&#91;1]: sysstat-collect.service: Succeeded.\n&#91;29337.443504] testvm1.both.org systemd&#91;1]: Finished system activity accounting tool.\n&#91;29394.784506] testvm1.both.org CROND&#91;2253]: (root) CMD (run-parts \/etc\/cron.hourly)\n&#91;29394.792113] testvm1.both.org run-parts&#91;2256]: (\/etc\/cron.hourly) starting 0anacron\n&#91;29394.799468] testvm1.both.org run-parts&#91;2262]: (\/etc\/cron.hourly) finished 0anacron<\/code><\/pre>\n\n\n\n<p>Read the <code>journalctl<\/code> man page for a complete list of the timestamp format options (among other things).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"time-spans\">Timespans<\/h2>\n\n\n\n<p>Timespans are primarily used in systemd timers to define a specific span of time between events. This could be used to trigger events so that they occur a specified amount of time after system startup or after a previous instance of the same event. For example, here is a sample expression in the timer unit file to trigger an event 32 minutes after system startup:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>OnStartupSec=32m<\/code><\/pre>\n\n\n\n<p>The default accuracy for triggering systemd timers is a time window starting at the specified time and lasting one minute. You can increase trigger timespan accuracy to within a microsecond by adding a statement like the following to the Timer section of the timer-unit file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>AccuracySec=1us<\/code><\/pre>\n\n\n\n<p>The <code>systemd-analyze timespan<\/code> command can help ensure you are using a valid timespan in the unit file. These samples will get you started:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;student@testvm1 ~]$ <strong>systemd-analyze timespan 15days<\/strong>\nOriginal: 15days       \n      \u03bcs: 1296000000000\n   Human: 2w 1d        \n&#91;student@testvm1 ~]$ <strong>systemd-analyze timespan \"15days 6h 32m\"<\/strong>\nOriginal: 15days 6h 32m \n      \u03bcs: 1319520000000 \n   Human: 2w 1d 6h 32min<\/code><\/pre>\n\n\n\n<p>Experiment with these and some of your own:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>\"255days 6h 31m\"<\/code><\/li>\n\n\n\n<li><code>\"255days 6h 31m 24.568ms\"<\/code><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"final-thoughts\">Final thoughts<\/h2>\n\n\n\n<p>Timespans are used to schedule timer events a specified interval after a defined event such as startup. Calendar timestamps can be used to schedule timer events on specific calendar days and times, either as one-offs or repeating. Timestamps are also used on systemd journal entries, although not in a default format that can be used directly in tools like <code>systemd-analyze<\/code>.<\/p>\n\n\n\n<p>All of this was more than just a little confusing to me when I started working with systemd timers and creating calendar and timestamp expressions to trigger events. That was partly because of the similar\u2014but not quite identical\u2014formats used for specifying timestamps and calendar event trigger times. I hope that this has helped to clarify this for you.<\/p>\n\n\n\n<p>In my next article, I will explore systemd journaling and related tools in more detail<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"resources\">Resources<\/h2>\n\n\n\n<p>There is a great deal of information about systemd available on the internet, but much is terse, obtuse, or even misleading. In addition to the resources mentioned in this article, the following webpages offer more detailed and reliable information about systemd startup.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The Fedora Project has a good, practical <a href=\"https:\/\/docs.fedoraproject.org\/en-US\/quick-docs\/understanding-and-administering-systemd\/index.html\" target=\"_blank\" rel=\"noreferrer noopener\">guide<\/a> <a href=\"https:\/\/docs.fedoraproject.org\/en-US\/quick-docs\/understanding-and-administering-systemd\/index.html\" target=\"_blank\" rel=\"noreferrer noopener\">to systemd<\/a>. It has pretty much everything you need to know in order to configure, manage, and maintain a Fedora computer using systemd.<\/li>\n\n\n\n<li>The Fedora Project also has a good <a href=\"https:\/\/fedoraproject.org\/wiki\/SysVinit_to_Systemd_Cheatsheet\" target=\"_blank\" rel=\"noreferrer noopener\">cheat sheet<\/a> that cross-references the old SystemV commands to comparable systemd ones.<\/li>\n\n\n\n<li>For detailed technical information about systemd and the reasons for creating it, check out <a href=\"http:\/\/Freedesktop.org\" target=\"_blank\" rel=\"noreferrer noopener\">Freedesktop.org<\/a>&#8216;s <a href=\"http:\/\/www.freedesktop.org\/wiki\/Software\/systemd\" target=\"_blank\" rel=\"noreferrer noopener\">description of systemd<\/a>.<\/li>\n\n\n\n<li><a href=\"http:\/\/Linux.com\" target=\"_blank\" rel=\"noreferrer noopener\">Linux.com<\/a>&#8216;s &#8220;More systemd fun&#8221; offers more advanced systemd <a href=\"https:\/\/www.linux.com\/training-tutorials\/more-systemd-fun-blame-game-and-stopping-services-prejudice\/\" target=\"_blank\" rel=\"noreferrer noopener\">information and tips<\/a>.<\/li>\n<\/ul>\n\n\n\n<p>There is also a series of deeply technical articles for Linux sysadmins by Lennart Poettering, the designer and primary developer of systemd. These articles were written between April 2010 and September 2011, but they are just as relevant now as they were then. Much of everything else good that has been written about systemd and its ecosystem is based on these papers.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"http:\/\/0pointer.de\/blog\/projects\/systemd.html\" target=\"_blank\" rel=\"noreferrer noopener\">Rethinking PID 1<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/0pointer.de\/blog\/projects\/systemd-for-admins-1.html\" target=\"_blank\" rel=\"noreferrer noopener\">systemd for Administrators, Part I<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/0pointer.de\/blog\/projects\/systemd-for-admins-2.html\" target=\"_blank\" rel=\"noreferrer noopener\">systemd for Administrators, Part II<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/0pointer.de\/blog\/projects\/systemd-for-admins-3.html\" target=\"_blank\" rel=\"noreferrer noopener\">systemd for Administrators, Part III<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/0pointer.de\/blog\/projects\/systemd-for-admins-4.html\" target=\"_blank\" rel=\"noreferrer noopener\">systemd for Administrators, Part IV<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/0pointer.de\/blog\/projects\/three-levels-of-off.html\" target=\"_blank\" rel=\"noreferrer noopener\">systemd for Administrators, Part V<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/0pointer.de\/blog\/projects\/changing-roots\" target=\"_blank\" rel=\"noreferrer noopener\">systemd for Administrators, Part VI<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/0pointer.de\/blog\/projects\/blame-game.html\" target=\"_blank\" rel=\"noreferrer noopener\">systemd for Administrators, Part VII<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/0pointer.de\/blog\/projects\/the-new-configuration-files.html\" target=\"_blank\" rel=\"noreferrer noopener\">systemd for Administrators, Part VIII<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/0pointer.de\/blog\/projects\/on-etc-sysinit.html\" target=\"_blank\" rel=\"noreferrer noopener\">systemd for Administrators, Part IX<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/0pointer.de\/blog\/projects\/instances.html\" target=\"_blank\" rel=\"noreferrer noopener\">systemd for Administrators, Part X<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/0pointer.de\/blog\/projects\/inetd.html\" target=\"_blank\" rel=\"noreferrer noopener\">systemd for Administrators, Part XI<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Learn how systemd uses calendar time, timestamps, and timespans to control when things happen.<\/p>\n","protected":false},"author":2,"featured_media":3872,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","footnotes":""},"categories":[5,160],"tags":[248,176,249,277],"class_list":["post-3869","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-linux","category-systemd","tag-calendar","tag-systemd","tag-timespans","tag-timestamps"],"modified_by":"David Both","_links":{"self":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/3869","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3869"}],"version-history":[{"count":7,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/3869\/revisions"}],"predecessor-version":[{"id":4071,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/3869\/revisions\/4071"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/media\/3872"}],"wp:attachment":[{"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3869"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3869"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3869"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}