hwclock − query and set the hardware clock (RTC)
hwclock --set --date=newdate [--correct=correction] [--reporterror]
hwclock --systohc [--correct=correction] [--reporterror]
hwclock --hctosys [--slew]
hwclock --setepoch --epoch=year
hwclock --adjust [--correct=correction] [--reporterror]
--utc --localtime --tzoffset=int --drift --nodrift --fast --nointerrupt --cpupriority=int --nomlock --badyear --rtc=fileName --adjfile=fileName --directisa --epoch --test --debug
and arcane options for DEC Alpha:
--arc --jensen --srm --funky-toy
Minimum unique abbreviations of all options are acceptable.
Also, equivalent options -r, -w, -s, -a, -v, -u, -D, -A, -J, -S, and -F are accepted for compatibility with the program "clock".
hwclock is a tool for accessing the Hardware Clock. You can display the current time, set the Hardware Clock to a specified time, set the Hardware Clock to the System Time, and set the System Time from the Hardware Clock.
You can also run hwclock periodically to insert or remove time from the Hardware Clock to compensate for systematic drift (where the clock consistently gains or loses time at a certain rate if left to run).
You need exactly one of the following options to tell hwclock what function to perform:
Read the Hardware Clock and print the datetime on Standard Output. The datetime is always in local time, even if you keep your Hardware Clock in Coordinated Universal Time. See the --utc option.
The datetime is
Sun May 14 23:21:03 2000 -0.606913 seconds PDT
The datetime on the left is the value of the hardware clock at some point during hwclock’s execution. Note that the hardware clock value is always in whole seconds. The offset to the right of that is what you have to combine with that value to get the exact time that you invoked hwclock. The 3 letters at the end are the locale (timezone) in which the datetime is expressed.
If you see a file specification where the locale name belongs, that means your C library cannot figure out your locale. It expected to find locale information in the specified file, but didn’t (that file probably doesn’t exist). Your C library got that file specification either from the TZ environment variable or by a configuration option used when your C library was built. See the man page for tzset() for details on how to tell your C library what your locale is.
The datetime hwclock shows is the actual value in the Hardware Clock registers, with no consideration of systematic drift. If you want to know what time it really is, you probably want --get instead.
Get the time of day from the Hardware Clock.
This is like --show except that it applies an adjustment for systematic drift. See the discussion of systematic drift below.
The display is like that for --show except there is no offset field. The time of day reported is the actual time of day as of the moment you invoked hwclock.
Set the Hardware Clock to the datetime given by the −−date option.
Set the System Time from the Hardware Clock.
If you specify the --slew option, hwclock uses the adjtimex() system call to cause the kernel to begin slewing the system time to the new datetime by advancing slightly faster or slower than normal for a certain period. Otherwise, hwclock sets the system time to the new datetime immediately, which means the system time may go backward or jump forward. Such discontinuities are usually a bad thing for a system. The only time the --slew option is not a good idea is when you are initially setting the system time in a startup script. No one should be looking at the system time before that, and a large discontinuity is normal then.
This option also causes hwclock to set the kernel’s timezone value to the local timezone as your C library’s tzset() function understands it. EXCEPT: hwclock always sets the daylight saving time part of the kernel’s timezone value to 0 ("not daylight saving time"). If DST is supposed to be in effect, hwclock just adds an hour to the base part.
To see exactly what hwclock considers your local timezone, see the documentation for tzset on your system.
Even with the --slew option, the local time part of the System Time jumps if you change the kernel timezone offset. This usually isn’t a problem because of the limited ways in which the local System Time gets used.
See the discussion of timezones below.
--hctosys is a good option to use in one of the system startup scripts.
--hctosys also has the side effect of sometimes configuring eleven minute mode, which means it can affect future values of the Hardware Clock. See the section "Automatic Hardware Clock Synchronization By the Kernel."
Set the Hardware Clock to the current System Time.
A common way to use this is to run ntpdate first to set the System Time, then run hwclock −−systohc to propagate the setting the the Hardware Clock.
Add or subtract time from the Hardware Clock to account for systematic drift since the last time the clock was set or adjusted. See discussion below.
Print on standard output the kernel’s Hardware Clock epoch value. This is the Gregorian year number of the year to which a zero year value in the Hardware Clock refers. For example, if you are using the convention that the year counter in your Hardware Clock contains the number of full years since 1952, then the kernel’s Hardware Clock epoch value must be 1952.
This epoch value is used whenever anything, including hwclock, reads or sets the hardware clock via the Linux rtc device driver.
This operation fails if you don’t have the Linux rtc device driver in your kernel.
Set the kernel’s Hardware Clock epoch value to the value specified by the −−epoch option. See the −−getepoch option for details.
This operation fails if you don’t have the Linux rtc device driver in your kernel.
Print the version of
hwclock on Standard Output.
You need the following option if you specify −−set option. Otherwise, it is ignored.
Specifies the time to which to set the Hardware Clock. The value of this option is an argument to the date(1) program. For example,
hwclock --set --date="9/22/96 16:45:05"
The argument is in local time, even if you keep your Hardware Clock in Coordinated Universal time or some other time scale. See the --utc option.
The following options apply to most functions.
Indicates that the Hardware Clock is kept in Coordinated Universal Time or local time or some explicit offset from UTC, respectively. It is your choice in which time scale to keep your clock, but nothing in the clock tells which you’ve chosen. So this option is how you give that information to hwclock.
If you specify the wrong one of these options (or specify none and take a wrong default), both setting and querying of the Hardware Clock will be messed up.
−−tzoffset’s value is the number of minutes one subtracts from UTC to get the raw Hardware Clock value (so as a timezone, it’s the number of minutes west of the Prime Meridian; the number of minutes the zone is behind UTC).
Note that there is a significant difference between "local time" (−−localtime) and a simple offset from UTC (−−tzoffset): for most people, the local time offset depends upon the season (daylight saving time).
If you specify none of −−utc, −−localtime, or −−tzoffset, the default is whichever was used the last time hwclock was used to set the clock (i.e. hwclock was successfully run with the −−set, −−systohc, or −−adjust options), as recorded in the adjtime file. If the adjtime file doesn’t exist (or was last updated by a version on hwclock that predates this field), the default is local time.
The default is local time for historical reasons, but UTC usually makes more sense. It is less confusing, more consistent with the way the system represents System Time, and more portable. And because it’s simpler, you’re less likely to encounter bugs in hwclock or other parts of your system. More important, though, is that in most locales, local time changes abruptly twice a year and the hardware clock cannot implement that. So you must reset your Hardware Clock explicitly whenever the local time zone switches between daylight saving time and standard time.
However, Windows is not designed to have the Hardware Clock in anything but local time. So if you might run Windows on the machine, you probably want your Hardware Clock in local time. Windows has complex function built in to reset the Hardware Clock twice a year. With hwclock, you’ll have to set the same thing up. All it takes to switch to or from DST is to set the Hardware Clock, which you might do with a hwclock --systohc in a startup script or cron job.
Bear in mind that hwclock always assumes it (or, more precisely, something using the adjtime file) is the only thing updating the Hardware Clock. So if you let Windows modify your Hardware Clock for a DST transition, you’re asking for trouble.
Note that you sort of have the ability to keep your Hardware Clock in UTC on Windows. There is a registry key named HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\RealTimeIsUniversal that is supposed to do that (its type is REG_DWORD; the value 1 is what you want). However, this is actually a vestige, not intended by Microsoft for use. Reports are that as late as Windows Vista, Microsoft does not provide a supported way to work with a Hardware Clock that is in UTC.
Tells hwclock to assume that there were no changes to the Hardware Clock time due to things other than systematic drift since the last time hwclock calibrated the Hardware Clock. Based on this assumption, hwclock may update the drift rate in the adjtime file if you are setting the clock. It adjusts the value for drift if you are reading the clock.
You don’t normally need this because hwclock assumes it. However, there is one troublesome case relating to eleven minute mode in which hwclock can falsely determine that your kernel is in the mode, and therefore not simply drifting. When you know hwclock will make this mistake, −−drift overrides it. See the section "Automatic Hardware Clock Synchronization By the Kernel."
Tells hwclock to assume that there were changes to the Hardware Clock time due to things other than systematic drift since the last time hwclock calibrated the Hardware Clock. Based on this assumption, hwclock will not update the drift rate in the adjtime file if you are setting the clock and will use the actual unadjusted value of the clock if you are reading it. If you are setting the clock, hwclock will record the present time as the starting point for any future drift calculations with or without the --nodrift option.
One case where you would want to use this is where your clock has gotten messed up due to loss of battery power. Another is where you have reset the clock manually with something other than hwclock. If the thing that is setting your Hardware Clock is the Linux kernel in eleven minute mode (perhaps set by an NTP daemon), you don’t need this option. hwclock knows about eleven minute mode. (See the section "Automatic Hardware Clock Synchronization By the Kernel.")
Another case for --nodrift is leap seconds. See the section Leap Seconds.
hwclock is smart enough to realize on its own that something other than drift has modified the Hardware Clock if the value of the clock is so different from what you’re setting it to that it cannot reasonably be explained by drift.
If you’re really picky about accuracy, you can also distinguish between cold drift and warm drift and use --nodrift to indicate any drift was while the clock was warm and therefore doesn’t count. See below.
Specifies the year which is the beginning of the Hardware Clock’s epoch. I.e. the Gregorian year number of the year to which a zero value in the Hardware Clock’s year counter refers.
hwclock --setepoch --epoch=1952
This option is analogous to the --localtime and --utc options, and its default is handled the same way. The basic default value is 1900.
Virtually everyone uses an epoch value of 1900, because that was the convention set up by designers of DOS. However, Digital Unix uses 1952, some other DEC machines use 1958, and there are reports that Windows NT uses 1980. Essentially the only reasons to use something besides 1900 are: 1) you run another operating system on this hardware and that operating system is fixed on some other epoch value, and 2) you have an old machine that doesn’t deal well with hardware clock year values greater than 99.
Most hardware clocks don’t allow you to use any arbitrary zero year convention, because of the way they decide whether to go from February 28 to February 29 or March 1. So choosing an --epoch value different from what the hardware clock defines will mess up your leap days. But if your convention is a multiple of 4 years from the built-in convention, you probably will never see any difference.
The epoch value must be at least 1900 and at most the current year.
The --epoch value (and its adjtime file default) do not affect interpretation of the hardware clock unless you use the "direct ISA" clock access method (see the --directisa option). All the other methods have their own way of determining the hardware clock’s epoch convention. (But see the --setepoch option, for the way to control one of those methods).
Besides controlling interpretation of the hardware clock, --epoch affects the --setepoch operation.
Indicates that the Hardware Clock is incapable of maintaining years outside the range 1994-1999. There is a problem in some BIOSes (almost all Award BIOSes made between 4/26/94 and 5/31/95) wherein they are unable to deal with years after 1999. If the POST routine (the BIOS routine that runs when the system powers up) finds a year less than 94 (or 95 in some cases) in the clock, it resets it to 94 (or 95). Thus, if you have one of these machines, it would be fruitless for hwclock to set the year after 1999 and hwclock cannot use the value of the clock as the true time in the normal way.
To compensate for this (without your getting a BIOS update, which would definitely be preferable), always use --badyear if you have one of these machines. When hwclock knows it’s working with a brain-damaged clock, it ignores the year part of the Hardware Clock value and instead tries to guess the year based on the last calibrated date in the adjtime file, by assuming that that date is within the past year. For this to work, you had better do a hwclock --set or hwclock --systohc at least once a year!
Though hwclock ignores the year value when it reads the Hardware Clock, it sets the year value when it sets the clock. It sets it to 1995, 1996, 1997, or 1998, whichever one has the same position in the leap year cycle as the true year. That way, the Hardware Clock inserts leap days where they belong. Again, if you let the Hardware Clock run for more than a year without setting it, this scheme could be defeated and you could end up losing a day.
hwclock warns you that you probably need --badyear whenever it finds your Hardware Clock set to 1994 or 1995.
There is one other way to deal with this BIOS problem (besides fixing the BIOS or using --badyear). There is a master boot loader program that notices when POST has messed up the clock and restores it to the proper year. It does this by updating the Master Boot Record with the current time each time it runs. Based on that, it can tell what year it is supposed to be unless you don’t boot your computer for more than a year.
(The master boot loader is the program that lives in the Master Boot Record (MBR), which POST loads and then transfers to when it’s done with its initialization work. POST is the BIOS routine that runs when you first power on or reset your ISA-family machine. The name POST is derived from "Power On Self Test.")
If you run this master boot loader, you don’t need --badyear. But it won’t hurt anything if you use it.
Since around March 2001, Debian’s and Suzhe’s master boot loader have had this function included.
This option says to use the Linux rtc device driver, via the device special file named fileName.
By default, hwclock chooses among various methods to access your hardware clock, as described in the section How Hwclock Access the Hardware Clock.
This option forces hwclock to consider only the Linux rtc device driver as the clock access method.
This option specifies what file to use as the adjtime file. See the ADJTIME_FILE section for information about the adjtime file and its default location.
Note that if you specify a nonexistent file name, hwclock does not fail. It proceeds with no adjtime file and, if it is to update the adjtime file, creates the named file.
is meaningful only on an ISA family machine or an Alpha (which implements enough of ISA to be, roughly speaking, an ISA machine for hwclock’s purposes). For other machines, specifying this option is an error. This option tells hwclock to use explicit I/O instructions to access the Hardware Clock. The process must have superuser effective uid to use this method.
We’re using the term "ISA family" here to refer to the various descendants of the original IBM PC/AT, whose architecture was named ISA. Though current machines have discarded a great deal of what was ISA, the Hardware Clock access is essentially the same.
By default, hwclock chooses among various methods to access your hardware clock, as described in the section "How Hwclock Accesses the Hardware Clock".
This option forces hwclock to consider only explicit I/O instructions.
This options makes hwclock take less time to read or set the hardware clock, at the cost of being up to a second wrong. The hardware clock can only be read or set in whole seconds. For hwclock to read or set the hardware clock precisely, it must wait until the moment the second changes. In some hwclock operations, this can mean up to two seconds of waiting.
If you don’t care for that much precision, specify --fast and there will be no waiting.
If you use --fast, --adjust will work for you only if you set and adjust the hardware clock very infrequently. You probably don’t want to do either unless the hardware clock is more than 5 seconds off.
--fast is useful for speeding up a system boot. If it isn’t important that your system time be accurate to less than a second, the hwclock --hctosys in your startup script may be unnecessarily slowing down your bootup.
When hwclock needs to wait for the moment of a clock tick (see the --fast option for an explanation of why it does this), it normally sets up an interrupt for the moment of the clock tick and lets other processes run until that interrupt happens. But if you specify --nointerrupt, hwclock will instead just read the clock continuously until it sees the clock’s value change.
One case where this is a good option to use is where your kernel is broken or misconfigured and the clock’s interrupt function doesn’t work. We have seen this happen. If this is your situation, either hwclock takes a long time to run or it issues an error message telling you you have the problem.
On some systems, the clock simply doesn’t have the interrupt function, and correctly indicates that fact to hwclock. In that case, hwclock automatically does the busywait instead and this option has no effect.
If you specify --fast, there is no waiting for a clock tick, so this option has no effect.
The only clock access method that has the interrupt function is the Linux rtc device driver (which is the method hwclock usually uses). If it uses any other method, this option has no effect.
The busywait method of synchronization with the Linux rtc device driver clock access method is not as accurate as the interrupt method. That’s because of the way the rtc device image deals with an attempt to read the clock while the hardware clock is in the middle of updating. Since hwclock reads continuously until it sees that an update has completed, it is bound to read the hardware clock while the update is in progress. When it does, the rtc device image notices that an update is in progress and therefore it cannot return a meaningful clock value. So it waits a while to give the update time to complete and then returns the clock value. But the amount of time it waits is always longer -- way longer -- than the update really takes, typically creating an error of between 8 and 18 milliseconds.
This option tells hwclock what absolute CPU priority to use for time-critical operations. There is a small part of the processing where it is important that hwclock’s execution be fast and of predictable speed. If the process gets preempted so another process can use the CPU, that severely hampers this goal. Therefore, you may want to give hwclock high priority for the CPU during these time-critical operations.
The value here is an absolute priority, not the traditional Unix "nice" priority you’re probably used to. With an absolute priority, hwclock will always run in preference to any other process with a lower absolute priority, regardless of how much CPU time hwclock has had in the past.
Most Linux processes use absolute priority zero, so there is some risk in using a higher absolute priority for hwclock: If a bug in hwclock causes it to go into an infinite loop, your entire system will be hung; you must reboot. To get around this, you might ensure that at least one process, perhaps a shell, runs with higher absolute priority than hwclock. You could use that process to kill a broken hwclock process.
hwclock uses timestamps so that the majority of its processing is not time-critical and uses high CPU priority only where absolutely necessary. But while this is a small part of hwclock’s processing, it can last a couple of seconds, because it involves waiting for the exact moment of a clock tick, and the ticks happen only once a second. But in the most usual environments, hwclock isn’t using the CPU that whole time -- other processses can run while hwclock waits for an interrupt, and then hwclock gets the CPU back immediately.
The value of --cpupriority is a nonnegative integer. The higher the number, the more favored the priority. The value is a minimum; if the process already has a higher priority, it remains at that level.
When hwclock raises the priority, it selects FIFO as the policy for scheduling among processes with that same priority.
The value zero, which is the default, is special. It means to leave CPU scheduling exactly as it is.
Also see --nomlock.
This option tells hwclock not to pin (lock) virtual memory in real memory.
By default, hwclock pins the entire process virtual memory in real memory while doing time-critical computations in order to reduce the computation time, and more importantly, the variability of the computation time. Without the pinning, a memory access by hwclock might generate a page fault and thus take substantially longer to complete than a memory access that doesn’t.
It requires special privilege to pin virtual memory (typically, the process must be running as superuser). If hwclock’s attempt to pin memory fails, it issues a warning message and continues anyway. --nomlock is a way to avoid that warning message.
Also see --cpupriority.
This option makes hwclock print to Standard Error the difference between the time you told it to set in the Hardware Clock and the time that actually got set.
The largest part of this error is normally the time it takes the Hardware Clock to do an update. That’s typically about 2 milliseconds.
Another, much smaller, part of the error is the time it takes the CPU and Linux kernel to process the change.
The error also includes the finite time it takes for hwclock to execute. But only a very small, quite reliable part of hwclock’s execution can cause this error, because hwclock measures its own execution time and takes as much of it as possible into consideration.
Altogether, if you don’t use --correct, you will normally see an error of at most a few milliseconds, and negative.
To the extent that this error is reliable (the same every time), you can compensate for it with the --correct option. The reported error has any --correct value already considered so that as you increase --correct, you should see the reported error increase (We’re talking about signed values, so "increase" isn’t necessarily bad!).
But note that if you never access the hardware clock with anything but hwclock, you won’t even see the effect of this error (so won’t need --correct), because hwclock records it in the adjtime file and takes it into account when it reads the clock in the future.
If the error is greater than 100 milliseconds, hwclock will print a warning to Standard Error regardless of --reporterror, because that probably signifies a more pathological cause, such as a bug in the system or a heavily loaded system interfering with hwclock’s timings. To avoid this warning, if the error is consistent, you can use --correct.
--correct This option specifies an amount in seconds to add to the time that gets set into the Hardware Clock with --set, --systohc, or --adjust to account for systematic inaccuracy in setting of the clock. I.e. if when you set the Hardware Clock, it always ends up .1 second behind what you set it to, you can specify --correct .1 and hwclock will set the Hardware Clock .1 second ahead of where it otherwise would to compensate.
A common source of this kind of inaccuracy is execution time of hwclock itself. While every effort is made by hwclock to eliminate the effect of execution time from the setting, there may still be a few milliseconds of error.
We’ve seen another case where the setting doesn’t work: Some Hardware Clocks appear always to set the datetime exactly half a second earlier than they are told to. If you have such a clock, you will get a warning message is described under --reporterror and you can use a --correct on a subsequent setting to compensate for the error and avoid the warning in the future.
The half second error is rather confusing because the standard Hardware Clock is actually designed, in one way of looking at it, to set the datetime half a second later than it is told to, so the erroneous Hardware Clock can be seen as simply setting it properly. This could explain the design error. The design calls for the Hardware Clock to tick exactly half a second after you set it, so if you set datetime 3:42:21 and read the clock registers 501 milliseconds later, you’ll get 3:42:22. If the Hardware Clock instead does the more natural thing and ticks a full second after being set, the effect is of setting the clock half a second earlier than was commanded.
You may specify a negative value.
You can use the --reporterror option to decide what value to use for this. Your goal is to get --reporterror to report an error as close to zero as possible.
hwclock remembers this value in the adjtime file. When you invoke hwclock in the future to set the Hardware Clock, and don’t specify --correct, hwclock will use this value again. In fact, you can use --correct on a command that doesn’t set the clock, just to set the value in the adjtime file for future settings.
But as a safety measure, hwclock does not remember the --correct value if it is a second or more, because that probably means you’re doing something reckless, and the value isn’t really a correction as described above.
These options all tell hwclock what kind of Alpha machine you have. They are invalid if you don’t have an Alpha and shouldn’t be necessary if you do, because hwclock should be able to determine by itself what it’s running on. These options make it possible for hwclock to work even when its environment does not conform to its expectations and thus it cannot accurately determine what sort of system it is running on. If you think hwclock is incorrectly determining the system’s characteristics, try running with the --debug option to see what conclusions the program is reaching and how. If you find you need one of these options to make hwclock work, contact the hwclock maintainer to see if the program can be improved to detect your system automatically.
--jensen means you are running on a Jensen model.
--arc means your machine is running with ARC console time.
--srm means your machine is running with SRM console time.
--funky-toy means that on your machine, one has to use the UF bit instead of the UIP bit in the Hardware Clock to detect a time transition. "Toy" in the option name refers to the Time Of Year facility of the machine.
Do everything except actually updating the Hardware Clock or anything else. This is useful, especially in conjunction with −−debug, in learning about hwclock.
Display a lot of information about what hwclock is doing internally. Some of its function is complex and this output can help you understand how the program works.
If you’re going to understand the world of timekeeping in Linux, or talk to someone else about it without causing confusion, you must get around the sloppy terminology that abounds in discussion of time.
First, remind yourself of the following, which should be obvious:
- There is no way to change the time of day in Linux. If you could write a program to do this, you would win a Nobel prize.
- It is always the same time in New York as it is in Paris.
- Governments cannot change the time of day by declaring daylight saving time. The time does not change each Spring and Fall.
What we can change are 1) the system’s perception of the time of day (a "clock"), and 2) what we call a particular time of day ("local time").
Clocks in a
There are two main clocks in a Linux system:
The Hardware Clock: This is a clock that runs independently of any control program running in the CPU and even when the machine is powered off.
On an ISA system, this clock is specified as part of the ISA standard. The control program can read or set this clock to a whole second, but the control program can also detect the edges of the 1 second clock ticks, so the clock actually has virtually infinite precision.
This clock is commonly called the hardware clock, the real time clock, the RTC, the BIOS clock, and the CMOS clock. Hardware Clock, in its capitalized form, was coined for use by hwclock because all of the other names are inappropriate to the point of being misleading.
The System Time: This is the time kept by a clock inside the Linux kernel and driven by a timer interrupt. (On an ISA machine, the timer interrupt is part of the ISA standard). It has meaning only while Linux is running on the machine. The System Time is the number of leap seconds since 00:00:00 January 1, 1970 UTC not including leap seconds (or more succinctly, the number of non-leap seconds since 1969). The System Time is not an integer, though. It has virtually infinite precision.
The System Time is the time that matters. The Hardware Clock’s basic purpose in a Linux system is to keep time when Linux is not running. You initialize the System Time to the time from the Hardware Clock when Linux starts up, and then never use the Hardware Clock again. Note that in DOS, for which ISA was designed, the Hardware Clock is the only real time clock.
It is important that the System Time not have any discontinuities such as would happen if you used the date program to set it while the system is running. You can, however, do whatever you want to the Hardware Clock while the system is running, and the next time Linux starts up, it will do so with the adjusted time from the Hardware Clock. You can also use hwclock --hctosys --slew or adjtimex to adjust the System Time smoothly while the system runs.
On some uncommon types of machine, the System Time is based on the Hardware Clock, not timer interrupts. This saves the time to process the interrupts (which, for reasons too complex to go into here is actually significant on these systems), and on these systems you can read the Hardware Clock as quickly as you could read an interrupt-based System Time. On a machine like this, much of hwclock’s function is meaningless, but we ignore these machines throughout this document except right here.
A Linux kernel maintains a concept of a local timezone for the system. But don’t be misled -- almost nobody cares what timezone the kernel thinks it is in. Instead, programs that care about the timezone (perhaps because they want to display a local time for you) almost always use a more traditional method of determining the timezone: They use the TZ environment variable and/or a directory such as /usr/local/etc/timezone, as explained in the man page for tzset(3). However, some programs and fringe parts of the Linux kernel such as filesystem drivers use the kernel timezone value. An example is the vfat filesystem driver. If the kernel timezone value is wrong, the vfat filesystem driver will report and set the wrong timestamps on files.
hwclock sets the kernel timezone to the value used by tzset when you set the System Time using the --hctosys option That means it uses the TZ environment variable or a directory of timezone information which is a configuration option of the system’s C library. GNU C Library Version 2 looks in the directory /usr/local/etc/zoneinfo by default, but is often configured to look instead in /usr/share/zoneinfo or /usr/lib/zoneinfo. The old Linux C library ("libc5") usually looks in /usr/lib/zoneinfo.
A complication is that the timezone value actually consists of two parts: 1) how far from the Standard Meridian the locality is geographically, and 2) whether or not a daylight saving time (DST) convention is in effect in the locality at the present time. In practice, the DST part of the timezone value is almost never used, so if the geographical part were to be set to its correct value, the users of the timezone value would actually compute the wrong local time.
Therefore, hwclock violates the definition of the kernel’s timezone value and always sets the DST part to zero. If DST is supposed to be in effect, hwclock simply adds an hour to the geographical part.
Accesses the Hardware Clock
hwclock uses many ways to get and set Hardware Clock values. The most normal way is to do I/O to the device special file /dev/rtc, which is presumed to be driven by the Linux rtc device driver. However, this method is not always available. For one thing, older systems don’t have it. Also, though there are versions of the rtc driver that work on DEC Alphas, there appear to be plenty of Alphas on which the rtc driver does not work.
The rtc device driver was new in Linux Release 2.0.
On older systems, the method of accessing the Hardware Clock depends on the system hardware.
On an ISA system, hwclock can directly access the "CMOS memory" registers that constitute the clock, by doing I/O to Ports 0x70 and 0x71. It does this with actual I/O instructions and consequently can only do it if running with superuser effective userid. (In the case of a Jensen Alpha, there is no way for hwclock to execute those I/O instructions, and so it uses instead the /dev/port device special file, which provides almost as low-level an interface to the I/O subsystem).
This is a really poor method of accessing the clock, for all the reasons that user space programs are generally not supposed to do direct I/O and disable interrupts. Hwclock provides it because it is the only method available on ISA and Alpha systems which don’t have working rtc device drivers available.
On an m68k system, hwclock can access the clock via the console driver, via the device special file /dev/tty1.
If you don’t specify any options to tell hwclock how you’d like it to access your hardware clock, hwclock tries various methods. First, it tries to use the Linux rtc device driver. If it is compiled for a kernel that doesn’t have that function, hwclock looks for another method. If it is compiled for a kernel with the rtc driver, it examines the first existing file in the list (/dev/misc/rtc, /dev/rtc, and /dev/rtc0) to see if it might be an interface to the rtc driver. If that fails, hwclock gives up on the rtc driver and looks for another method.
You can force hwclock not to consider any method other than the Linux rtc device driver, and specify the device special file through which you want it to access the driver, with the --rtc option.
On an ISA or Alpha machine, you can force hwclock to use the direct manipulation of the CMOS registers without even trying any other method by specifying the --directisa option.
device driver (/dev/rtc)
In this section, we assume that the device special file that hwclock is expects to access the Linux rtc device driver on your system is named /dev/rtc, but it is equally applicable to hwclock’s other default choice, /dev/misc/rtc, or any file you specify with the --rtc option.
If your system is incorrectly configured, hwclock may tell you that you have the /dev/rtc file, but not the device driver for it. Typically, you would see this message when hwclock complains that it can’t find any way to access the hardware clock, and then you run hwclock with the --debug option to find out why hwclock didn’t find /dev/rtc acceptable.
To confirm what hwclock is telling you, you can do the following:
ls -l /dev/rtc
and look at the major and minor device numbers displayed. Conventionally, it is Major 10 (miscellaneous devices), Minor 135 (rtc). Also, it should show a "c" at the beginning of the line, for "character device."
to list the drivers that are present in the kernel for Major 10. You should see a line like:
indicating that the rtc device driver has initialized and registered itself as available to serve Minor 135.
If you don’t see this, or something equivalent, that explains why you are having this problem with hwclock.
At the very least, you should delete dev/rtc, since it can only cause confusion. But you’d probably rather leave dev/rtc and get a device driver for it installed.
It’s possible that you don’t have the rtc driver in your kernel because one hasn’t been written for your machine. Or you may be running a really old Linux kernel from before the rtc driver existed. But it may just be that you didn’t select the CONFIG_RTC option ("Enhanced Real Time Clock Support") as a configuration option when you built your Linux kernel.
Note that hwclock does not depend on you using the conventional setup (Major 10, etc.) for the rtc device driver. The instructions above assume you are just for simplicity. The only thing hwclock depends upon is that the file /dev/rtc, if it exists, accesses your rtc device driver.
The Hardware Clock is usually not very accurate. However, much of its inaccuracy is completely predictable -- it gains or loses the same amount of time every day. This is called systematic drift. By tracking the rate of systematic drift, hwclock can get a more precise time from the Hardware Clock -- i.e. it doesn’t just go by what the clock says explicitly; it knows how to adjust it.
Furthermore hwclock’s "adjust" function lets you make systematic corrections to correct the systematic drift in the actual Hardware Clock (possibly for the benefit of other programs that access the clock that don’t have the benefit of hwclock’s knowledge of the systematic rate).
It works like this: hwclock keeps a file, called the "adjtime file," that keeps some historical information. See the ADJTIME FILE section for information about the adjtime file.
Suppose you start with no adjtime file. You issue a hwclock --set command to set the Hardware Clock to the true current time. hwclock creates the adjtime file and records in it the current time as the last time the clock was calibrated. 5 days later, the clock has gained 10 seconds, so you issue another hwclock --set command to set it back 10 seconds. hwclock updates the adjtime file to show the current time as the last time the clock was calibrated, and records 2 seconds per day as the systematic drift rate.
24 hours go by, and then you issue a hwclock --get command. hwclock consults the adjtime file and sees that the clock gains 2 seconds per day when left alone and that it has been left alone for exactly one day. So it subtracts 2 seconds from the value it reads from Hardware Clock and reports the result to you. Another 24 hours goes by and you issue another hwclock --get. This time, hwclock subtracts 4 seconds from the time it reads.
Now you issue a hwclock --adjust. This sets the actual Hardware Clock back 4 seconds and updates the adjtime file with the current time as the last time the clock was calibrated. The only purpose this really serves is to make the Hardware Clock value accurate for readers who don’t use the adjtime file (e.g. BIOS or dual-booted Windows).
Every time you calibrate (set) the clock (using --set or --systohc), hwclock recalculates the systematic drift rate based on how long it has been since the last calibration, how long it has been since the last adjustment, what drift rate was assumed in any intervening adjustments, and the amount by which the clock is presently off.
A small amount of error creeps in any time hwclock sets the clock, so it refrains from making an adjustment that would be less than 1 second. Later on, when you request an adjustment again, the accumulated drift will be more than a second and hwclock will do the adjustment then.
It is good to do a hwclock --adjust just before shutting the system down and periodically while the system is running via cron.
hwclock does the systematic drift correction any time it uses the time it reads from the Hardware Clock, except for the --show function. That function is meant to be a low level examination of the hardware more than an actual time query.
The Hardware Clock’s timekeeping is based on a quartz crystal. The electrical circuit causes the crystal to vibrate physically at its resonant frequency, and the electronics count the vibrations. The resonant frequency of a quartz crystal is very reliable, but one thing that has a quite noticeable effect on it is temperature. This is unfortunate for managing the systematic drift with hwclock, because the most convenient time to do the drift calculations is while the computer is running, which means hot, whereas knowing the drift rate is only really important when the computer is not running, which means it is cold. To get an accurate drift rate, you need to set the clock with --nodrift just before shutting down, leave it down for a while, and set it without --nodrift just after starting up.
A long time ago (before 2000), hwclock did not use the systematic drift information when reading the time from the Hardware Clock, but only for doing --adjust. In those days, you had to do hwclock --adjust frequently, and especially before invoking hwclock to do something such as --hctosys that relies on accurate Hardware Clock time. So lots of systems still exist today that do hwclock --adjust superfluously.
Every few years UTC has an additional second stuffed into it. The clock goes from 23:59:59 to 23:59:60 and then to 00:00:00. But most Hardware Clocks, including every one I have ever encountered, are not smart enough to do that. A Hardware Clock instead goes from 23:59:59 directly to 00:00:00 and thereafter is off by one second until you reset it.
Besides causing a problem just by being off for a second, this messes up hwclock’s drift calculation, because when you next calibrate the Hardware Clock (e.g. do a --systohc), hwclock might think the one second error was caused by drift and update the adjtime file to expect the clock to keep drifting at this rate in the future.
When this erroneous drift assumption happens, it will eventually get corrected as you continue to calibrate the Hardware Clock (do subsequent --systohc operations), but you can avoid it in the first place by doing a --systohc right before the leap second and a --hctosys --nodrift right after it.
Of course, if you’re calibrating the Hardware Clock from the system time, you should make sure the system time properly reflects the leap second first. The system time won’t necessarily do that automatically.
There is a case where you don’t want to correct the Hardware Clock after a leap second, thus making it always contain a time later than UTC. This is the case where your Linux system clock does not follow the POSIX standard, but instead counts the total number of seconds, including leap seconds since the epoch. Such systems have been proposed and have many benefits, and I have heard hints that they exist, but have no direct knowledge that they exist and I don’t know how to make one. I do know that such a system uses the "right" branch as opposed to the "posix" branch of the tzdata time zone database.
If you do have such a system, you don’t have to do anything special with hwclock except tell it to keep the Hardware Clock in UTC, and understand that it won’t actually do that. The Hardware Clock will actually be keeping a time later than UTC, but it will correctly transfer the time between the Hardware Clock and the system clock and will display the correct time. (The reason it will display the correct time in spite of the fact that it doesn’t contain real UTC is that the "right" timezone files (see above), which hwclock uses to compute the values to display, compensate for the lie).
The adjtime file, while named for its historical purpose of controlling adjustments only, actually contains other information for use by hwclock in remembering information from one invocation to the next.
You do not need to have an adjtime file to run hwclock. hwclock assumes defaults when it does not find one. hwclock typically creates an adjtime file any time you do a clock setting operation.
The most normal name for the adjtime file is /var/state/adjtime. Versions of hwclock before June 2003 used /etc/adjtime instead, so if you have that and not /var/state/adjtime, hwclock will use that instead. And FHS since at least 2006 specifies /var/lib/hwclock/adjtime, so hwclock will look there too.
But if you set the environment variable ADJTIME_PATH, hwclock uses the variable’s value as the name of the adjtime file. By the way, the reason /var/state is a better place for the adjtime file than /etc is that /etc is traditionally for system configuration information, not data that changes with the normal operation of the system. There is no widely accepted convention for placement of files like the adjtime file, but /var/state seems like the most logical convention around.
The format of the adjtime file is, in ASCII:
Line 1: 3 numbers, separated by blanks: 1) systematic drift rate in seconds per day, floating point decimal; 2) Resulting number of whole seconds since 1969 UTC of most recent adjustment or calibration, decimal integer (see Line 4 for fractional seconds); 3) time missed in most recent setting of the Hardware Clock, as a decimal integer.
Some detail on the (2) number: When hwclock sets the Hardware Clock, it sets it such that at the moment of the next clock tick after setting (more precisely, at the moment that hwclock notices the tick and looks at the system time), the Hardware Clock is exactly on the time scale to which you requested to have it set, with zero drift correction. That moment is what gets recorded as (2). The Hardware Clock begins drifting away from that time scale at that moment, so in future drift calculations, this is the value to use.
But the Hardware Clock drifts during the half second between when hwclock sets it and the next clock tick. hwclock compensates for that in choosing the moment to set the Hardware Clock so that there is zero accumulated drift at the moment of the tick (2). It accounts for it by using your --correct value. To the extent that your --correct value does not correct for that drift, hwclock will set the clock wrong, and you will see the error with --reporterror.
And for (3): hwclock is not able to set the Hardware Clock precisely for various reasons, but can read it quite precisely. So after it sets the clock, hwclock reads it and sees how close it got. It records here the amount of time that should have gone into the clock but didn’t (mathematically, the opposite of the setting error). Use --reporterror to make hwclock issue a message containing this information. So to get the true datetime, you add this value to whatever you read from the Hardware Clock. If you always use this value to correct what you read from the Hardware Clock, there is no reason for the --correct option (and Line 4 of the adjtime file) when you set the clock.
The ancient primogenitor of hwclock, clock, made no attempt to set the clock with better than one second precision, so this error value was the only way to get subsecond precision. It was known as the "not adjusted" value, since it was used only for drift adjustments that are so susceptible to that rounding error.
Line 2: 1 number: Resulting number of seconds since 1969 UTC of most recent calibration. Zero if there has been no calibration yet or it is known that any previous calibration is moot (for example, because the Hardware Clock has been found, since that calibration, not to contain a valid time). This is a decimal integer.
Line 3: 3 tokens: 1) "UTC" or "LOCAL". Tells whether the Hardware Clock is set to an explicit offset from absolute time (Coordinated Universal Time) or local time. You can always override this value with options on the hwclock command line. 2) epoch. The year number in the Common Era that a zero in the hardware clock’s year represents (e.g. 1900 means 1900 AD). Must be an integer greater than or equal to 1900. 3) timezone offset. This is the number of seconds one subtracts from the raw value in the Hardware Clock to get UTC. As a time zone, it is seconds west of the prime meridian. This value applies to the present contents of the Hardware Clock, and is not necessarily the value one should use to set a new value: In the case of a Hardware Clock kept in a local time that has daylight saving time, the appropriate offset for now might not be the appropriate offset for the datetime when the clock was last set. For a normal Hardware Clock kept in UTC, the timezone offset is always zero.
Line 4: Fractional part of last adjustment time referred to in Line 1. Floating point decimal.
Line 5: Correction to be added any time hwclock sets the Hardware Clock. In effect, the value of the --correct option when hwclock was most recently invoked.
You can use an adjtime file that was previously used with the clock program or any older version of hwclock with hwclock.
Hardware Clock Synchronization By the Kernel
You should be aware of another way that the Hardware Clock is kept synchronized in some systems. The Linux kernel has a mode wherein it copies the System Time to the Hardware Clock every eleven minutes. We’ll call this mode "eleven minute mode." The most important thing to know about eleven minute mode is that it is almost always bad, and you should do what you can to avoid it. See below for tips.
Eleven minute mode can be a reasonable mode to use when you are using something sophisticated like NTP to keep your System Time synchronized. (NTP is a way to keep your System Time synchronized either to a time server somewhere on the network or to a radio clock hooked up to your system. See RFC 1305). But it probably isn’t even then, because it does nothing about the systematic drift that happens while the computer is down, and keeping track of time while the computer is down is the whole point of the Hardware Clock. And even while the system is running, it is not as accurate as hwclock -- the Hardware Clock does drift during that eleven minutes. It would be better to use hwclock --systohc regularly, but on most systems you don’t have that option because you can’t disable eleven minute mode.
hwclock tries to determine whether the kernel is in eleven minute mode, but it can’t know for sure. It simply assumes that that if the system clock is in "externally synchronized" mode, then the kernel is in eleven minute mode, and vice versa.
When hwclock believes the kernel is in eleven minute mode, hwclock --adjust does nothing and functions that set the clock reset the drift calibrations in the adjtime file to reflect the fact that the deviation between the Hardware Clock time and true time says nothing about systematic drift.
Also, if you set the Hardware Clock with hwclock when it believes the kernel is in eleven minute mode, the program warns you that you may be interfering with something else that is trying to maintain Hardware Clock time.
Eleven minute mode usually follows the externally synchronized mode of the system clock. Externally synchronized mode is the mode of the system clock where something other than the kernel’s timer interrupts is keeping it on track. The system clock is not in externally synchronized mode until something puts it into it. The NTP daemon ntpd is one thing that does. You can take the system clock out of externally synchronized mode by running anything, including hwclock --hctosys, that sets the System Time the old fashioned way.
To see if the system clock is in externally synchronized mode, use the command adjtimex --print and look at the value of "status". If the "64" bit of this number (expressed in binary) is equal to 0, it is in the mode. Otherwise, it is not.
If you know your kernel is not in eleven minute mode, you can stop hwclock from doing the wrong thing (based on its false conclusion that it is) by specifying the --drift option. That makes hwclock’s belief about eleven minute mode irrelevant because you are explicitly telling it that the Hardware Clock is running and drifting on its own.
Another confusing aspect of eleven minute mode is that hwclock --hctosys, which ostensibly just sets the System Time, sometimes has the odd side effect of configuring eleven minute mode. Eleven minute mode maintains the Hardware Clock in either local or universal time (just as hwclock does). But the kernel provides no direct way for the user to choose which one. Instead, it makes it a complex side effect of setting the System Time, as follows.
The first time (after boot) you set the kernel time zone offset, the kernel configures eleven minute mode for either universal or local time in the Hardware Clock. If you set it to something other than zero, and don’t set the time of day at the same time, the kernel configures eleven minute mode for local time. Otherwise, it configures it for universal time. Note that it makes no difference what nonzero value you set; the local time offset that eleven minute mode uses is the kernel timezone offset at the time eleven minute mode sets the Hardware Clock (i.e. every 11 minutes). And note that the local/universal setting is permanent as long as the kernel runs. It is a side effect only of the first time you set the kernel timezone offset.
Because there is no way to avoid or undo this side effect of setting the kernel timezone offset, there is no way to avoid such a side effect of hwclock --hctosys. hwclock does, however, get to choose the setting of the switch -- local or universal -- and it does it according to whether you specified (or defaulted) --local or --utc.
The ability for eleven minute mode to maintain the Hardware Clock in local time was new in Linux 3.9 (May 2013). It worked as described above as late as Linux 3.16 (August 2014). hwclock before Release 2.45 always configures eleven minute mode (when it hasn’t already been permanently configured) for a universal time Hardware Clock.
Eleven Minute Mode
The best thing to do is to configure the Linux kernel without the CONFIG_GENERIC_CMOS_UPDATE option (the default is with). You really don’t want eleven minute mode.
Older kernels do not have this option. You can easily modify the kernel code to eliminate eleven minute mode, though.
Some Linux kernels have a proc file sys/kernel/time/rtc_update that you can use to disable eleven minute mode regardless of externally synchronized mode. Some simply don’t have eleven minute mode.
You can of course leave the eleven minute mode capability in the kernel and just never run Ntpd or anything else that puts the system clock into externally synchronized mode.
Along these lines, note that to turn off eleven minute mode, it is not enough to stop Ntpd. Even without additional input from Ntpd, the kernel continues to consider the system clock to be externally synchronized for a while (about a day in one experiment). To declare the clock not externally synchronized and end eleven minute mode, use adjtimex --status 65.
If you disable or otherwise don’t have eleven minute mode but run Ntpd, be sure to use the --drift option as specified above to prevent hwclock from being fooled. Also, run hwclock --systohc regularly (maybe once a day) to take advantage of the Ntpd clock discipline and do what eleven minute mode was meant to do (but much better).
The user accounting database (normally implemented as files named "utmp" and "wtmp") is what principally keeps track of who is logged in and who has logged in. There are special records defined to record any setting of the System Time. (Since all the records in the database have timestamps, these records can help to interpret the database).
hwclock records records in the utmp and wtmp files whenever you set the System Time (with the --hctosys option), unless you set it without discontinuity (by using the --slew option). hwclock updates any existing "last-time-change" records in utmp and adds time-change log records to wtmp.
You identify the utmp and wtmp files with the UTMP_FILE and WTMP_FILE environment variables. If you don’t set these, the filenames default to whatever default your C library uses. Typically, this is /var/run/utmp and /var/log/wtmp.
There are two formats of utmp/wtmp records commonly used with Linux kernels: The Linux libc version and the GNU libc 2 version. The Linux libc version (you may know this C library as "libc5") is older; the GNU libc 2 (you may know this C library as "libc6") replaces it. Which format hwclock generates is determined by which C library you use with it. Some systems keep separate files with the separate formats and have some programs write one format and others write the other. Some run a utmpd daemon to convert and copy records between the two. You may have to pay attention to these issues to avoid having hwclock write records in one format and other programs write records in another format to the same file.
Clock Century Value
There is some sort of standard that defines CMOS memory Byte 50 on an ISA machine as an indicator of what century it is. hwclock does not use or set that byte because there are some machines that don’t define the byte that way, and it really isn’t necessary anyway, since the year-of-century does a good job of implying which century it is.
If you have a bona fide use for a CMOS century byte, contact the hwclock maintainer; an option may be appropriate.
Note that this section is relevant only when you are using the "direct ISA" method of accessing the Hardware Clock.
(see above for complete documentation of hwclock’s use of these)
ADJTIME_PATH TZ UTMP_FILE WTMP_FILE
(see above for complete documentation of hwclock’s use of these)
/var/state/adjtime /etc/adjtime /usr/lib/zoneinfo/ /usr/local/etc/zoneinfo/ /usr/share/zoneinfo/ /dev/rtc /dev/port /dev/tty1 /proc/cpuinfo /var/run/utmp /var/log/wtmp
adjtimex(8), date(1), gettimeofday(2), settimeofday(2), crontab(1), tzset(3), ntp(8)
You can get adjtimex from Metalab. Look it up on http://www.freshmeat.net.
date is in the GNU shell utilities package, which is available from http://www.gnu.org.
gettimeofday(), settimeofday(), and tzset() are in the Linux or GNU C library.
You can look up the location of the current version of hwclock on http://www.freshmeat.net.
ntp (the software package, not the protocol) is available via the Time WWW server at http://www.eecis.udel.edu/~ntp/. Or see ftp://ftp.udel.edu/pub/ntp.
Written By Bryan Henderson, September 1996 (firstname.lastname@example.org), based on work done on the clock program by Charles Hedrick, Rob Hooft, and Harald Koenig. See the source code for complete history and credits.
As of this writing, Bryan Henderson (email@example.com) is actively maintaining hwclock. Contact Bryan with questions, suggestions, or requests.