You can set a timezone for the duration of the query, thusly:
TZ=America/New_York date
Note the whitespace between the TZ
setting and the date
command. In Bourne-like and rc
-like shell, that sets the TZ
variable only for the command line. In other shells (csh
, tcsh
, fish
), you can always use the env
command instead:
env TZ=America/New_York date
tl;dr
On Linux systems. timezones are defined in files in the /usr/share/zoneinfo
directory. This structure is often referred to as the "Olson database" to honor its founding contributor.
The rules for each timezone are defined as text file lines which are then compiled into a binary file. The lines so compiled, define the zone name; a range of data and time during which the zone applies; an offset from UTC for the standard time; and the notation for defining how transition to-and-from daylight saving time occurs, if applicable.
For example, the directory "America" contains the requisite information for New York in the file America/New_York
as used, above.
Beware that the specification of a non-existent zone (file name) is silently ignored and UTC times are reported. For example, this reports an incorrect time:
TZ="America/New York" date ### WRONG ###
The Single UNIX Specification, version-3, known as SUSv3 or POSIX-2001, notes that for portability, the character string that identifies the timezone description should begin with a colon character. Thus, we can also write:
TZ=":America/New_York" date
TZ=":America/Los_Angeles" date
As an alternative method to the specification of timezones using a pathname to a description file, SUSv3 describes the POSIX model. In this format, a string is defined as:
std offset [dst[offset][,start-date[/time],end-date[/time]]]
where std
is the standard component name and dst
is the daylight saving one. Each name consists of three or more characters. The offset
is positive for timezones west of the prime meridian and negative for those east of the meridian. The offset is added to the local time to obtain UTC (formerly known as GMT). The start
and end
time fields indicate when the standard/daylight transitions occur.
For example, in the Eastern United States, standard time is 5-hours earlier than UTC, and we can specify EST5EDT
in lieu of America/New_York
. These alternatives are not always recognized, however, especially for zones outside of the United States and are best avoided.
HP-UX (an SUSv3 compliant UNIX) uses textual rules in /usr/lib/tztab
and the POSIX names like EST5EDT, CST6CDT, MST7MDT, PST8PDT. The file includes all of the historical rules for each time zone, akin to the Olson database.
NOTE: You should be able to find all of the timezones by inspecting the following directory: /usr/share/zoneinfo
.
The date
command, like almost all programs, relies on the standard library to access timezone data. On Linux (except for some embedded systems) and *BSD, the standard library determines the current timezone from the content of /etc/localtime
.
It appears that on your system, /etc/localtime
does not contain what it seems to contain. Like Stéphane Chazelas and derobert, I strongly suspect that the file /usr/share/zoneinfo/Etc/UTC
, which /etc/localtime
is a symbolic link to, contains incorrect information, probably because someone who didn't know what they were doing attempted to change the system timezone and ended up overwriting a system file.
I recommend reinstalling the time zone information to make sure that your system isn't corrupted. Run rpm -qf /usr/share/zoneinfo/Etc/UTC
to see which package contains that file and reinstall it with yum reinstall
. Then set the timezone properly, either with the timedatectl
command or by changing the /etc/localtime
symbolic link and the text file /etc/zoneinfo
or /etc/sysconfig/clock
(I think Fedora uses the latter):
ln -snf /usr/share/zoneinfo/Europe/Madrid /etc/localtime
echo Europe/Madrid >/etc/zoneinfo
sed -i -e '/^ *ZONE=/d' /etc/sysconfig/clock
echo 'ZONE="Europe/Madrid"' >>/etc/sysconfig/clock
Java does things differently — it bypasses the standard library and reads /etc/timezone
or /etc/sysconfig/clock
instead. That's why you're seeing different timezone information from Java programs.
Best Answer
Just for completeness' sake, ensure that your default timezone is correct (which, since it already says
Asia/Kolkata
andIST
in what you are seeing it likely is, this step being largely redundant):Use
sudo
orsu
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):
The
-q
option tellsntpd
to just set the time once and exit. It does not become a dæmon. This one-shot mode isntpd
's equivalent for the standalonentpdate
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 thanntpd
that you could use to keep synchronized to NTP servers from now on, such aschronyd
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 haveAsia/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
ntpd
as aforegiven, hand-setting it in your machine's firmware's SETUP utility at power-on, or even within Windows), andFurther reading