My local time is in the correct timezone, but isn’t actually the real local time here

clocktimezone

I have a machine that dual boots Kali Linux and Windows.
The correct local time when I ran my tests was 11:19 IST (India Standard Time), which is of course 05:49 UTC.
As you can see from the edit history of this question, I originally posted this a few minutes later at 05:58 UTC.

The date command gets the timezone right, but the time quite wrong.

$ date
Wednesday 19 August 2020 04:49:10 PM IST

As noted in question commentary, that's 12-hour notation, which is 16:49:10 in 24-hour notation.
The local time reported by the date command is 5 and a half hours ahead of what it should be.

Time in the GUI clock on my desktop is 11:19, which is correct.

A minute or so ago I ran this:

$ timedatectl
               Local time: Wed 2020-08-19 16:47:50 IST
           Universal time: Wed 2020-08-19 11:17:50 UTC
                 RTC time: Wed 2020-08-19 11:17:51
                Time zone: Asia/Kolkata (IST, +0530)
System clock synchronized: no
              NTP service: inactive
          RTC in local TZ: no

As you can see, the timezone is right, but the local time is very wrong.
Interestingly, if the "Universal time" there were IST and not UTC, it would have been right.

I don't get why this is happening.
Why is it?
How do I fix it?

Best Answer

Just for completeness' sake, ensure that your default timezone is correct (which, since it already says Asia/Kolkata and IST in what you are seeing it likely is, this step being largely redundant):

# dpkg-reconfigure tzdata

Use sudo or su if you are not already running a superuser shell, of course.

And then synchronize your system clock with the correct UTC time using a dæmon that gets the time from some NTP servers (installing the ntp package for this if it isn't already installed):

# ntpd -qg

The -q option tells ntpd to just set the time once and exit. It does not become a dæmon. This one-shot mode is ntpd's equivalent for the standalone ntpdate command.

The -g option is important for the reasons explained at "What is the recommended way to synchronize time using NTP?". Your clock is a lot more than 1000 seconds different from the correct UTC value. It is five and a half hours different. Without the use of the -g option, ntpd will simply refuse to correct this situation.

(There are of course other ways to re-set your system clock to the correct UTC time. You could hand-enter it in the machine's firmware's SETUP utility, or even hand-enter it with the date command. There are even tools other than ntpd that you could use to keep synchronized to NTP servers from now on, such as chronyd from the chrony package for example.)

Why

What has happened is this. When you were running only Windows, your hardware real-time clock (RTC) was interpreted as the local (IST) time by Windows. You installed a Linux-based operating system (this applying to more than just Kali Linux), but didn't fix a conflict between Linux-based operating systems (indeed Unix-like operating systems in general) and Windows.

Windows thought, and still thinks no doubt, that your real-time clock is reporting a local (IST) time. Normally, Linux-based operating systems think that your real-time clock reports a universal (UTC) time. The actual clock hardware does not have a timezone register, note; so it is up to each operating system to decide what the date and time registers in the clock actually represent, what timezone the clock is understood to be running in.

This is a fundamental conflict. You need to fix it.

Linux-based operating systems often give the choice of interpreting the real-time clock registers the same way that Windows does, but this is a poor choice for a lot of reasons, which would be (and is, here and there on the WWW) an entire Q&A in its own right. The far better choice is to have Windows and your Linux-based operating system both agree to understand the RTC registers as reading a universal (UTC) date and time.

You do this by configuring Windows; there is a fairly widely known registry setting. You actually do not need to do anything on the Linux side except for synchronizing the RTC to the UTC date and time. As you can see from the output of timedatectl when you ran it, you already have Asia/Kolkata as your (default) timezone and already have "RTC in local TZ" (i.e. "understand the RTC registers as local, the same way that Windows does") set to "no".

If Windows happens to re-synchronize the RTC back to IST values before you get the chance to reconfigure and reboot it, you'll need to synchronize back to UTC values again.

So why is your GUI clock right? It is because, ironically, you haven't configured it with the correct IST timezone in its, or your desktop's, settings. It's showing you the UTC time, or possibly the Dublin/London/Lisbon/Bamako/Freetown/Yamoussoukro time, and because on your system the "UTC time" taken from your RTC by the operating system is in reality the local IST time values, as put there by Windows, your GUI clock showing the UTC time just happens to look right.

This is the same reason that the "Universal time" reported by timedatectl has the right date and time for local time. Anything reporting what your Linux-based operating system currently thinks to be UTC is actually reporting local IST date and time.

Summary

So you need to

  • correct the real-time clock to the true UTC date and time (with ntpd as aforegiven, hand-setting it in your machine's firmware's SETUP utility at power-on, or even within Windows), and
  • reconfigure Windows so that it agrees on how the real-time clock should be read by operating systems.

Further reading

Related Question