Time can go off inside Ubuntu on Windows with WSL when you hibernate notebook.
Depending on the sleep/hibernation periods the time difference may increase.
Inspect system time.
$ date
Thu Aug 10 18:24:15 CEST 2023
Inspect RTC time.
$ sudo hwclock --show
2023-08-10 18:27:08.892736+02:00
Set system time from RTC.
$ sudo hwclock --hctosys
Verify time synchronization.
$ date
Thu Aug 10 18:29:07 CEST 2023
$ sudo hwclock --show
2023-08-10 18:29:09.906957+02:00
Create systemd service and timer to automatically synchronize time.
$ cat << EOF | sudo tee /etc/systemd/system/rtctosys.service [Unit] Description=Set the system time from the RTC Wants=rtctosys.timer [Service] Type=oneshot StandardError=null StandardOutput=null ExecStart=/usr/sbin/hwclock --hctosys [Install] WantedBy=multi-user.target EOF
$ cat << EOF | sudo tee /etc/systemd/system/rtctosys.timer [Unit] Description=Schedule time sync [Timer] Persistent=true OnCalendar=*-*-* *:*:00 Unit=rtctosys.service [Install] WantedBy=timers.target EOF
Reload systemd configuration.
$ sudo systemctl daemon-reload
Enable timer.
$ sudo systemctl enable --now rtctosys.timer
List timers.
$ systemctl list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES Thu 2023-08-10 18:37:00 CEST 42s left Thu 2023-08-10 18:36:00 CEST 17s ago rtctosys.timer rtctosys.service Thu 2023-08-10 19:33:15 CEST 56min left Tue 2023-08-08 08:03:03 CEST 2 days ago apt-daily.timer apt-daily-upgrade.service Thu 2023-08-10 22:56:28 CEST 4h 20min left Thu 2023-08-10 16:46:11 CEST 1h 50min ago ua-timer.timer ua-timer.service Fri 2023-08-11 00:00:00 CEST 5h 23min left n/a n/a dpkg-db-backup.timer dpkg-db-backup.service Fri 2023-08-11 00:00:00 CEST 5h 23min left Thu 2023-08-10 16:40:52 CEST 1h 55min ago logrotate.timer logrotate.service Fri 2023-08-11 04:20:27 CEST 9h left Thu 2023-08-10 18:31:03 CEST 5min ago man-db.timer man-db.service Fri 2023-08-11 06:44:34 CEST 12h left Thu 2023-08-10 16:46:11 CEST 1h 50min ago apt-daily-upgrade.timer apt-daily-upgrade.service Fri 2023-08-11 07:10:10 CEST 12h left Thu 2023-08-10 18:28:42 CEST 7min ago motd-news.timer motd-news.service Fri 2023-08-11 16:58:28 CEST 22h left Thu 2023-08-10 16:55:54 CEST 1h 40min ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service Sun 2023-08-13 03:10:26 CEST 2 days left Sun 2023-08-06 11:02:59 CEST 4 days ago e2scrub_all.timer e2scrub_all.service 10 timers listed. Pass --all to see loaded but inactive timers, too.
Time will sync every minute.
But, what if this in not sufficient?
Check if NTP service is active.
$ timedatectl
Local time: Fri 2023-08-11 17:57:21 CEST Universal time: Fri 2023-08-11 15:57:21 UTC RTC time: Fri 2023-08-11 15:57:22 Time zone: Europe/Warsaw (CEST, +0200) System clock synchronized: no NTP service: inactive RTC in local TZ: no
Inspect service status.
$ systemctl status systemd-timesyncd.service
○ systemd-timesyncd.service - Network Time Synchronization Loaded: loaded (/lib/systemd/system/systemd-timesyncd.service; enabled; vendor preset: enabled) Active: inactive (dead) Condition: start condition failed at Thu 2023-08-10 16:40:52 CEST; 20h ago Docs: man:systemd-timesyncd.service(8) Aug 10 16:40:52 Arges systemd[1]: Condition check resulted in Network Time Synchronization being skipped.
Inspect service definition to identify condition check.
$ cat /lib/systemd/system/systemd-timesyncd.service
# SPDX-License-Identifier: LGPL-2.1-or-later # # This file is part of systemd. # # systemd is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. [Unit] Description=Network Time Synchronization Documentation=man:systemd-timesyncd.service(8) ConditionCapability=CAP_SYS_TIME ConditionVirtualization=!container DefaultDependencies=no After=systemd-sysusers.service Before=time-set.target sysinit.target shutdown.target Conflicts=shutdown.target Wants=time-set.target [Service] AmbientCapabilities=CAP_SYS_TIME BusName=org.freedesktop.timesync1 CapabilityBoundingSet=CAP_SYS_TIME # Turn off DNSSEC validation for hostname look-ups, since those need the # correct time to work, but we likely won't acquire that without NTP. Let's # break this chicken-and-egg cycle here. Environment=SYSTEMD_NSS_RESOLVE_VALIDATE=0 ExecStart=!!/lib/systemd/systemd-timesyncd LockPersonality=yes MemoryDenyWriteExecute=yes NoNewPrivileges=yes PrivateDevices=yes PrivateTmp=yes ProtectProc=invisible ProtectControlGroups=yes ProtectHome=yes ProtectHostname=yes ProtectKernelLogs=yes ProtectKernelModules=yes ProtectKernelTunables=yes ProtectSystem=strict Restart=always RestartSec=0 RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 RestrictNamespaces=yes RestrictRealtime=yes RestrictSUIDSGID=yes RuntimeDirectory=systemd/timesync StateDirectory=systemd/timesync SystemCallArchitectures=native SystemCallErrorNumber=EPERM SystemCallFilter=@system-service @clock Type=notify User=systemd-timesync WatchdogSec=3min [Install] WantedBy=sysinit.target Alias=dbus-org.freedesktop.timesync1.service
Create override to overcome this condition.
$ sudo mkdir /etc/systemd/system/systemd-timesyncd.service.d
$ cat <<EOF | sudo tee /etc/systemd/system/systemd-timesyncd.service.d/clear-condition-virtualization.conf [Unit] ConditionVirtualization= EOF
Reload systemd configuration.
$ sudo systemctl daemon-reload
Enable NTP service.
$ sudo timedatectl set-ntp yes
Verify sync status.
$ timedatectl
Local time: Fri 2023-08-11 18:10:16 CEST Universal time: Fri 2023-08-11 16:10:16 UTC RTC time: Fri 2023-08-11 16:10:13 Time zone: Europe/Warsaw (CEST, +0200) System clock synchronized: yes NTP service: active RTC in local TZ: no
Remember to disable the timer created earlier.
$ sudo systemctl disable --now rtctosys.timer
Problem solved.