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.


--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
  • Does the hardware clock actually contain some kind of timezone or offset information? Or do the -u/--localtime options merely tell hwclock how to interpret the values it reads from it? – Otheus Jan 23 '17 at 16:00
  • @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. – Gilles Jan 23 '17 at 17:56
  • Thanks 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. – Otheus Jan 23 '17 at 21:25
  • UTC is an invalid value for the TZ environment variable (it may work on some machines, but not everywhere, such as on some Debian 9 machines). The POSIX standard specifies to use UTC0 or the historical value GMT0. – vinc17 Aug 11 '18 at 1:23
  • @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? – Gilles Aug 11 '18 at 8:17

I setup my time information with the following commands:

# setup local timezone
rm /etc/localtime
# setup for EDT and EST (+4 EDT; +5 EST)
ln -s /usr/share/zoneinfo/EST5EDT /etc/localtime
# setup for only EST (+5 EST)
#ln -s /usr/share/zoneinfo/EST /etc/localtime
# setup for only Daylight Saving Time
#ln -s /usr/share/zoneinfo/EDT /etc/localtime

rm /etc/timezone
echo "US/Eastern" > /etc/timezone
export TZ="/usr/share/zoneinfo/America/New_York"

Note: set system clock after this script runs with date -u MMDDhhmm command using atomic watch as computer time drifts after power down

  • Being 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. – trycatch Apr 9 '13 at 21:35
  • If 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. – Tom Apr 9 '13 at 22:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.