mirror of
https://github.com/boostorg/date_time.git
synced 2026-01-28 19:12:17 +00:00
164 lines
7.4 KiB
HTML
164 lines
7.4 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
|
|
<title>Date-Time Concepts - Theoretical Foundations</title>
|
|
<link href="doxygen.css" rel="stylesheet" type="text/css">
|
|
</head>
|
|
|
|
<body>
|
|
<a href="../../../index.htm">
|
|
<img align="left" src="../../../c++boost.gif" alt="C++ Boost">
|
|
</a>
|
|
<h1>Tradeoffs: Stability, Predictability, and Approximations</h1>
|
|
<p> </p>
|
|
<hr>
|
|
<a href="index.html">Overall Index</a> --
|
|
<a href="gregorian.html">Gregorian Index</a> --
|
|
<a href="posix_time.html">Posix Time Index</a>
|
|
<p>
|
|
|
|
<H2>Unavoidable Trade-offs</H2>
|
|
|
|
<p>
|
|
The library does its best to provide everything a user could want, but there are certain inherent constraints that limit what <i>any</i> temporal library can do. Specifically, a user must choose which two of the following three capabilities are desired in any particular application:
|
|
<UL>
|
|
<li>exact agreement with wall-clock time
|
|
<li>accurate math, e.g. duration calculations
|
|
<li>ability to handle timepoints in the future
|
|
</UL>
|
|
Some libraries may implicitly promise to deliver all three, but if you actually put them to the test, only two can be true at once. This limitation is not a deficiency in the design or implementation of any particular library; rather it is a consequence of the way different time systems are defined by international standards. Let's look at each of the three cases:
|
|
<p>
|
|
If you want exact agreement with wall-clock time, you must use either UTC or local time. If you compute a duration by subtracting one UTC time from another and you want an answer accurate to the second, the two times must not be too far in the future because leap seconds affect the count but are only determined about 6 months in advance. With local times a future duration calculation could be off by an entire hour, since legislatures can and do change DST rules at will.
|
|
<p>
|
|
If you want to handle wall-clock times in the future, you won't be able (in the general case) to calculate exact durations, for the same reasons described above.
|
|
<p>
|
|
If you want accurate calculations with future times, you will have to use TAI or an equivalent, but the mapping from TAI to UTC or local time depends on leap seconds, so you will not have exact agreement with wall-clock time.
|
|
<p>
|
|
<H2>Stability, Predictability, and Approximations</H2>
|
|
|
|
<p>
|
|
Here is some underlying theory that helps to explain what's going on.
|
|
Remember that a temporal type, like any abstract data type (ADT),
|
|
is a set of values together with operations on those values.
|
|
<p>
|
|
<H3>Stability</H3>
|
|
|
|
<p>
|
|
The representation of a type is <i>stable</i> if the bit pattern associated with a given value does not change over time.
|
|
A type with an unstable representation is unlikely to be of much
|
|
use to anyone, so we will insist that any temporal library use
|
|
only stable representations.
|
|
<p>
|
|
An operation on a type is stable if the result of applying the operation to a particular operand(s) does not change over time.
|
|
<p>
|
|
<H3>Predictability</H3>
|
|
|
|
<p>
|
|
|
|
Sets are most often classified into two categories: well-defined
|
|
and ill-defined. Since a type is a set, we can extend these definitions
|
|
to cover types. For any type T, there must be a predicate
|
|
<i>is_member( x )</i>
|
|
which determines whether a value x is a member of type T.
|
|
This predicate must return <i>true</i>, <i>false</i>, or <i>dont_know</i>.
|
|
<p>
|
|
If for all x, is_member( x ) returns either true or false, we
|
|
say the set T is <i>well-defined</i>.
|
|
<p>
|
|
If for any x, is_member( x ) returns dont_know, we say the
|
|
set T is <i>ill-defined</i>.
|
|
<p>
|
|
Those are the rules normally used in math. However,
|
|
because of the special characteristics of temporal
|
|
types, it is useful to refine this view and create a third category
|
|
as follows:
|
|
<p>
|
|
For any temporal type T, there must be a predicate <i>is_member( x, t )</i>
|
|
which determines whether a value x is a member of T.
|
|
The parameter t represents the time when the predicate is evaluated.
|
|
For each x<sub>i</sub>, there must be a time t<sub>i</sub> and a value v
|
|
such that:
|
|
<ul>
|
|
<li>v = true or v = false, and
|
|
<li>for all t < t<sub>i</sub>, is_member( x<sub>i</sub>, t ) returns dont_know, and
|
|
<li>for all t >= t<sub>i</sub>, is_member( x<sub>i</sub>, t ) returns v.
|
|
</ul>
|
|
t<sub>i</sub> is thus the time when we "find out" whether x<sub>i</sub> is a
|
|
member of T.
|
|
Now we can define three categories of temporal types:
|
|
<p>
|
|
If for all x<sub>i</sub>, t<sub>i</sub> = negative infinity,
|
|
we say the type T is <i>predictable</i>.
|
|
<p>
|
|
If for some x<sub>i</sub>, t<sub>i</sub> = positive infinity,
|
|
we say the type T is <i>ill-formed</i>.
|
|
<p>
|
|
Otherwise we say the type T is <i>unpredictable</i> (this
|
|
implies that for some x<sub>i</sub>, t<sub>i</sub> is finite).
|
|
<p>
|
|
Ill-formed sets are not of much practical use, so we will
|
|
not discuss them further. In plain english the above
|
|
simply says that all the values of a predictable type are
|
|
known ahead of time, but some values of an unpredictable
|
|
type are not known until some particular time.
|
|
|
|
<p>
|
|
<H3>Stability of Operations</H3>
|
|
|
|
<p>
|
|
Predictable types have a couple of important properties:
|
|
<UL>
|
|
<li> there is an order-preserving mapping from their elements onto a set of consecutive integers, and
|
|
<li> duration operations on their values are stable
|
|
</UL>
|
|
The practical effect of this is that duration calculations
|
|
can be implemented with simple integer subtraction.
|
|
Examples of predictable types are TAI timepoints and
|
|
Gregorian dates.
|
|
<p>
|
|
Unpredictable types have exactly the opposite properties:
|
|
<UL>
|
|
<li> there is no order-preserving mapping from their elements onto a set of consecutive integers, and
|
|
<li> duration operations on their values are not stable.
|
|
</UL>
|
|
Examples of unpredictable types are UTC timepoints and
|
|
Local Time timepoints.
|
|
<p>
|
|
We can refine this a little by saying that a range within
|
|
an unpredicatable type can be predictable, and operations performed
|
|
entirely on values within that range will be stable.
|
|
For example, the range of UTC timepoints from 1970-01-01
|
|
through the present is predictable, so calculations of durations within that range will be stable.
|
|
<p>
|
|
<H3>Approximations</H3>
|
|
|
|
<p>
|
|
These limitations are problematical, because important temporal
|
|
types like UTC and Local Time are in fact unpredictable, and
|
|
therefore operations on them are sometimes unstable. Yet as a practical matter we often want to perform this kind of operation, such as computing the duration between two timepoints in the future that are specified in Local Time.
|
|
<p>
|
|
The best the library can do is to provide an approximation,
|
|
which is generally possible and for most purposes will be
|
|
good enough. Of course the documentation must specify when
|
|
an answer will be approximate (and thus unstable) and how
|
|
big the error may be. In many respects calculating with unpredictable sets is analogous to the use of floating point numbers, for which results are expected to only be approximately correct. Calculating with predictable sets would then be
|
|
analogous to the user of integers, where results are expected
|
|
to be exact.
|
|
<p>
|
|
For situations where exact answers are required or instability cannot be tolerated, the user must
|
|
be able to specify this, and then the library should throw an
|
|
exception if the user requests a computation for which an
|
|
exact, stable answer is not possible.
|
|
<p>
|
|
|
|
<hr>
|
|
<address><small>
|
|
<!-- hhmts start -->
|
|
Last modified: Wed Aug 21 14:46:55 MST 2002
|
|
<!-- hhmts end -->
|
|
by <a href="mailto:jeff@crystalclearsoftware.com">Jeff Garland</a> © 2000-2002
|
|
</small></address>
|
|
</body>
|
|
</html>
|