Date and time

The "system clock" is the clock that the kernel starts at boot. It is corrected by the ntpd service and is displayed in the zone that /etc/localtime points to. A wrong clock causes https certificate checks to fail, so that package downloads fail, and it gives frames and log lines the wrong time.

The clock at boot

/etc/rc does not run hwclock. The kernel configuration has CONFIG_RTC_DRV_CMOS=y and CONFIG_RTC_SYSTOHC=y with rtc0, and CONFIG_RTC_HCTOSYS is not set. In QEMU the time is correct at the first login, because it is taken from the virtual hardware clock. The kernel reads the hardware clock as UTC, so on a machine whose firmware clock is kept in local time the system clock is wrong by the offset of the zone until ntpd corrects it. hwclock from util-linux is installed. In a QEMU guest it printed a message.

Time zone

A new system has no /etc/localtime and shows UTC:

$ date
Mon Nov  2 16:53:14 UTC 2026
$ ls -l /etc/localtime
ls: cannot access '/etc/localtime': No such file or directory

The zone is a symbolic link into the zoneinfo package, whose share/zoneinfo links to the tzdata 2026e files in the store. The directory is /rod/profile/share/zoneinfo, and not /usr/share/zoneinfo.

# ls /rod/profile/share/zoneinfo
Africa  America  Antarctica  Arctic  Asia  Atlantic  Australia  Brazil  CET  ...
# ln -sf /rod/profile/share/zoneinfo/Europe/Helsinki /etc/localtime
$ date
Mon Nov  2 18:53:25 EET 2026

setup --timezone Europe/Helsinki has the same effect It checks that the name is a file under the zoneinfo directory and that it has no .. component. The name of a directory, such as Europe, is refused in the same way.

A link to a name that does not exist makes date fall back to UTC without a message:

# ln -sf /rod/profile/share/zoneinfo/Nope /etc/localtime
$ date
Fri Jan  2 03:04:05 UTC 2026

If the zoneinfo package is removed with rod +r zoneinfo, the link dangles in the same way.

The TZ variable

The C library does not look for zone names in the profile. TZ=Asia/Tokyo date printed the UTC time with the abbreviation Asia. When the directory is given, the command works:

$ TZDIR=/rod/profile/share/zoneinfo TZ=Asia/Tokyo date
Tue Nov  3 02:02:47 JST 2026
$ TZ=JST-9 date
Tue Nov  3 02:02:47 JST 2026

If you use named TZ values, you should export TZDIR in ~/.profile.

Set the time by hand

# date -s '2026-01-02 03:04:05'
Fri Jan  2 03:04:05 UTC 2026

This sets the system clock only. hwclock --systohc writes the system clock to the hardware clock.

ntpd

The ntpd service runs busybox ntpd 1.37.0:

exec ntpd -n -p pool.ntp.org -p time.cloudflare.com 2>&1

To use other servers, edit /etc/sv/ntpd/run and run sv restart ntpd. The log is /var/log/ntpd/current. ntpd starts at the same time as dhcp, so the server names often cannot be resolved at first. The log shows the start and a later query:

# cat /var/log/ntpd/current
2026-11-02_16:57:26.55396 ntpd: bad address 'pool.ntp.org'
2026-11-02_16:57:26.55400 ntpd: bad address 'time.cloudflare.com'
2026-11-02_16:58:57.92487 ntpd: timed out waiting for 93.94.88.51, reach 0x3e, next query in 32s

The process keeps running after the first messages and resolves a name about 90 seconds later. The firewall accepts the replies, because they belong to an outgoing connection. ntpd does not use /etc/localtime.

The timestamps that svlogd -tt writes to a log are always UTC, including on a system that is set to Europe/Helsinki.

Without a network, the time must be set with date -s. sv status ntpd shows the service, and geiger checks only that it is running.