Sources: linuxquestions.org
Inspired by the above link here are the 2 commands that saved the day:
hwclock --hctosys --localtime
hwclock --systohc --localtime
Windows stores the Local Time in the hardware clock and that is what is displayed in the System Notification Area on the Taskbar, whereas Linux keeps the times in the hardware clock and system clock separate, and only reads the time from the hardware clock at startup. When you boot Linux it reads the time in the hardware clock and sets the system clock to that time and applies any timezone offset that you have defined in a configuration file. Thus the time in the hardware clock and system clock can be -- and usually is -- different.
If you dual boot Linux and Windows, the chances are that you've already come across the problem of the on-screen clocks in Linux and Windows having a difference of one or more hours; this usually happens twice a year when the clocks change in countries that adopt Daylight Saving Time (but can also occur in between, depending on how the two operating systems have been configured). You can experience various effects depending on how your Linux and Windows have been configured, such as the on-screen clock moving forwards (or backwards) by 1 hour in Linux on the allotted day, then when you boot Windows the clock moves forwards (or backwards) by a further 1 hour.
hwclock --hctosys --localtime: set the system time from the hardware clock and keep the hardware clock in local time
hwclock --systohc --localtime: set the hardware clock from the current system time and keep the hardware clock in local time
For Ubuntu 16.04 and newer, run the following command (thanks to Erwinson Pagtalunan for the update!):
timedatectl set-local-rtc 1
You can then check if Ubuntu uses local time, you can then use the following command:
timedatectl
Which should display the following "RTC in local TZ: yes". A warning will also be displayed. Here's the full command output:
$ timedatectl
Local time: Lu 2016-04-25 12:18:22 EEST
Universal time: Lu 2016-04-25 09:18:22 UTC
RTC time: Lu 2016-04-25 12:18:22
Time zone: Europe/Bucharest (EEST, +0300)
Network time on: yes
NTP synchronized: no
RTC in local TZ: yes
Warning: The system is configured to read the RTC time in the local time zone.
This mode can not be fully supported. It will create various problems
with time zone changes and daylight saving time adjustments. The RTC
time is never updated, it relies on external facilities to maintain it.
If at all possible, use RTC in UTC by calling
'timedatectl set-local-rtc 0'.
For Ubuntu versions older than 16.04: you must edit the /etc/default/rcS file and replace "UTC=yes" with "UTC=no" (both without the quotes). To do this automatically, simply copy/paste the following command in a terminal:
sudo sed -i 's/UTC=yes/UTC=no/' /etc/default/rcS
And then reboot.
Then, to disable the Windows Time service (which still writes local time to RTC regardless of the registry setting above, on shutdown), run Command Prompt as Administrator and paste this command:
sc config w32time start= disabled
And reboot.
A. From Ubuntu: reverting this change from Ubuntu is pretty easy.
Ubuntu 16.04 and newer: to revert the changes, simply run the following command:
timedatectl set-local-rtc 0
Ubuntu versions older than 16.04: all you have to do is replace "UTC=no" with "UTC=yes" in the /etc/default/rcS file. To do this automatically, copy/paste the command below in a terminal:
sudo sed -i 's/UTC=no/UTC=yes/' /etc/default/rcS
And then reboot your computer.
Firstly, open the .reg file downloaded when applying the fix for Windows (see download link above) with a text editor and change the "RealTimeIsUniversal" value from "dword:00000001" to "-" (without the quotes). Here's how the file should look like after making this change:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation]
"RealTimeIsUniversal"=-
Then save the file and double click it.
sc config w32time start= demand
And finally, reboot.