Correct use of TZ, date, and hwclock?

32,256

--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
Share:
32,256

Related videos on Youtube

trycatch
Author by

trycatch

Updated on September 18, 2022

Comments

  • trycatch
    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
    trycatch about 11 years
    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.
  • Tom
    Tom about 11 years
    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.
  • Gilles 'SO- stop being evil'
    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
    Otheus over 7 years
    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.
  • vinc17
    vinc17 almost 6 years
    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.
  • Gilles 'SO- stop being evil'
    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
    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, only UTC0 and GMT0 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.