Representing Time

Introduction

I got involved in working on time representation when working on a Scheme Request for Implementation on Time and Date procedures. I wanted a standard for Scheme like Common Lisp's Time functions. Standard Scheme does not have procedures for time at all, although all implementations provide some support.

General background information

Claus T¿ndering's Frequently Asked Questions about calendars is very useful resource.

Systems of Time

An excellent resource is the NIST Systems of Time page. A crucial distincution is between "international atomic time" (TAI), and "Coordinated Universal Time" (UTC). These differ by "an integral number of leap seconds." Leap seconds are not predictable; you have to look them up in a table, or request it from some time service.

TAI measures constant, real time. UTC is TAI adjusted by a number of leap seconds.

Standard Notational Representation of Time

ISO Standard 8601 is an internation standard for time/date notation (including durations). Markus Kuhn has a useful summary description; so does Gary Houston. The W3 Consortium also has a useful Note.

Data type representations for time

There are a number of goals, some conflicting, for a time data type:
  1. It should take up as little space as possible to represent a time.
  2. It should represent a wide range of time it can represent.
  3. It should have good precision at the 'macro' and 'sub-second' level.
  4. It should be easy and fast to do time arithmetic and time comparisons.
  5. It should be easy and fast to do conversions to/from standard time formats.
  6. It should be handle all of the minutae of time representations including leap seconds, wierd calendar formats, etc.

Typically, the start of the range is called 'the epoch.'

Erik Naggum's representation of time as three fixnums: number of days since 2000-03-01, number of seconds since the start of the day, the number of ms since the start of the second.

From Marc Feeley's comments on an early draft of mine:

For your information, Gambit-C (a Scheme implementation) represents the time datatype internally as a flonum, and counts the number of microseconds elapsed since the base date (so the value 15.0 means 15 microseconds since the turn of the year 1970). The advantage of this representation is that
  1. computing with time (such as time comparison and difference) can be done very fast (no bignum operation is required)
  2. time is represented with microsecond resolution exactly (by an inexact integer) over the range: base date +/- 285 years (because there are 53 bits of mantissa)
  3. the resolution degrades gradually as the point in time get further from the base date (but frankly I don't expect Scheme to survive for 285 years, although I am sure you'll still be able to buy Cobol compilers!)

Dan Berstein has a 64-bit format, TAI64, which "TAI64 represents a few hundred billion years of real time with 1-second precision". The epoch was a long time ago. It supports nanosecond (10^-9) or attosecond (10^-18) precision.

Standard UNIX time represents time as an unsigned 32-bit number of seconds since the beginning of 1970; it will expire in 2038.

A good recommendation for a replacement for ISO C 200X, including lots of options for TAI, UTC, etc.

Implementations

Dan Berstein's representation, libtai (C-based).

More background information

The Time Service Department of the U.S. Naval Observatory has excellent information. And so is NIST; see NIST's Time FAQ.

Dan's Bernstein's UTC, TAI, and UNIX time is short and sweet.

Set up your own set of world-wide clocks.

Peter Baum has some good pages on Date algorithms.