The UNIX and Linux Forums  

Go Back   The UNIX and Linux Forums > Top Forums > UNIX for Dummies Questions & Answers > Answers to Frequently Asked Questions > Tips and Tutorials
Google UNIX.COM



View Single Post in UNIX Forums - Click on the Thread or Permalink to View Entire Thread -->
  #1 (permalink)  
Old 02-19-2007
Perderabo's Avatar
Perderabo Perderabo is offline
Unix Daemon
 

Join Date: Aug 2001
Location: Washington DC Area
Posts: 8,334
Understanding Unix Timekeeping

Internal Time
Internally, a Unix system maintains time as the number of seconds since the Unix Epoch. The Unix Epoch was at midnight Jan 1, 1970 UTC. In the Eastern Timezone of the US that was Dec 31, 1969 at 19:00. As I start this article, the time is 1171733878. I am using NTP (Network Time Protocol) to keep my computer's clock in sync. So at the exact instant that my computer thought it was 1171733878, probably so did yours. Every computer should be in agreement as to what time it is. It does not matter in which timezone your computer resides or in which timezone you reside. If I had written to a file during that second, Unix would have recorded the modification time as 1171733878.

Unix time was traditionally a signed 32 bit integer. That means that maximum time is 2147483647 which, in the Eastern TimeZone of the US would be Jan 18, 2038 at 22:14:07. The plan is for this to expand to a 64 bit integer before then. Unix seconds count forward one-by-one. After 1171733878, the next second that my system will know about is 1171733879. Once it is syncronized, NTP works by shortening or lengthening a second. I can obtain the time by calling the system call time(). If I want something better than seconds, the next most accurate interface is the system call times(). times() main purpose is to obtain a structure of data pertaining to system usage. But the return code is also useful... it is the time in clock ticks. Clock ticks start at some arbitrary point in the past (often boot time) and they advance whenever the kernel clock routine runs. How many clock ticks per second can vary. You can call sysconf(_SC_CLK_TCK) to find out your value. 100 is common value these days. Older systems used 60. 100 and 60 are the only two values I have seen. Clock ticks are also returned as a signed integer. So after about a year, the number will roll back to zero. Other than rollover, clock ticks also advance one-by-one. (Clock ticks are often called "jiffies" by Linux folks.) There is also another system call, gettimeofday() which returns the time since the Unix Epoch in seconds and microseconds. gettimeofday() is required to exist and to use microsecond precision. However the accuracy is explicitly unspecified. The microseconds do not advance one-by-one in any system that I have seen. I assume that Unix systems are fairly good with hundreths of a second and maybe even milliseconds is some cases. But I would not assume any accuracy beyond that.

Human Readable Timestamps
Now that we know how Unix keeps time, let's move on to a different subject: How to display time to a user. Few users will be happy with a timestamp being displayed as 1171733878. Since I am in the Eastern Timezone of the US, I would like to see something like 12:37:58 on Feb 17, 2007. But a person in Los Angeles California would want something like 9:37:58 on Feb 17, 2007. I wrote a little perl script to display the formatted time when given a number like 1171733878. Here is the output as it should appear in both the Eastern and Pacific timezones for a few carefully selected timestamps:
Eastern:
1173596399 Sun 2007-03-11 01:59:59 Standard Time
1173596400 Sun 2007-03-11 03:00:00 Daylight Saving Time
1173607199 Sun 2007-03-11 05:59:59 Daylight Saving Time
1173607200 Sun 2007-03-11 06:00:00 Daylight Saving Time
Pacific:
1173596399 Sat 2007-03-10 22:59:59 Standard Time
1173596400 Sat 2007-03-10 23:00:00 Standard Time
1173607199 Sun 2007-03-11 01:59:59 Standard Time
1173607200 Sun 2007-03-11 03:00:00 Daylight Saving Time
Notice that the internal Unix time does not change with the onset of Daylight Saving Time. What happens is that a new rule for how to display the time takes effect. In order to convert internal time to a timestamp, Unix needs to know which timezone to use. And it needs to know if Daylight Saving is in effect. There are various subroutines that can be called to format a timestamp. All of these eventually invoke tzset() to determine the timezone and the state of Daylight Saving. And tzset always checks for the environment variable TZ to figure out what the user wants. If you don't a TZ environment variable, tzset() will go with some sort of default that can vary from system to system. The TZ environment variable is often set to something like EST5EDT4 which is what I use. This says that I am in a timezone called EST which is offset from Universal Time by 5 hours and during Daylight Saving days my timezone is called EDT which is offset from Universal Time by 4 hours. To know when Daylight Saving is in effect, tzset will look in some data file. Which file (and what format the file is in) varies from system to system. The patches that are available for this year's change in Daylight Saving should really be little more than some revisions to these files.

Universal Time
In addition to knowing about your timezone, a Unix System must be able to use Universal Time (which is almost the same as the old Greenwich Mean Time). This is what "date -u" does. The definition for Universal Time is well known and does not involve daylight saving changes. The Universal Time definition may be build into the date routines rather than using the data file for tzset(). This may be true even if an entry is present for UTC. Mail programs often use UTC timestamps.
Forum Sponsor