Correct use of TZ, date, and hwclock?
--utc
tells hwclock
that the hardware clock keeps UTC, and --localtime
says that the hardware clock keeps the same timezone as the system clock. (More precisely, it says that the hardware clock keeps the same offset to UTC as the system clock currently does — hardware clocks often don't know whether DST is active.) These options have no relation with the timezone of the system clock.
In theory, this tells you everything you need to know. In practice, this can be confusing.
# date -u; hwclock -u;
Tue Apr 9 20:08:44 UTC 2013
Tue Apr 9 15:08:45 2013 -0.397120 seconds
“First, tell me the system time in UTC. Then, assuming the hardware clock keeps UTC, what is the time in the local timezone?”
# date; hwclock --localtime
Tue Apr 9 15:09:07 CDT 2013
Tue Apr 9 20:09:08 2013 -0.686601 seconds
“First, tell me the system time in the local timezone. Then, assuming the hardware clock keeps local time, what is the time in the local timezone?”
On most systems, you can set the TZ
environment variable to set the timezone for a process. It's a POSIX feature. BusyBox supports this (I don't see an option to turn it off at compile time), and I believe so does uClibc. When working on clock synchronization, it can help to operate all in UTC for a short while:
export TZ=UTC0
date
hwclock
Related videos on Youtube
trycatch
Updated on September 18, 2022Comments
-
trycatch almost 2 years
I'm working on an Buildroot developed ARM/ulibc Linux distribution for a custom board. I'm trying to understand the relationship between
If I do this, as I've seen on a few examples online:
# date --set "2013-04-09 15:06:30" Tue Apr 9 15:06:30 CDT 2013 # hwclock --systohc --utc # hwclock Tue Apr 9 15:06:39 2013 -0.351552 seconds
and reboot, I get:
.... boot messages ... ... setting system clock to 2013-04-09 20:07:31 UTC (1365538051) .... boot messages ... # # date; hwclock; Tue Apr 9 15:08:24 CDT 2013 Tue Apr 9 15:08:25 2013 -0.473164 seconds # # date -u; hwclock -u; Tue Apr 9 20:08:44 UTC 2013 Tue Apr 9 15:08:45 2013 -0.397120 seconds # # date; hwclock --localtime Tue Apr 9 15:09:07 CDT 2013 Tue Apr 9 20:09:08 2013 -0.686601 seconds #
So, it seems that the hwclock thinks that localtime is UTC? And for some reason, when applying
-u
it actually applies the timezone instead? I'm a bit confused. Can anyone suggest how I should be going about this?EDIT: I should note that being an ARM + Busybox + uclibc, slimmed down system, I don't have a lot of the typical directories and files, like sysconfig and zoneinfo.
-
trycatch about 11 yearsBeing an ARM / Busybox / very slimmed down Linux, I don't have access to /usr/share/zoneinfo or some of the other usual directories / setting files. I can try manually creating them, but I don't know how it will go.
-
Tom about 11 yearsIf you only use the date command as above, then BusyBox Command Help document says you do not need to convert to local time if you stick to UTC time which is now +4 hours ahead of Eastern Time using ( date -u MMDDhhmm ) command.
-
Gilles 'SO- stop being evil' over 7 years@Otheus AFAIR, the hardware clock on a PC does not contain any timezone information. (It was designed before laptops were a thing. Moving a computer across timezones is far too rare to be handled in firmware.) The
hwclock
utility needs to be told what offset to apply when accessing the hardware clock. -
Otheus over 7 yearsThanks Gilles. FYI, KVM/Qemu appears to implement some kind of "Smart hwclock" feature that determines if the guest OS is storing UTC or localtime. The behavior is that hwclock should mirror hypervisor's systime (in UTC), and if the guest writes a value (
hwclock -w
) that is an hour off (the only test I conducted), it guesses the TZ based on the offset. That way in the future, even after a VM power off, it can correctly guess the time the guest expects. -
vinc17 almost 6 years
UTC
is an invalid value for theTZ
environment variable (it may work on some machines, but not everywhere, such as on some Debian 9 machines). The POSIX standard specifies to useUTC0
or the historical valueGMT0
. -
Gilles 'SO- stop being evil' almost 6 years@vinc17 POSIX does indeed mandate a numerical offset, but I don't know of any system that requires it after a timezone name — it defeats the point of named timezones. In addition most systems treat an unknown timezone name as UTC. So I'm curious, how does one cause
TZ=UTC
not to work? -
vinc17 almost 6 years@Gilles After some search, it seems that here, this is due to the fact that the
/usr/share/zoneinfo/UTC
file got corrupt, probably via a write to/etc/localtime
, which is a symlink, and this is IMHO a bug. Now, onlyUTC0
andGMT0
are guaranteed to work, as in case of unknown timezone, platforms may have extensions in practice, with behavior unspecified by POSIX. TZ=GMT doesn't work either on Tru64 Unix, and TZ=UTC has probably the same issue.