new time conversion interface

Nathan Myers ncm at cantrip.org
Tue Nov 3 11:56:07 UTC 1998


Apologies for following up my own posting, but I don't want to lose
the thread here.  I have edited the quoted text below for clarity.

>  > Nathan Myers wrote:
>  > > The problem with the mktime model is that conversions between civil
>  > > time and timestamps can result in 2, 1, or <1 valid conversions ...
>
> ... it's a rare wall clock, legal document, train schedule or 
> airline ticket that indicates UTC offset, and when it does it's 
> likely to be wrong, especially during the "interesting" times.
> ...
> The problem that normally arises is that someone enters a date/time
> and I want a numeric real-time value.  I distinguish the following 
> troublesome cases:
>
> 1. It's in spring and they enter 02:30, and that time doesn't exist,
>    but there's a good guess (e.g. equiv. to 03:30) for what
>    they probably meant.  (There's a corresponding case for leap
>    seconds.)
> 2. In spring they enter 03:30, which might be correct, but they might 
>    well have meant 04:30 because they failed to reset their clock.
> 3. In autumn, they enter 01:30; did they mean the first time it 
>    happened that day or the second?  Either is equally valid.
> 4. (Also in autumn) If they enter 02:30, did they mean officially 
>    02:30, or did they mean the second 01:30?

I believe that conversions should yield a struct containing
a reference timestamp, followed by up to four offsets tagged with
official wall-clock offset, interpretation, and confidence values.  
For example, in the cases above, and ignoring leap seconds for 
the moment, we would get

0.  Unambiguous time, e.g. 04:30 morning of a time change

  t0=123456789
  offset 0: 0 sec; wall-clock offset: -3600 sec; 
     interpretation: unambiguous; confidence: certain
  offset 0: -3600 sec; wall-clock offset: -3600 sec. 
     interpretation: suggested substitute; confidence: doubtful

1. Spring ambiguity, enter 02:30 when it doesn't exist because 
   civil time proceeded 01:59:59 -> 03:00:00.  (Or 02:00:00 to
   03:00:01?  I don't know.)

  t0=123456789
  offset 0: 0 sec; wall-clock offset: -3600 sec. 
     interpretation: suggested substitute; confidence: doubtful

2. Spring ambiguity, enter 02:30 when it doesn't exist because 
   civil time proceeded 01:59:59 -> 03:00:00 (or whatever).

  t0=123456789
  offset 0: 0 sec; wall-clock offset: 0 sec. 
     interpretation: official choice; confidence: Nominally unambiguous
  offset 1: -3600 sec; wall-clock offset: 0 sec. 
     interpretation: suggested substitute; confidence: doubtful

3. Autumn ambiguity, enter 01:30 on morning when civil time proceeds
   from 01:59:59 to 01:00; is it the first or second 01:30 event?

  t0=123456789
  offset 0: 0 sec; wall-clock offset: 3600 sec. 
     interpretation: ambiguous choice; confidence: equal alternative
  offset 1: 3600 sec; wall-clock offset: 0 sec. 
     interpretation: ambiguous choice; confidence: equal alternative

4. Autumn, enter 02:30, same morning as above; did they mean the
   official 02:30, or did they mean the second 01:30 because they 
   failed to reset their clock?

  t0=123456789
  offset 0: 0 sec; wall-clock offset: 0 sec. 
     interpretation: official choice; confidence: Nominally unambiguous
  offset 1: 3600 sec; wall-clock offset: 0 sec. 
     interpretation: unofficial choice; confidence: Possible alternative

For each case above one might have up to two more entries corresponding
to leap-second ambiguities.  The detailed semantics of all the possible
"interpretation" and "confidence" tags must be nailed down.  This might 
end up looking sort of like the following C struct layout, using 
deliberately unsatisfactory names for exposition:

  typedef ... time_stamp;  /* something more-or-less numeric */
  typedef enum { 
    official, unofficial, ambiguous, suggested 
  } time_meaning;
  typedef enum { 
    nominal, alternative, possible, doubtful 
  } time_confidence;
  struct time_interpretation {
    int offset;        /* limited to +/- 3601 */
    long wall_offset;  /* limited to +/- 43200 */
    time_meaning meaning;
    time_confidence confidence;
  };
  struct time_from_civil {
    time_stamp reference_time;
    int interpretation_count;  /* range 0-4 */
    time_interpretation interpretation[4];
  };

(I've neglected leap-second ambiguity interpretations because they would
reduce the clarity of the exposition.)  The conversion function might
look like:

  int time_convert(const struct tm *, const time_zone *, time_from_civil *);

I think an interface like this would encapsulate knowledge about
time conversion issues, exposing a high-level view of the possible 
real-time values implied by wall-clock time records.  I think it 
would lead to better, more robust interfaces for conversions, and 
reduce programmer errors.

Comments?

Nathan Myers
ncm at cantrip.org




More information about the tz mailing list