AUTHOR: Archaic DATE: 2003-09-28 LICENSE: GNU Free Documentation License http://www.gnu.org/licenses/fdl.txt SYNOPSIS: Explanation of timezones, UTC, and the TZ environment variable DESCRIPTION: Your Linux system is multinational. It can not only talk in different languages, but it's aware of timezones, too. This hint tells you how you can set it up. PREREQUISITES: The script provided is based on lfs-bootscripts-1.11, but should be easy to modify even if major changes happen to the boot scripts. HINT: Earth is divided in 24 time zones. The local time in a zone depends on how many zones it is away from Greenwich, Great Britain. The difference in time is relative to the 0 zone over Greenwich. For example, in Indiana, USA (where I live) we're in the -5 zone. That means, it's five hours earlier here than in Great Britain. This compensates for the world turning. ### Local vs. UTC ### The first and most important question you'll have to answer is whether you want to store the time in your machine in either UTC or local time format. UTC (Universal Time Coordinated) is the same as GMT (Greenwich Mean Time). Local time is the time that is displayed on a clock hanging on a wall near you. Each format has its own advantages and disadvantages, but both of them are discussed in this hint. Traditionally, all POSIX machines (i.e. Solaris, BSD, UNIX) have their system time in UTC format. The more stupid OS's (mainly the Microsoft ones) require their users to configure their machines for local time. Fortunately, Linux can handle both the normal UTC machines and the machines suffering from Microsoft diseases that have their system time in local format. At this point, you'll have to decide what it's gonna be; local or UTC time. Some guidelines: If you're running Windows and Linux together on 1 box, I recommend you use local time. If you have Windows but you hardly use it or if you don't have Windows at all, it's a good idea to store your time in UTC format. Once you've decided, edit /etc/sysconfig/clock. Use UTC=0 for local time and UTC=1 for UTC (GMT) time. ### Determining Your Timezone ### Knowing what timezone you're living in is important for the rest of this hint. But it's not enough to know how many zones you're away from Greenwich, since daylight saving is also influenced by this choice. LFS comes with an easy program to determine your timezone in only a few questions (usually 2 or 3). Run it now: # tzselect When this program quits, the last line it prints is your timezone. Here, it prints "America/Indianapolis" (without the quotes). Remember this value. Write it down or put it somewhere in a text file. This variable will be referenced to as $TIMEZONE in the rest of this hint to simplify explanations. ### Using the $TIMEZONE Setting ### Now that you know what timezone you're living in, we can put this knowledge into practice. First, we start by creating the /etc/localtime file. This file needs to exist whether you choose UTC or local time. This can be a symlink or a copy of the real file renamed to localtime. At the time of this writing, LFS was using a real file, so I will use that method, though a symlink will work fine. # cp --remove-destination /usr/share/zoneinfo/$TIMEZONE /etc/localtime Next, we need to modify the setclock boot script, but first a brief explanation of system time and hardware time. The hardware clock is the clock that ticks in your BIOS and keeps the time even if the system is powered off. However, the hardware clock is not all that precise. The system clock is the time that the kernel maintains while it's running and it is considerably more precise. But how does the system clock know what time it is? During boot up, the standard LFS boot scripts set the system clock from the hardware clock. After that, the hardware clock is ignored. The problem with this scenario is that after many days of uptime (depending on the accuracy of your BIOS), there could be a rather large discrepancy between the system clock and the hardware clock. When you reboot, the still inaccurate hardware clock will be used to set the system clock. Therefore, it would behoove us to allow the kernel to update the BIOS time at shutdown so that the BIOS will be more likely to have an accurate time when the system boots up the next time. Reading from and writing to the hardware clock is done by a program named hwclock(8). This program is part of a normal LFS system, so you don't need to download it. We'll modify some of the boot scripts to make this program run at power up and power down. NOTE: Keith Harwood informed me that his DS10 Alpha box's hardware clock is more accurate than its system clock. The system clock was losing a couple of minutes a day. This is most likely a kernel flaw of some sort, but you should probably check your system's time against a known good time and compare it after the system has been running at least a day. I doubt any x86 users will find the hardware clock more accurate than the system clock. In the book, a script named setclock is created in /etc/rc.d/init.d. This script performs only half of the job, because it only sets the system time from the hardware clock. We will modify this script and create some additional symlinks to make this script save the system time to the hardware clock at shutdown/reboot. cat >/etc/rc.d/init.d/setclock <<"EOF" #!/bin/bash # Begin $rc_base/init.d/setclock - Setting Linux Clock # Based on setclock script from LFS-3.1 and earlier. # Rewritten by Gerard Beekmans - gerard@linuxfromscratch.org # Rewritten by Marc Heerdink to include writing to the hardware clock # Rewritten by Archaic to conform to # lfs-bootscripts-1.11 source /etc/sysconfig/rc source $rc_functions source /etc/sysconfig/clock case "$1" in start) case "$UTC" in yes|true|1) echo "Setting system clock..." hwclock --hctosys --utc evaluate_retval ;; no|false|0) echo "Setting system clock..." hwclock --hctosys --localtime evaluate_retval ;; *) echo "Invalid value for UTC in /etc/sysconfig/clock: $UTC" echo "Valid values for UTC are 1 and 0." exit 1 ;; esac ;; stop) case "$UTC" in yes|true|1) echo "Updating hardware clock..." hwclock --systohc --utc evaluate_retval ;; no|false|0) echo "Updating hardware clock..." hwclock --systohc --localtime evaluate_retval ;; *) echo "Invalid value for UTC in /etc/sysconfig/clock: $UTC" echo "Valid values for UTC are 1 and 0." exit 1 ;; esac ;; *) echo "Usage: $0 {start|stop}" exit 1 ;; esac # End $rc_base/init.d/setclock EOF chmod 755 /etc/rc.d/init.d/setclock Next are the symlinks. The symlink to run the setclock script is already present in /etc/rc.d/rc.sysinit.d, so the only symlinks we have to create are the ones to run setclock when the system shuts down: # ln -s ../init.d/setclock /etc/rc.d/rc0.d/K45setclock && # ln -s ../init.d/setclock /etc/rc.d/rc6.d/K45setclock At this point, the boot scripts are correctly set up and the only thing that's left to configure is the TZ environment variable. ### TZ Environment Variable ### This variable is used by hwclock, when it's run from a shell, and some programs that heavily depend on timezones. This variable is used system-wide, so it's a good idea to have it in the system-wide environment that is set up in /etc/profile. Add these lines to your /etc/profile: export TZ=value_of_$TIMEZONE ACKNOWLEDGEMENTS: This hint was originally written by Marc Heerdink. It's still 80% his text. CHANGELOG: [2002-04-10] * Marc Heerdink's final version [2003-09-28] * Edited out irrelevant or redundant info * Fixed some typos and grammatical errors * Updated the script and file locations to match current LFS * Update to new hint format