Time for UNIX
Midnight, Thu Jan 1, 1970 is the traditional beginning
of the UNIX
epoch. UNIX keeps track of time as the number of seconds
that date, Greenwich Mean Time (GMT). UNIX stores the
seconds as a
32-bit offset from that date, where 0 is that date.
Using 32 bits,
UNIX can represent a range of 4,294,967,296 seconds,
to 136 years, 36 days, 6 hours, 28 minutes, and 16 seconds.
in Listing 1 shows that the minimum date representable
is Fri Dec 13, 1901, at 8:45:52 pm and the maximum (2,147,483,647)
is Tue Jan 19, 2038, at 3:14:07 am. Only about 44 more
before UNIX has to set a new epoch.
This 32-bit number (the seconds offset from the beginning
of the epoch)
is used throughout UNIX operations. It figures in the
of files, in the process and login time stamps, and
in all other time
calculations. The ANSI C Standard borrowed this idea
for the time_t
data type, so any C program written with the standard
functions is using the UNIX epoch format. Other systems
may use a
different epoch -- for instance, MSDOS and derivatives
Jan 1, 1980 instead -- but the idea is the same.
Time is an important aspect of UNIX operations because
are often left on around the clock to take advantage
processing and deferred processing. cron doesn't work
the real time clock operating properly, and for the
clock to run properly
the system administrator must understand how UNIX treats
zones, daylight savings time, and holidays.
Local Time Zones
Each user has an individual time zone setting stored
in the TZ
environment variable. This variable's initial setting
the system-wide setting in the /etc/TIMEZONE file. TZ
can hold a simple value composed of two parts, but typically
is composed of at least three parts: the three-letter
for the standard time zone, the number of hours offset
from GMT to
that time zone, and the three-letter abbreviation for
the zone's daylight
savings time. For example, PST8PDT means that Pacific
Time is eight hours away from GMT and Pacific Daylight
A system in New York is only five hours away from GMT,
so it would
Hour offsets can be either positive or negative. One
adds eight hours
to PST to get GMT. At a site east of GMT, one would
to get to GMT. For instance, Middle European Time, also
known as Central
European Time, is MET-1 DST, Hong Kong time is HKT-8,
and Japan time is JST-9. (Add -1, -8, and -9 hours,
to local time at these locations to get GMT.) The offset
minutes, and even seconds, if necessary. Hours, minutes,
are separated with colons. For instance, Newfoundland
and parts of
Australia use half-hour offsets from GMT. Newfoundland's
UNIX assumes that daylight savings time is one hour
the usual local offset. If that isn't true for your
can overide the default with an additional offset value
the daylight savings time abbreviation.
Each user can have an individual time zone setting.
(This is handy
for people who commonly login to the system from remote
can set the TZ variable from within the user's own .profile
files under Bourne Shell (sh) or Korn Shell (ksh), or
within the .login
files if you're using C-Shell (csh). Once TZ is reset,
time stamps are adjusted to the new time zone, yet other
different time zone settings would see their own zone-adjusted
Try it! Create a file, then look at a long listing showing
stamp of that file. Change your TZ variable's setting.
sure to export TZ if you're using sh or ksh.
Then look at a long listing of that file. The time stamp
to the new time zone. You can reset your TZ to the system's
standard by executing the /etc/TIMEZONE script. Use
. /etc/TIMEZONE in sh or ksh. For csh,
you'll need to manually execute the TZ setting shown
by using the setenv command.
Daylight Savings Time
One great problem in time-keeping today is daylight
savings time (DST).
Different regions have different rules and these rules
are often inconsistent.
The general rule now in the United States is to add
one hour to the
clock at 2 am on the first Sunday in April, and take
that hour back
at 2 am on the last Sunday in October. Of course, it
this way. Before 1974, DST started on the last Sunday
in April. In
1974, Presidential decree set the start date back to
January. In 1975,
DST started in February. From 1976 to 1986 it started
on the last
Sunday in April. In 1987 it was pushed back to the first
April, where it is today.
If you think that sounds complicated be warned that
it gets worse.
Some countries change in different months, on different
days of the
week, and at different times of the day. Some countries
DST. According to the rules I've found, the People's
Republic of China
turns back to standard time in September, not October,
while the Republic
of Korea changes to DST in May, not April. European
to change in March and September, but some change at
2 am, and some
at 3 am. Southern hemisphere countries must reverse
their change months.
Some parts of Australia had variations during the 1970s
but now seem
to revert to standard time in March. Other parts of
use DST. New South Wales had several variations in the
1980s but has
settled down to starting DST in October and ending it
in March. Brazil
changes on Saturdays instead of Sundays.
Given these examples, a system administrator clearly
can't set the
DST date once and never look at it again. New UNIX site
may require someone to look at the local conventions
and adjust the
system's clock to seasonal changes. Existing UNIX installations
occasionally update their settings when the government
new time change.
The simplest example of a TZ setting is one without
savings time, such as JST-9. Japan Standard Time (JST-9)
is nine hours east of GMT. (Japan doesn't observe Daylight
Time.) In the United States, PST8PDT, Pacific Standard
is eight hours west of GMT and has a daylight time abbreviation
a number. Without a number following the daylight time
(PDT), the system assumes that the daylight time is
one hour from the standard time. You may specify a DST
offset if you need one. For example, PST8PDT7 explicitly
that daylight savings time in the Pacific zone be seven
I have yet to determine how the system identifies when
in the year
to change to daylight savings time. The TZ variable
includes a mechanism for explicitly citing only one
year. After the
DST abbreviation and its own optional hour offset, you
a comma followed by a starting date and time, and another
by an ending date and time. On the starting date, at
time, the system applies the DST offset. When the ending
time come, the standard offset is restored. For example,
A start time comes after the first comma. The number
92 refers to
April 3, the first Sunday in April in 1994. (This 92
from Table 1.) Following the 92 is a slash, which separates
number from the time to start the PDT change: 2 am.
signals the end time. The 302, again from Table 1, refers
30, the last Sunday in October in 1994. On that date
at 2 am, PDT
is turned off and the system returns to PST. Changing
at 2 am is the
default, so the line could have been:
The problem with this Table 1 method is that in 1995
the Sundays will fall on different dates. Daylight savings
begin on day 91 (instead of 92), and end on day 301
(instead of 302).
So a system administrator using this method must change
the date numbers
(There are 14 possible calendars -- seven plain years
1 on each day of the week and seven leap years with
January 1 on each
day of the week. A system administrator could create
the 14 possible
variations as separate files, but would still have to
enable the appropriate
one each year. I can imagine a cron job using my day-of-the-week
script ("Which Day of the Week Is This?,"
Jul/Aug 1993 Sys
Admin, vol. 2, no. 4, p. 79) that runs every January
1 and enables
the appropriate variation in /etc/TIMEZONE. Or maybe
change the /etc/TIMEZONE script itself, making it far
sophisticated so that it can figure the local time directly
login. I don't find this an elegant solution, though.
exists the problem of modifying all 14 variations to
national or local daylight savings time change.)
Somebody came up with a better way. I've found that
if I don't explicitly
name the DST start and end dates my system knows to
start on the first
Sunday in April and end on the last Sunday in October.
I didn't tell
it to do that, so the method must exist somewhere. My
Esix SVR4 system
has a /usr/lib/locale/TZ directory containing a set
that identify many time zones and their DST variations.
I found some
documentation for this in zic(1M), which stands for
compiler. There are seven files in zic containing data
major regions of the world. Table 2 reviews the contents
These files contain two kinds of tables, known as rules
and may contain links that identify variations in zone
tables make it easy to track and modify time zone variations.
zic program reads these files and produces very small
files and occasionally some directories that represent
the rules in
some system-usable form.
There's only one problem. I can't find where the zic's
get installed so the system can use them. The zic man
doesn't say. The man page refers to a standard directory,
/usr/share/lib/zoneinfo, where the compiled files will
but that directory doesn't exist on a newly installed
system and running
zic doesn't create it. If the directory doesn't exist,
are the files that drive newly installed systems? I
my system using the names that zic created but I couldn't
find any originals with those file names. So, I'm stumped.
I know my system knows the appropriate time to change
to DST. I know
the system's time change corresponds with the information
within the appropriate /usr/lib/locale/TZ table file.
know how it knows that. I don't know where to install
the new files
created by zic if I need to change or add to the rules,
how to tell the system to use the newly created files.
has an option to put the files into a directory other
I assume there is some way to tell the system which
directory to use.
(This method would be similar to debugging terminfo
where you can identify a specific directory for testing
definitions without fouling up the rest of the system.)
No man pages
I've found yet answer any of these questions about zic.
If you know the secrets of the time zone tables used
or if you have found or will write more thorough documentation
using these files, please contact Sys Admin.
The first time I ran accounting on UNIX I discovered
an error message
about an undocumented /etc/acct/holidays file. This
the current year, the hour and minute when prime time
begins, the hour and minute when non-prime time usage
the holidays recognized by the system site.
At least five accounting programs use the holidays file:
acctcon(1M), acctcon1(1M), acctprc(1M), and
acctprc1(1M). The runacct(1M) script tests to see
if acctcon creates an error log file. That log file
if some process named pnpsplit fails. This pnpsplit,
most likely a compiled function named for Prime time/Non-Prime
parsing, probably reads, parses, and validates the holidays
preparing the holidays data for further use by other
parts of those
programs. I've deduced this from error messages within
the five compiled
accounting programs. There is no documentation for pnpsplit
and my system contains no source code associated with
it. (I refuse
to disassemble acctcon.)
There is a maximum number of holiday entries because
the error messages
ask the user to recompile pnpsplit and increase a constant
named NHOLIDAYS. Unfortunately, this isn't easy to do
the source code is unavailable and I have no idea what
NHOLIDAYS is set to. However, I know that at least eight
are supported because that's how many are listed in
my copy of /etc/acct/holidays.
Because this holidays file isn't documented except by
in the file, I'll try to document the file format here:
1. Comments begin with an asterisk (*) and extend
to the end of the line.
2. The first uncommented line contains three tab-separated
numbers. Leading white space is ignored.
a. The first number is the current year expressed as
a four-digit number, such as 1994.
b. The second number is the time when prime time starts
expressed as a four-digit number representing a 24-hour
instance, use 0800 to mean 8:00 am.
c. The third number is the time when non-prime time
starts expressed as a four-digit number representing
a 24-hour clock.
For instance, use 1800 to mean 6:00 pm.
The line containing all three examples would look like
1994 0800 1800
3. The remaining uncommented lines contain the month,
a slash (/),
and the day of the holiday followed optionally by at
least one tab
and any comments about the date, such as the name of
Each holiday requires a new line. New Year's Day would
look like this:
1/1 New Year's Day
Every date listed in the /etc/acct/holidays file
is presumably treated as non-prime time, and so are
times on all other
dates between the non-prime start time and the prime
Here's the problem for the system administrator: this
has to be changed every year. Certain holidays fall
on specific dates
despite the day of the week, such as New Year's Day,
and Christmas Day. These holidays never need changing.
But other holidays
fall on certain weekdays, such as Memorial Day, Labor
Day, and Thanksgiving
Day. The dates for these holidays will be different
I propose a script that cron can run once a year. This
reads a configuration file containing a table that identifies
about the holiday, which could be the specific month
and day or could
be some designation such as the fourth Thursday of November.
of this configuration file is in uniformly identifying
for different locales. The script analyzes the current
possibly using my day-of-the-week script, and updates
file indentifying the current year and the holiday dates
current year. If you have the script, or wish to write
to handle this problem, contact Sys Admin.
About the Author
Larry Reznick has been programming professionally since
1978. He is currently
working on systems programming in UNIX, MS-DOS, and
He teaches C language courses
at American River College and at National University
He can be reached via email at: