I’ve written enough about the challenges of Windows devices and the real-time clock that you’ve probably heard this one before: Windows stores the time in the real-time clock in the local time zone, which causes problems if you install a new OS on the device and it boots up in a different default time zone (usually Pacific). The OS will assume that the real-time clock is in that time zone. So let’s say you had an old OS that was installed and configured for Central European Time where the time was 12 pm (noon). If you install a new Windows 10 OS image, it will boot up and assume that the time is in Pacific time, so in effect the time jumps forward 9 hours. Eventually, the OS will do a time sync and the time will shift to 3 am, assuming that happens before the time zone is changed. Then the time zone can get set back to Central European time and it’s again 12 pm.
The problem is the chaos that can cause in the process. Anything with a timeout (e.g. ESP) can run into issues. Anything with a “not good before” (e.g. a cert) may not be valid yet. Anything with a specific scheduled time (e.g. an MDM sync) may be delayed (time hasn’t yet arrived) or skipped (time is already past). “Results can be unpredictable.”
When doing some reading on UEFI I noticed this quote:
UEFI provides device-independent time services. Time services include support for time zone and daylight saving fields, which allow the hardware real-time clock to be set to local time or UTC. On machines using a PC-AT real-time clock, by default the hardware clock still has to be set to local time for compatibility with BIOS-based Windows, unless using recent versions and an entry in the Windows registry is set to indicate the use of UTC.
That’s good news, for two reasons: (1) UEFI supports UTC in the real-time clock, and (2) Windows 10 does too, but it needs a registry entry to force that to happen. Of course the Wikipedia article doesn’t say what that registry key is, but a quick Internet search (finding a bunch of articles related to dual-booting other OSes, since those other OSes assume UTC) points to this value:[HKEY_LOCAL_MACHINESystemCurrentControlSetControlTimeZoneInformation]RealTimeIsUniversal=1
Alright, let’s say you make that change in the registry and then reboot. How do you verify that it did any good? The first way is to see if the time on the device changed – the registry change doesn’t immediately take effect, so you’ll see a shift in the time (unless your time zone matched UTC). You can force a sync to get it to change back easily enough.
The next way would be to boot into the UEFI firmware settings for your device. On a Surface device, reboot and hold down the volume up button, then go to the “Date and Time” option. That should confirm the device is now in UTC (assuming it was properly set for whatever time zone the OS was configured to use after the reboot after the registry key was set).
OK, so what about a virtual machine? In Hyper-V, the Hyper-V integration services will keep the time in sync between the host and the guest VM. Will that respect the UTC setting? From my limited testing (my home Hyper-V server is a pale comparison to what I used to have in the office), yes, it does appear that this works fine, which makes sense as the Hyper-V integration services frequently sync the time between host and guest and people would complain if that didn’t handle differences in time zones between host and guest. (It just proves that Hyper-V isn’t adjusting the real-time clock directly, but is instead doing it via the integration services.)
Another interesting twist: This is apparently something that Azure ran into as well, so when you upload a VHDX to be used as the base for new IaaS VMs, you need to follow the documentation to set the same thing:
Set Coordinated Universal Time (UTC) time for Windows. Also, set the startup type of the Windows time service w32time to Automatic:
Set-ItemProperty -Path HKLM:SYSTEMCurrentControlSetControlTimeZoneInformation -Name RealTimeIsUniversal -Value 1 -Type DWord -Force Set-Service -Name w32time -StartupType Automatic
And if you’re an AWS user, they’ve also documented it here.
If you are using a Mac (which always uses UTC in the real-time clock), it sounds like BootCamp will take care of this for you (well, as long as BootCamp continues to exist – seems like that would be challenging with an ARM-based Mac). Other virtualization software may or may not handle this, so test it out yourself.
Now we just need to get the industry to make a few changes:
- Windows should set the RealTimeIsUniversal registry value as a default; that should also be done for Windows PE.
- Manufacturers should ship their devices with the firmware time pre-set to the correct UTC time. (If they set the time from within Windows where the registry is set, that would just happen.)
Someone with some pull should make those requests…