Windows wants the time in your local timezone, while Linux defaults to Universal Time Code (you just see your local time in linux because it gets calculated using timezone information). When Windows shuts down, it saves the local time in your BIOS memory. When Linux starts, it interprets this value as Universal Time - which is wrong. When Linux shuts down, it saves Universal Time to BIOS, which is then interpreted wrong by Windows.
You have to consider both systems to use UTC, or both to use Local time: The option mentioned by syg00 in Ubuntu's control center should do.
Or make Windows use UTC: Start registry editor, Navigate to
Code:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation
and edit (or create) a DWORD value:
Code:
RealTimeIsUniversal
with value 1.
I use the latter method, however from time to time something mysteriously makes windows interpret the time as local again (without changing the registry key or writing the wrong time to BIOS on shutdown). I have configured NTP time updates in Windows' Control Center to counter this.