WSL2 clock goes out of sync after resuming from sleep/hibernate.

A workaround was shared on GitHub sudo hwclock -s to resync clock in WSL, but you have to do this every time you resume from sleep/hibernate.
WSL2 clock goes out of sync after resuming from sleep/hibernate.

A workaround was shared on GitHub sudo hwclock -s to resync clock in WSL, but you have to do this every time you resume from sleep/hibernate.
In case anyone finds this via search and doesn't notice that there is actually a solution listed in the question, you can fix WSL clock drift via.
sudo hwclock -s
If you just need to do it occasionally, this is a fine solution. If you need to do it more frequently, consider @piouson's solution
sudo hwclock -s gets you kind of there, but for some reason doesn't get the exact time - I often find it's a minute or so in the future!
sudo ntpdate pool.ntp.org should get you the correct time.
But this is all because of a bug in the Linux kernel which should be included in a Windows update at some point...
There are a number of hacks referenced in the the GitHub issue which can work around this, mostly, but not always, in my experience...
UPDATE: The fix is now in! In the Windows Insiders build, at least: https://devblogs.microsoft.com/commandline/servicing-the-windows-subsystem-for-linux-wsl-2-linux-kernel/
UPDATE: as mentioned by drkvogel, the Clock Sync fix was released in WSL2 kernel version 5.10.16.3
OBSOLETE
At time of writing, this GitHub Issue was open for the bug.
The workaround I chose for my situation (single distro in WSL2) is to use Windows Task Scheduler to run hwclock in WSL whenever Windows resyncs hardware clock.
Windows: Open PowerShell as Administrator
schtasks /create /tn WSLClockSync /tr "wsl.exe sudo hwclock -s" /sc onevent /ec system /mo "*[System[Provider[@Name='Microsoft-Windows-Kernel-General'] and (EventID=1)]]"
Set-ScheduledTask WSLClockSync -Settings (New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries)
WSL2: Run
sudo visudoand addhwclockto sudoers to skip password prompt
# bottom of my file looks like this
...
...
#includedir /etc/sudoers.d
<username> ALL=(ALL) NOPASSWD:/usr/sbin/hwclock, /usr/bin/apt update, /usr/bin/apt upgrade
Results
See image for how to get Event XPath from Windows Event filtering. Use as provided to let task scheduler auto-display scheduled triggers.
Necro'ing this: As of May 2022, this issue persists to a degree.
There are two components.
First, Windows time sync needs to be decent to start with. It's not, out of the box, on machines that aren't domain-joined.
Change w32time to start automatically. In Administrator cmd, but not PowerShell, sc triggerinfo w32time start/networkon stop/networkoff. Verify with sc qtriggerinfo w32time. To get into cmd that way, you can start Admin PowerShell and then just type cmd.
Make a few changes in regedit.
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w32time\Config, set MaxPollInterval to hex c, decimal 12.Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w32time\Parameters\NtpServer. If it ends in 0x9 you are done. If it ends in 0x1 you need to adjust SpecialPollInterval in Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w32time\TimeProviders\NtpClient to read 3600Reboot, then from Powershell run w32tm /query /status /verbose to verify that w32time service did start. If it didn't, check triggers again. If all else fails, set it to Automatic Delayed startup
Second, WSL2 needs to actually stay in sync. MS will likely release another kernel fix. In the meantime a scheduled task can bring it back into sync periodically:
schtasks /Create /TN WSL2TimeSync /TR "wsl -u root hwclock -s" /SC ONEVENT /EC System /MO "*[System[Provider[@Name='Microsoft-Windows-Kernel-Power'] and (EventID=107 or EventID=507) or Provider[@Name='Microsoft-Windows-Kernel-General'] and (EventID=1)]]" /F
You can manually update the WSL2 kernel to 5.10.16 by following the method in this comment: #5650 (comment). I have fixed the issue by this method.
sudo hwclock -sAs others said before sudo hwclock -s syncs the clock,
but you will need to do this after every sleep/hibernate.
Solution is to add an hourly cron task to sync the clock.
Open crontab with sudo (must open with sudo since the command uses sudo):
sudo crontab -e
and add this code with a new line after the task (it's a cron requirement):
PATH=/sbin:/bin:/usr/bin
@hourly hwclock -s
You must either set PATH since root-cron do not has it or use absolute paths e.g. /usr/sbin/hwclock.
* * * * * date > /tmp/log.txtpgrep cron.sudo service cron start.I've added this to Windows Task Scheduler, set to run every 12 hours:
wsl.exe -d ubuntu -u root -- ntpdate time.windows.com
To install ntpdate:
sudo apt install ntpdate
This GitHub Issue was closed
You can also run the below command in Powershell Terminal so sync it.
wsl.exe sudo hwclock -s