<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
  "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>


<meta http-equiv="content-type" content="text/html; charset=US-ASCII">
<title>Custom Time Duration Support</title>

<style type="text/css">
	h1	{ text-align: center; }
	p	{ text-align: justify; }
	address	{ text-align: right; }
	li	{ text-align: justify; }
	dt	{ font-style: italic; }
	ins {background-color:#A0FFA0}
	del {background-color:#FFA0A0}
	table	{ border-collapse: collapse;
		  margin-left: auto; margin-right: auto; }
	th	{ padding: 3px 10px 3px 10px;
		  border: 1px solid; }
	td	{ padding: 3px 10px 3px 10px;
		  border: 1px solid; }
</style>
</head>

<body>

<h1>Custom Time Duration Support</h1>

<p>
ISO/IEC JTC1 SC22 WG21 N2498=08-0008 - 2008-01-19
</p>

<p>
<a href="mailto:hinnant@twcny.rr.com">Howard E. Hinnant</a><br/>
<a href="mailto:jeff@crystalclearsoftware.com">Jeff Garland</a>
</p>

<h2>Contents</h2>

<ul>
<li><a href="#Introduction">Introduction</a></li>
<li><a href="#duration1">How Does One Create A Time Duration?</a></li>
<li><a href="#duration2">How Should One Be Able To Create A Time Duration?</a></li>
<li><a href="#comparison">Comparing <code>duration</code></a></li>
<li><a href="#arithmetic"><code>duration</code> Arithmetic</a></li>
<li><a href="#duration_cast"><code>duration_cast</code></a></li>
<li><a href="#wording">Proposed Wording</a></li>
<li><a href="#Acknowledgments">Acknowledgments</a></li>
</ul>

<h2><a name="Introduction">Introduction</a></h2>

<p>
<a href="n2497.html">N2497</a> introduces <a href="n2497.html#time.duration.requirements">Duration requirements</a>
which essentially create a concept for time durations in the standard library.  These time durations will
be very convenient and useful both for use in other parts of the standard library interface, and in
client code.  Several concrete types meeting the Duration requirements are also introduced:
</p>

<blockquote><pre>
class nanoseconds;
class microseconds;
class milliseconds;
class seconds;
class minutes;
class hours;
</pre></blockquote>

<p>
Because there is a documented set of requirements which all of the durations meet, this introduces
the possibility of <i>user-written</i> time durations.  Indeed <a href="n2497.html">N2497</a> was
written with the intent of interoperating with user-written time durations.  A user-written time
duration might model (for example) the amount of time between display updates.  For the purposes
of this paper, an example user-written duration referred to as <code>frame_duration</code> which
has units of 1/30 of a second will be used to illustrate the salient points described herein.
</p>

<p>
This paper proposes to make the creation of user-written durations (such as <code>frame_duration</code>)
<i>much</i> easier, while at the same time lifting some of the restrictions <a href="n2497.html">N2497</a>
places on duration comparison and arithmetic operations.  Furthermore, if accepted, this proposal
makes it easier for the client to write robust generic algorithms where the duration type itself is
generic (a <code>round_to_nearest</code> duration conversion algorithm is given as an example).
</p>

<p>
The ideas in this paper were specifically not folded into <a href="n2497.html">N2497</a> because the authors of
that paper felt that this work went well beyond the mandate of the Kona LWG Motion 14 and should
be formally reviewed by the LWG as a separate issue.
</p>

<p>
This paper does not change the syntax that the clients will use when working with standard defined
durations.  It only changes the syntax for those clients wishing to support or write user-defined
durations and algorithms trafficking in generic durations.  However it does impact the ABI of the
standard-defined durations.  Because of this, it is important to target this work towards C++0X instead
of a TR (where ABI breakage is generally intolerable).
</p>

<h2><a name="duration1">How Does One Create A Time Duration?</a></h2>

<p>
It is instructive to go through the process of creating <code>frame_duration</code> according
to the specification in <a href="n2497.html#time.duration.requirements">N2497</a>.  In addition
to the requirements listed in N2497, we may also want to add converting constructors from
those standard-defined durations which will exactly convert to <code>frame_duration</code>
(standard-defined durations have implicit conversions when the conversion is exact).
Most of the member functions for <code>frame_duration</code> are easy, though repetitive, and
included in the sketch below:
</p>

<blockquote><pre>
class frame_duration
{
    long long <var>ticks_</var>;
public:
    // traits information
    typedef long long tick_type;
    static const tick_type ticks_per_second = 30;
    static const tick_type seconds_per_tick = 0;
    static const bool is_subsecond = true;

    // construct
    frame_duration(long long <var>ticks</var>=0)
        : <var>ticks_</var>(<var>ticks</var>) {}

    // convert
    frame_duration(std::hours <var>hr</var>)
        : <var>ticks_</var>(<var>hr</var>.count() * (std::hours::seconds_per_tick * ticks_per_second)) {}
    frame_duration(std::minutes <var>mn</var>)
        : <var>ticks_</var>(<var>mn</var>.count() * (std::minutes::seconds_per_tick * ticks_per_second)) {}
    frame_duration(std::seconds <var>sec</var>)
        : <var>ticks_</var>(<var>sec</var>.count() * (std::seconds::seconds_per_tick * ticks_per_second)) {}

    // observer functions
    tick_type count() const {return <var>ticks_</var>;}

    // modifier functions
    template&lt;typename RhsDuration&gt;
        frame_duration&amp; operator-=(const RhsDuration&amp; <var>d</var>);
    template&lt;typename RhsDuration&gt;
        frame_duration&amp; operator+=(const RhsDuration&amp; <var>d</var>);
    frame_duration&amp; operator*=(tick_type <var>rhs</var>) {<var>ticks_</var> *= <var>rhs</var>;}
    frame_duration&amp; operator/=(tick_type <var>rhs</var>) {<var>ticks_</var> /= <var>rhs</var>;}

    // operations
    frame_duration operator-() const {return -<var>ticks_</var>;}
};
</pre></blockquote>

<p>
Implementing the <code>+=</code> and <code>-=</code> operators is a little more difficult.
We might choose to simply replace the templated members with a list of all of the standard
durations which will exactly convert:
</p>

<blockquote><pre>
// modifier functions
frame_duration&amp; operator-=(const std::hours&amp; <var>d</var>)   {<var>ticks_</var> -= frame_duration(<var>d</var>).count(); return *this;}
frame_duration&amp; operator-=(const std::minutes&amp; <var>d</var>) {<var>ticks_</var> -= frame_duration(<var>d</var>).count(); return *this;}
frame_duration&amp; operator-=(const std::seconds&amp; <var>d</var>) {<var>ticks_</var> -= frame_duration(<var>d</var>).count(); return *this;}
frame_duration&amp; operator+=(const std::hours&amp; <var>d</var>)   {<var>ticks_</var> += frame_duration(<var>d</var>).count(); return *this;}
frame_duration&amp; operator+=(const std::minutes&amp; <var>d</var>) {<var>ticks_</var> += frame_duration(<var>d</var>).count(); return *this;}
frame_duration&amp; operator+=(const std::seconds&amp; <var>d</var>) {<var>ticks_</var> += frame_duration(<var>d</var>).count(); return *this;}
</pre></blockquote>

<p>
This is easy but repetitive.  It also has the distinct disadvantage that it will not interoperate
with other user-written duration types which may be exactly convertible to <code>frame_duration</code>.
For example if someone else writes <code>tenth_second</code>, which would exactly convert to
<code>frame_duration</code>, one will still not be able to add <code>tenth_second</code> to
<code>frame_duration</code>.
</p>

<p>
To correct the above problem the author of <code>frame_duration</code> may choose to create a concept
or type trait which represents the idea of <code>RhsDuration</code> being a duration which is
exactly convertible to <code>frame_duration</code>.  One could then restrict the <code>RhsDuration</code>
template parameter, get away with a single implementation for the <code>+=</code> and <code>-=</code>
operators, and then interoperate seamlessly with <code>tenth_second</code>, even if <code>tenth_second</code>
does not yet exist.
</p>

<blockquote><pre>
// modifier functions
template&lt;typename RhsDuration&gt;
typename std::enable_if
&lt;
    is_duration_exactly_convertible_to&lt;RhsDuration, frame_duration&gt;::value,
    frame_duration&amp;
&gt;::type
    operator-=(const RhsDuration&amp; <var>d</var>);

template&lt;typename RhsDuration&gt;
typename std::enable_if
&lt;
    is_duration_exactly_convertible_to&lt;RhsDuration, frame_duration&gt;::value,
    frame_duration&amp;
&gt;::type
    operator+=(const RhsDuration&amp; <var>d</var>);
</pre></blockquote>

<p>
This is a far more difficult task, not only because of the need to write
<code>is_duration_exactly_convertible_to</code>, but also because of the need to
handle the generalized resolution conversion within the body of these members.
Having gone through this exercise the authors will simply relate their experience rather than
show the code here.  It is over 200 lines of support code which involves some template
meta programming and is easy to get wrong (which we did on the first few tries).  The
use of concepts instead of <code>enable_if</code> will only provide a little
relief (perhaps not reducing the line count at all).
</p>

<h2><a name="duration2">How Should One Be Able To Create A Time Duration?</a></h2>

<p>
During the writing of <a href="n2497.html">N2497</a> it was noticed that there is a
much better way to support the author of <code>frame_duration</code>.  However it was
a large enough change that it went well beyond "fixing the wording and minor problems
of <a href="../2007/n2447.htm">N2447</a>" (as was our mandate in writing N2497).
</p>

<p>
This paper proposes to replace the
<a href="n2497.html#time.duration.requirements">Duration requirements</a>
with a class template:
</p>

<blockquote><pre>
template &lt;class TickType, long long TicksPerSecond, long long SecondsPerTick&gt;
class duration
{
    TickType <var>ticks</var>;  // exposition only
public:
    // traits information
    typedef TickType tick_type;
    static const long long ticks_per_second = TicksPerSecond;
    static const long long seconds_per_tick = SecondsPerTick;
    static const bool is_subsecond = seconds_per_tick == 0;

    static_assert(ticks_per_second &gt;  1 &amp;&amp; seconds_per_tick == 0 ||
                  ticks_per_second == 0 &amp;&amp; seconds_per_tick &gt;  1 ||
                  ticks_per_second == 1 &amp;&amp; seconds_per_tick == 1,
                  "duration has inconsistent type");

    duration();
    duration(const tick_type&amp; <var>tick</var>);

    // conversions
    template &lt;class TT, long long TPS, long long SPT&gt;
      // Requires duration&lt;TT, TPS, SPT&gt; is exactly convertible to duration
      duration(const duration&lt;T, TPS, SPT&gt;&amp; <var>d</var>);

    // observer

    tick_type count() const;

    // arithmetic

    template &lt;class TT, long long TPS, long long SPT&gt;
      // Requires duration&lt;TT, TPS, SPT&gt; is exactly convertible to duration
      duration&amp;
      operator-=(const duration&lt;TT, TPS, SPT&gt;&amp; <var>d</var>);

    template &lt;class TT, long long TPS, long long SPT&gt;
      // Requires duration&lt;TT, TPS, SPT&gt; is exactly convertible to duration
      duration&amp;
      operator+=(const duration&lt;TT, TPS, SPT&gt;&amp; <var>d</var>);

    duration operator-() const;

    duration&amp; operator*=(tick_type <var>rhs</var>);
    duration&amp; operator/=(tick_type <var>rhs</var>);
};
</pre></blockquote>

<p>
The standard-defined durations then simply become <code>typedef</code>s.
</p>

<blockquote><pre>
typedef duration&lt;int_least64_t, 1000L * 1000 * 1000,    0&gt; nanoseconds;
typedef duration&lt;int_least55_t,        1000L * 1000,    0&gt; microseconds;
typedef duration&lt;int_least45_t,                1000,    0&gt; milliseconds;
typedef duration&lt;int_least35_t,                   1,    1&gt; seconds;
typedef duration&lt;int_least29_t,                   0,   60&gt; minutes;
typedef duration&lt;int_least23_t,                   0, 3600&gt; hours;
</pre></blockquote>

<p>
And the author of <code>frame_duration</code> now simply writes a single line of code instead of hundreds:
</p>

<blockquote><pre>
<b>typedef std::duration&lt;long long, 30, 0&gt; frame_duration;</b>
</pre></blockquote>

<p>
This <code>frame_duration</code> will interoperate with all exactly convertible
standard durations, <b>and</b> with all exactly convertible user-written durations.
The <code>duration</code> template takes care of all duration conversions and
arithmetic while maintaining the invariant that only exact conversions and
arithmetic is allowed, rejecting inexact operations at compile time.  The
embedded <code>static_assert</code> virtually eliminates the possibility of creating
a buggy duration:
</p>

<blockquote><pre>
typedef std::duration&lt;long, 5, 3&gt; MyBuggyDuration;

int main()
{
    MyBuggyDuration d;
}

In instantiation of 'std::duration&lt;long int, 5ll, 3ll&gt;':
main.cpp:7:   instantiated from here
error: static assertion failed: "duration has inconsistent type"
</pre></blockquote>

<p>
The <code>duration</code>'s <code>tick_type</code> can be an integral type,
a floating point type, or a user-written class (such as an arbitrary range integer class).  For example:
</p>

<blockquote><pre>
typedef std::duration&lt;big_int, 1000LL * 1000 * 1000 * 1000, 0&gt; picosecond;
</pre></blockquote>

<p>
The standard-defined durations all use a signed integral type for the
<code>tick_type</code>.  As long as the custom duration
<code>tick_type</code>s will explicitly convert to and from the signed
integral types used by the standard-defined durations, then the
user-defined durations will interoperate seamlessly with the
standard-defined durations.
</p>

<p>
A reference implementation exists, is available under an open source license, and is actually shorter than the reference
implementation of <a href="n2497.html#time.duration.requirements">N2497</a>.
</p>

<h2><a name="comparison">Comparing <code>duration</code></a></h2>

<p>
Consider the following code based on the <code>duration</code> template:
</p>

<blockquote><pre>
frame_duration    fd = 1;
std::milliseconds ms = 33;
bool b = ms &lt; fd;
</pre></blockquote>

<p>
According to <a href="n2497.html#time.nonmembers">N2497</a> the above will not compile
because <code>frame_duration</code> is not exactly convertible to <code>std::milliseconds</code>
and vice-versa.  This is a necessary constraint of N2497 because the only implementation technique
for the comparison is to convert <code>frame_duration</code> to <code>std::milliseconds</code>
and compare the two values of <code>milliseconds</code>.  However the comparison could give the
wrong answer since the conversion is not exact (<span style="font-size: 80%"><sup>1</sup>&frasl;<sub>30</sub></span> of a second is exactly 33<span style="font-size: 80%"><sup>1</sup>&frasl;<sub>3</sub></span> milliseconds).
</p>

<p>
But we know that 33 milliseconds is less than <span style="font-size: 80%"><sup>1</sup>&frasl;<sub>30</sub></span> of a second (by exactly <span style="font-size: 80%"><sup>1</sup>&frasl;<sub>3000</sub></span> of a second).
So it is unfortunate to not support this comparison and return the correct answer
(<code>b</code> is <code>true</code>).  Indeed, very practical code can result in non-obvious incorrect run time
results when comparisons do not give the correct result.
With the introduction of the <code>duration</code>
class template, we can now synthesize a new type that both <code>frame_duration</code> and
<code>std::milliseconds</code> exactly convert to, convert both arguments to that new type,
and then perform the comparison &mdash; <em>exactly</em>.
</p>

<p>
To describe this new synthesized type, the term <code>CommonDuration</code> is introduced and defined.
</p>

<blockquote>
<p>
The <code>CommonDuration</code> type of <code>duration&lt;T1, TPS1, SPT1&gt;</code> and
<code>duration&lt;T2, TPS2, SPT2&gt;</code> is:
</p>

<ul>
<li>
If <code>duration&lt;T2, TPS2, SPT2&gt;</code> is exactly convertible to
<code>duration&lt;T1, TPS1, SPT1&gt;</code>, then the <code>CommonDuration</code> type
is <code>duration&lt;T1, TPS1, SPT1&gt;</code>.
</li>

<li>
Else if <code>duration&lt;T1, TPS1, SPT1&gt;</code> is exactly convertible to
<code>duration&lt;T2, TPS2, SPT2&gt;</code>, then the <code>CommonDuration</code> type
is <code>duration&lt;T2, TPS2, SPT2&gt;</code>.
</li>

<li>
Else if <code>duration&lt;T1, TPS1, SPT1&gt;</code> and <code>duration&lt;T2, TPS2, SPT2&gt;</code>
are both non-subsecond <code>duration</code>s, then the <code>CommonDuration</code> type is
<code>duration&lt;T, TPS, SPT&gt;</code> where <code>SPT</code> is the
greatest common divisor of <code>SPT1</code> and <code>SPT2</code>, <code>TPS</code> is equal
to <code>SPT == 1</code>, and <code>T</code> is a signed integral type capable of representing a
&plusmn; 292 year range.  If the values <code>TPS</code> and <code>SPT</code>
correspond to a standard-defined duration, then <code>T</code> shall be the same type as the
<code>tick_type</code> of that standard-defined duration.
</li>

<li>
Else <code>duration&lt;T1, TPS1, SPT1&gt;</code> and <code>duration&lt;T2, TPS2, SPT2&gt;</code>
are both subsecond <code>duration</code>s.
The <code>CommonDuration</code> type is <code>duration&lt;T, TPS, SPT&gt;</code> where
<code>TPS</code> is the least common multiple of <code>TPS1</code> and <code>TPS2</code>,
and <code>SPT</code> is <code>0</code>.  If <code>TPS1 &lt; TPS2</code>, <code>T</code> has the same type as
<code>duration&lt;T2, TPS2, SPT2&gt;::tick_type</code>, else <code>T</code> has the same type as
<code>duration&lt;T1, TPS1, SPT1&gt;::tick_type</code>.
</li>
</ul>

<p>
[<i>Note:</i> Both <code>duration&lt;T1, TPS1, SPT1&gt;</code> and <code>duration&lt;T2, TPS2, SPT2&gt;</code>
are exactly convertible to their <code>CommonDuration</code> type. --<i>end note</i>]
</p>
</blockquote>

<p>
This paper proposes that all <code>duration</code> comparisons behave as if both arguments are
converted to their <code>CommonDuration</code> type prior to comparison.  Thus the restriction
of comparisons in <a href="n2497.html#time.nonmembers">N2497</a> which says that one argument
must be exactly convertible to the other can be lifted.  <em>Any</em> two <code>duration</code> types can be
<em>exactly</em> compared.
</p>

<p>
For example, the <code>CommonDuration</code> type of <code>duration&lt;long long, 1000, 0&gt;</code>
(<code>std::milliseconds</code>)
and <code>duration&lt;long long, 30, 0&gt;</code> (<code>frame_duration</code>) is
<code>duration&lt;long long, 3000, 0&gt;</code>.
In comparing 33 <code>milliseconds</code> with 1 <code>frame_duration</code>, the implementation
will first convert to the <code>CommonDuration</code> type and compare 99 with 100 and subsequently
return <code>true</code>.  The computation of the type of the <code>CommonDuration</code> type
is performed at compile time.  And so the run time cost of the comparison is at most 2 multiplications
in addition to the comparison.
</p>

<h2><a name="arithmetic"><code>duration</code> Arithmetic</a></h2>

<p>
Though the <code>+=</code> and <code>-=</code> operators of <code>duration</code> must remain
constrained to exactly convertible types, the same is not true of the binary
<code>+</code> and <code>-</code> operators.  For example, 1 <code>frame_duration</code> minus 33
<code>std::milliseconds</code> is <em>exactly</em> 1 <code>std::duration&lt;long long, 3000, 0&gt;</code>.
</p>

<p>
This paper proposes that the return type of the binary <code>+</code> and <code>-</code> operators
be changed from the <code>FinestDuration</code> type to the <code>CommonDuration</code> type.  When
one <code>duration</code> type is exactly convertible to the other, the <code>CommonDuration</code> type
and the <code>FinestDuration</code> type resolve to the same type.
</p>

<p>
Having exact <code>duration</code> comparison and arithmetic in his tool box, the standard library
client can write some very useful duration-generic code which is robust, even in the face of
yet-to-be-defined custom duration types.  For example here is user-written code which converts
one duration to another using "round to nearest" when the conversion is inexact, and "round
to even" on a tie:
</p>

<blockquote><pre>
template &lt;class TT, long long TPS, long long SPT&gt;
inline
std::duration&lt;TT, TPS, SPT&gt;
abs(std::duration&lt;TT, TPS, SPT&gt; d)
{
    if (d.count() &lt; 0)
        return -d;
    return d;
}

template &lt;class ToDuration, class TT, long long TPS, long long SPT&gt;
ToDuration
round_to_nearest(const std::duration&lt;TT, TPS, SPT&gt;&amp; f)
{
    ToDuration t1 = duration_cast&lt;ToDuration&gt;(f);
    int sign = f.count() &gt;= 0 ? 1 : -1;
    ToDuration t2 = t1 + ToDuration(1) * sign;
    auto d1 = abs(f - t1);
    auto d2 = abs(t2 - f);
    if (d1 == d2)
    {
        if (t1.count() % 2 == 0)
            return t1;
         return t2;
    }
    if (d1 &lt; d2)
        return t1;
    return t2;
}
</pre></blockquote>

<p>
There are several interesting points to note about the above example code:
</p>

<ul>
<li>
It is much easier to write a duration-generic function such as <code>abs</code> due
to the existence of the <code>duration</code> class template.  Without this template
the author of <code>abs</code> would need to create a <code>is_duration</code> trait
or concept, and then constrain the <code>abs</code> function to duration types appropriately.
</li>

<li>
Because of exact comparisons and exact arithmetic, <code>round_to_nearest</code> will
always compile and work, no matter what kinds of durations are thrown at it.
</li>

<li>
If this proposal is not accepted
<code>round_to_nearest&lt;std::milliseconds&gt;(frame_duration(2))</code
> fails to compile because of the subtraction involving types which
won't exactly convert to each other.  If this proposal is accepted, then
<code>round_to_nearest&lt;std::milliseconds&gt;(frame_duration(2))</code
> returns <code>std::milliseconds(67)</code> (<span style="font-size: 80%"><sup>2</sup>&frasl;<sub>30</sub></span> of a second is
exactly 66<span style="font-size: 80%"><sup>2</sup>&frasl;<sub>3</sub></span> milliseconds).
</li>

<li>
Note that the exact type of the result of the <code>duration</code> subtractions is
unimportant to the algorithm.
</li>

<li>
<code>duration_cast</code> is a user written function which implements <code>duration</code>
conversion with round towards zero for inexact conversions.  It turns out this is an often
needed function (even for the standard library implementation) which is approximately 250 lines of code
and easy to get wrong.
</li>
</ul>

<h2><a name="duration_cast"><code>duration_cast</code></a></h2>

<p>
Because <code>duration_cast</code> is an often needed function when working with durations,
and because it is both lengthy and easy to get wrong, we feel that it should be standardized.
Without it, even converting between the standard-defined durations can be tedious and error
prone (and even more so when converting among user-defined durations).  For example, the following code has a subtle bug:
</p>

<blockquote><pre>
std::hours hr = ...;
std::minutes mn = hr.count() * std::hours::seconds_per_tick / std::minutes::seconds_per_tick;
</pre></blockquote>

<p>
The bug is that the above code is susceptible to overflow (on common platforms), even when
<code>hr</code> is within the 292 year range.  The corrected code is:
</p>

<blockquote><pre>
std::minutes mn = hr.count() * (std::hours::seconds_per_tick / std::minutes::seconds_per_tick);
</pre></blockquote>

<p>
The parenthesis reduces the constant multiplier down to a range which will not overflow as long as
<code>hr</code> is within the 292 year limit.  It also increases efficiency as we now have only one integral
multiplication at run time instead of one run time multiplication and one run time division
(the division is exact and done at compile time).
</p>

<p>
However one can not blindly apply parenthesis to every duration
conversion expression.  For example consider converting
in the other direction (<code>minutes</code> to <code>hours</code>).
</p>

<blockquote><pre>
std::hours hr = mn.count() * (std::minutes::seconds_per_tick / std::hours::seconds_per_tick);
</pre></blockquote>

<p>
Now the expression is incorrect <em>with</em> the parentheses.  The above always multiplies
<code>mn.count()</code> by <code>0</code>!  (that's zero-exclamation, not zero-factorial)
</p>

<p>
Dropping the parentheses will yield the correct amount <em>most</em> of the time:
</p>

<blockquote><pre>
std::hours hr = mn.count() * std::minutes::seconds_per_tick / std::hours::seconds_per_tick;
</pre></blockquote>

<p>
However the above expression is again vulnerable to overflow.  The safe (and efficient) expression is:
</p>

<blockquote><pre>
std::hours hr = mn.count() / (std::hours::seconds_per_tick / std::minutes::seconds_per_tick);
</pre></blockquote>

<p>
This drops the expense down to one run time division and avoids the possibility of overflow.
</p>

<p>
It is far easier and less error prone to implement this logic once and for all, and then let
the client simply say:
</p>

<blockquote><pre>
std::hours hr = std::duration_cast&lt;std::hours&gt;(mn);
</pre></blockquote>

<p>
The simplicity of the above expression is readily apparent when you read the specification of
<a href="#duration_cast_spec"><code>duration_cast</code></a>
which consists of nine distinct formulas for computing the conversion.  Each of those nine formulas is designed to
compute the correct conversion with a minimum expense, and a minimum, if not zero, chance of overflow error.
The correct formula is chosen at compile time
and depends only upon the types being converted between, and not the values.
This encapsulation is especially important when writing duration-generic code such as <code>round_to_nearest</code> where
the types of the durations are not known until the algorithm is instantiated.
</p>

<h2><a name="wording">Proposed Wording</a></h2>

<p>
The differences in the proposed wording are written with respect to <a href="n2497.html">N2497</a>.
The changes look large, but they are largely mechanical.  They reduce to a few fundamental steps:
</p>

<ol>
<li>Modify all functions templated on a <code>Duration</code> to instead be templated on
<code>duration&lt;TT, TPS, SPT&gt;</code>.</li>
<li>Replace the <code>Duration</code> requirements with a <code>duration</code> class template.</li>
<li>Replace the classes <code>nanoseonds</code> ... <code>hours</code> with <code>duration typedef</code>s.</li>
<li>Replace <code>FinestDuration</code> with <code>CommonDuration</code>.</li>
<li>Add <code>duration_cast</code>.</li>
<li>Remove the <i>Requires:</i> paragraph from the duration comparison and binary <code>+</code> and <code>-</code>
operators.</li>
<li>Remove any wording associated with constraining the <code>Duration</code> template parameter.</li>
</ol>

<p>
The resulting specification is actually smaller (more text is removed than is added).
</p>

<h4>30.1.1 Template Parameter Names [thread.tmplparmname]</h4>

<p>
Throughout this clause,
the names of template parameters are used to express type requirements.
</p>

<p>
<del>The requirements for Duration parameters are specified in
chapter 31 [time].</del>
</p>

<h4>30.1.4 Timing Specifications [thread.timing_specifications]</h4>

<p>
Several functions described in this clause
take an argument to specify a timeout.
These timeouts are specified as either a <del>D</del><ins>d</ins>uration or a Time Point type
as specified in [time].
</p>

<h3>30.2 Threads [thread.threads]</h3>

<p>
...
</p>

<p>
<strong>&lt;thread&gt; synopsis</strong>
</p>

<blockquote>
<pre><code>
namespace std {

...

namespace this_thread
{
    ...
    void sleep(const system_time&amp; <var>abs_t</var>);
    template &lt;class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
        void sleep(const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>rel_t</var>);

}  // this_thread

}  // std
</code></pre>
</blockquote>

<h4>30.2.2 Namespace <code>this_thread</code> [thread.threads.this]</h4>

<blockquote>
<pre><code>
namespace this_thread {

...
void sleep(const system_time&amp; <var>abs_t</var>);
template &lt;class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
    void sleep(const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>rel_t</var>);

}  // this_thread
</code></pre>
</blockquote>

<p>...</p>

<pre><code>
template &lt;class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
    void sleep(const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>rel_t</var>);
</code></pre>

<blockquote>
<dl>
<dt>Effects:</dt>
<dd>
The current thread blocks for at least the amount of time specified.
If the resolution of <code><del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins></code>
is finer than the native
resolution, the time is rounded to the next larger value that can be
represented in the native resolution.
</dd>

<dt>Synchronization:</dt>
<dd>
None.
</dd>

<dt>Throws:</dt>
<dd>
Nothing.
</dd>
</dl>
</blockquote>

<h4>30.3.2 TimedMutex requirements [thread.timedmutex.requirements]</h4>

<p>
To meet the TimedMutex requirements,
types shall meet the Mutex requirements.
In addition, the following requirements shall be met,
where <code>rel_time</code>
denotes a value of <del>a</del> type <del>meeting the D</del><ins>d</ins>uration ([time.duration])
<del>requirements</del>
or <code>abs_time</code>
denotes a value of type <code>system_time</code>:
</p>

<p>...</p>

<blockquote>
<dl>
<dt>Precondition:</dt>
<dd>
If the resolution of <ins>the</ins> <code><del>D</del><ins>d</ins>uration</code>
is finer than the native resolution,
the time is rounded up to the nearest native resolution.
</dd>
<p>...</p>
</dl>
</blockquote>

<h5>30.3.2.1 Class timed_mutex [thread.timed.class]</h5>

<blockquote>
<pre><code>
namespace std {

class timed_mutex
{
public:
    timed_mutex();
    ~timed_mutex();

    timed_mutex(const timed_mutex&amp;) = delete;
    timed_mutex&amp; operator=(const timed_mutex&amp;) = delete;

    void lock();
    bool try_lock();
    template &lt;class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
        bool timed_lock(const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; rel_time);
    bool timed_lock(const system_time&amp; abs_time);
    void unlock();

    typedef <var><strong>implementation-defined</strong></var> native_handle_type;  // <em>See [thread.native]</em>
    native_handle_type native_handle();                // <em>See [thread.native]</em>
};

}  // std
</code></pre>
</blockquote>

<h5>30.3.2.2 Class recursive_timed_mutex [thread.timed.recursive]</h5>

<blockquote>
<pre><code>
namespace std {

class recursive_timed_mutex
{
public:
    recursive_timed_mutex();
    ~recursive_timed_mutex();

    recursive_timed_mutex(const recursive_timed_mutex&amp;) = delete;
    recursive_timed_mutex&amp; operator=(const recursive_timed_mutex&amp;) = delete;

    void lock();
    bool try_lock();
    template &lt;class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
        bool timed_lock(const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; rel_time);
    bool timed_lock(const system_time&amp; abs_time);
    void unlock();

    typedef <var><strong>implementation-defined</strong></var> native_handle_type;  // <em>See [thread.native]</em>
    native_handle_type native_handle();                // <em>See [thread.native]</em>
};

}  // std
</code></pre>
</blockquote>

<h5><a name="thread.lock.unique">30.3.3.2 Class unique_lock [thread.lock.unique]</a></h5>

<blockquote>
<pre><code>
namespace std {

template &lt;class Mutex&gt;
class unique_lock
{
public:
    typedef Mutex mutex_type;

    unique_lock();
    explicit unique_lock(mutex_type&amp; <var>m</var>);
    unique_lock(mutex_type&amp; <var>m</var>, defer_lock_t);
    unique_lock(mutex_type&amp; <var>m</var>, try_to_lock_t);
    unique_lock(mutex_type&amp; <var>m</var>, adopt_lock_t);
    unique_lock(mutex_type&amp; <var>m</var>, const system_time&amp; <var>abs_time</var>);
    template &lt;class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
        unique_lock(mutex_type&amp; <var>m</var>, const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>rel_time</var>);
    ~unique_lock();

    unique_lock(unique_lock const&amp;) = delete;
    unique_lock&amp; operator=(unique_lock const&amp;) = delete;

    unique_lock(unique_lock&amp;&amp; <var>u</var>);
    unique_lock&amp; operator=(unique_lock&amp;&amp; <var>u</var>);

    void lock();
    bool try_lock();

    template &lt;class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
        bool timed_lock(const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>rel_t</var>);
    bool timed_lock(const system_time&amp; abs_time);

    void unlock();

    bool owns_lock() const;
    explicit operator bool () const;
    mutex_type* mutex() const;

    void swap(unique_lock&amp;&amp; <var>u</var>);
    mutex_type* release();

private:
    mutex_type* pm;  // for exposition only
    bool owns;       // for exposition only
};

...

}  // std
</code></pre>
</blockquote>

<p>...</p>

<pre><code>
template &lt;class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
  unique_lock(mutex_type&amp; <var>m</var>, const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>rel_time</var>);
</code></pre>

<blockquote>
<dl>
<dt><del>Remarks:</del></dt>
<dd>
<del>The implementation shall ensure that only <code>Duration</code> types ([time])
will bind to this constructor.</del>
</dd>
</dl>
</blockquote>

<blockquote>
<dl>
<dt>Precondition:</dt>
<dd>
If <code>mutex_type</code> is not a recursive mutex, then the current thread
does not own the mutex.
</dd>

<dt>Effects:</dt>
<dd>
Constructs an object of type <code>unique_lock</code>
and calls <code><var>m</var>.timed_lock(<var>rel_time</var>)</code>.
</dd>

<dt>Postconditions:</dt>
<dd>
<code><var>pm</var> == &amp;<var>m</var></code>
<br>
<code><var>owns</var> ==</code>
the result of the call to
<code><var>m</var>.timed_lock(<var>rel_time</var>)</code>
</dd>

<dt>Throws:</dt>
<dd>
Nothing.
</dd>
</dl>
</blockquote>

<p>...</p>

<pre><code>
template &lt;class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
   bool timed_lock(const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>rel_t</var>);
</code></pre>

<blockquote>
<dl>
<dt>Effects:</dt>
<dd>
<code><var>pm</var>-&gt;timed_lock(<var>rel_t</var>)</code>.
</dd>

<dt>Returns:</dt>
<dd>
The result of the call to <code>timed_lock(<var>rel_t</var>)</code>.
</dd>

<dt>Postconditions:</dt>
<dd>
<code><var>owns</var> == </code>
the result
of the call to <code>timed_lock(<var>rel_t</var>)</code>.
</dd>

<dt>Throws:</dt>
<dd>
<code>lock_error</code>,
if on entry <code><var>owns</var></code> is <code>true</code>
or if <code><var>pm</var> == 0</code>.
</dd>
</dl>
</blockquote>

<h4>30.4.1 Class condition_variable [thread.condvar]</h4>

<blockquote>
<pre><code>
namespace std {

class condition_variable
{
public:

    condition_variable();
    ~condition_variable();

    condition_variable(const condition_variable&amp;) = delete;
    condition_variable&amp; operator=(const condition_variable&amp;) = delete;

    void notify_one();
    void notify_all();
    void wait(unique_lock&lt;mutex&gt;&amp; <var>lock</var>);
    template &lt;class Predicate&gt;
        void wait(unique_lock&lt;mutex&gt;&amp; <var>lock</var>, Predicate <var>pred</var>);
    template &lt;class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
        bool timed_wait(unique_lock&lt;mutex&gt;&amp; <var>lock</var>, const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>rel_time</var>);
    bool timed_wait(unique_lock&lt;mutex&gt;&amp; <var>lock</var>, const system_time&amp; <var>abs_time</var>);
    template &lt;class Predicate&gt;
        bool timed_wait(unique_lock&lt;mutex&gt;&amp; <var>lock</var>, const system_time&amp; <var>abs_time</var>,
                        Predicate <var>pred</var>);
    template &lt;class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>, class Predicate&gt;
        bool timed_wait(unique_lock&lt;mutex&gt;&amp; <var>lock</var>, const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>rel_time</var>,
                        Predicate <var>pred</var>);

    typedef <var><strong>implementation-defined</strong></var> native_handle_type;  // <em>See [thread.native]</em>
    native_handle_type native_handle();                // <em>See [thread.native]</em>
};

}  // std
</code></pre>
</blockquote>

<p>...</p>

<pre><code>
template &lt;class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
    bool timed_wait(unique_lock&lt;mutex&gt;&amp; <var>lock</var>, const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>rel_time</var>);
</code></pre>

<blockquote>
<dl>
<dt>Effects:</dt>
<dd>
<p>
As if:
</p>

<blockquote>
<pre><code>
timed_wait(<var>lock</var>, get_current_time() + <var>rel_time</var>)
</code></pre>
</blockquote>
</dd>

<dt>Returns:</dt>
<dd>
<code>false</code> if the call is returning
because the time duration specified by
<code>rel_time</code> has elapsed, <code>true</code> otherwise.
</dd>

</dl>
</blockquote>

<p>...</p>

<pre><code>
template &lt;class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>, class Predicate&gt;
    bool timed_wait(unique_lock&lt;mutex&gt;&amp; <var>lock</var>, const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>rel_time</var>,
                    Predicate <var>pred</var>);
</code></pre>

<h4>30.4.2 Class condition_variable_any [thread.condvarany]</h4>

<blockquote>
<pre><code>
namespace std {

class condition_variable_any
{
public:
    condition_variable_any();
    ~condition_variable_any();

    condition_variable_any(const condition_variable_any&amp;) = delete;
    condition_variable_any&amp; operator=(const condition_variable_any&amp;) = delete;

    void notify_one();
    void notify_all();
    template &lt;class Lock&gt;
        void wait(Lock&amp; <var>lock</var>);
    template &lt;class Lock, class Predicate&gt;
        void wait(Lock&amp; <var>lock</var>, Predicate <var>pred</var>);
    template &lt;class Lock&gt;
        bool timed_wait(Lock&amp; <var>lock</var>, const system_time&amp; <var>abs_time</var>);
    template &lt;class Lock, class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
        bool timed_wait(Lock&amp; <var>lock</var>, const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>rel_time</var>);
    template &lt;class Lock, class Predicate&gt;
        bool timed_wait(Lock&amp; <var>lock</var>, const system_time&amp; <var>abs_time</var>,
                        Predicate <var>pred</var>);
    template &lt;class Lock, class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>, class Predicate&gt;
        bool timed_wait(Lock&amp; <var>lock</var>, const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>rel_time</var>, Predicate <var>pred</var>);

    typedef <var><strong>implementation-defined</strong></var> native_handle_type;  // <em>See [thread.native]</em>
    native_handle_type native_handle();                // <em>See [thread.native]</em>
};

}  // std
</code></pre>
</blockquote>

<p>...</p>

<pre><code>
template &lt;class Lock, class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
    bool timed_wait(Lock&amp; <var>lock</var>, const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>rel_time</var>);
</code></pre>

<p>...</p>

<pre><code>
template &lt;class Lock, class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>, class Predicate&gt;
    bool timed_wait(Lock&amp; <var>lock</var>, const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>rel_time</var>, Predicate <var>pred</var>);
</code></pre>

<h2>Chapter 31&nbsp;&nbsp; Date Time Library [time]</h2>

<p>...</p>

<p>
<del>Throughout this clause,
the names of template parameters are used to express type requirements.
Parameter names
<code>Duration</code>, <code>LhsDuration</code> and <code>RhsDuration</code>
express the Duration requirements ([time.duration.requirements]).
For all non-member functions in this clause
that are templated on Duration types,
the implementation shall constrain these function templates such that they will
only instantiate for Duration types.</del>
</p>

<p>
The <code><del>D</del><ins>d</ins>uration</code> types shall represent durations
of at least &plusmn; 292 years.
The <code>system_time</code> type shall represent times
at least within the range epoch + 292 years.
</p>

<p>
<strong>Header &lt;date_time&gt; Synopsis</strong>
</p>

<blockquote>
<pre><code>
namespace std {

// <em>duration <del>types</del></em>
<ins>template &lt;class TickType, long long TicksPerSecond, long long SecondsPerTick&gt; class duration;</ins>

<del>class</del> <ins>typedef duration&lt;int_least64_t, 1000L * 1000 * 1000,    0&gt;</ins> nanoseconds;
<del>class</del> <ins>typedef duration&lt;int_least55_t,        1000L * 1000,    0&gt;</ins> microseconds;
<del>class</del> <ins>typedef duration&lt;int_least45_t,                1000,    0&gt;</ins> milliseconds;
<del>class</del> <ins>typedef duration&lt;int_least35_t,                   1,    1&gt;</ins> seconds;
<del>class</del> <ins>typedef duration&lt;int_least29_t,                   0,   60&gt;</ins> minutes;
<del>class</del> <ins>typedef duration&lt;int_least23_t,                   0, 3600&gt;</ins> hours;

<ins>template &lt;class ToDuration, class TT, long long TPS, long long SPT&gt;
  ToDuration duration_cast(const duration&lt;TT, TPS, SPT&gt;&amp; fd);</ins>

// <em>timepoint type</em>
class system_time;

// <em>non-member functions ([time.nonmembers])</em>
system_time get_system_time();

template&lt;typename <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
  system_time operator+(const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>td</var>, const system_time&amp; <var>rhs</var>);

template &lt;class <del>LhsDuration</del> <ins>TT1, long long TPS1, long long SPT1</ins>, class <del>RhsDuration</del> <ins>TT2, long long TPS2, long long SPT2</ins>&gt;
  bool operator==(const <del>LhsD</del><ins>d</ins>uration<ins>&lt;TT1, TPS1, SPT1&gt;</ins>&amp; <var>lhs</var>, const <del>RhsD</del><ins>d</ins>uration<ins>&lt;TT2, TPS2, SPT2&gt;</ins>&amp; <var>rhs</var>);
template &lt;class <del>LhsDuration</del> <ins>TT1, long long TPS1, long long SPT1</ins>, class <del>RhsDuration</del> <ins>TT2, long long TPS2, long long SPT2</ins>&gt;
  bool operator!=(const <del>LhsD</del><ins>d</ins>uration<ins>&lt;TT1, TPS1, SPT1&gt;</ins>&amp; <var>lhs</var>, const <del>RhsD</del><ins>d</ins>uration<ins>&lt;TT2, TPS2, SPT2&gt;</ins>&amp; <var>rhs</var>);

template &lt;class <del>LhsDuration</del> <ins>TT1, long long TPS1, long long SPT1</ins>, class <del>RhsDuration</del> <ins>TT2, long long TPS2, long long SPT2</ins>&gt;
  bool operator&lt; (const <del>LhsD</del><ins>d</ins>uration<ins>&lt;TT1, TPS1, SPT1&gt;</ins>&amp; <var>lhs</var>, const <del>RhsD</del><ins>d</ins>uration<ins>&lt;TT2, TPS2, SPT2&gt;</ins>&amp; <var>rhs</var>);
template &lt;class <del>LhsDuration</del> <ins>TT1, long long TPS1, long long SPT1</ins>, class <del>RhsDuration</del> <ins>TT2, long long TPS2, long long SPT2</ins>&gt;
  bool operator&lt;=(const <del>LhsD</del><ins>d</ins>uration<ins>&lt;TT1, TPS1, SPT1&gt;</ins>&amp; <var>lhs</var>, const <del>RhsD</del><ins>d</ins>uration<ins>&lt;TT2, TPS2, SPT2&gt;</ins>&amp; <var>rhs</var>);
template &lt;class <del>LhsDuration</del> <ins>TT1, long long TPS1, long long SPT1</ins>, class <del>RhsDuration</del> <ins>TT2, long long TPS2, long long SPT2</ins>&gt;
  bool operator&gt; (const <del>LhsD</del><ins>d</ins>uration<ins>&lt;TT1, TPS1, SPT1&gt;</ins>&amp; <var>lhs</var>, const <del>RhsD</del><ins>d</ins>uration<ins>&lt;TT2, TPS2, SPT2&gt;</ins>&amp; <var>rhs</var>);
template &lt;class <del>LhsDuration</del> <ins>TT1, long long TPS1, long long SPT1</ins>, class <del>RhsDuration</del> <ins>TT2, long long TPS2, long long SPT2</ins>&gt;
  bool operator&gt;=(const <del>LhsD</del><ins>d</ins>uration<ins>&lt;TT1, TPS1, SPT1&gt;</ins>&amp; <var>lhs</var>, const <del>RhsD</del><ins>d</ins>uration<ins>&lt;TT2, TPS2, SPT2&gt;</ins>&amp; <var>rhs</var>);

template &lt;class <del>LhsDuration</del> <ins>TT1, long long TPS1, long long SPT1</ins>, class <del>RhsDuration</del> <ins>TT2, long long TPS2, long long SPT2</ins>&gt;
  <var><del>Finest</del><ins>Common</ins>Duration</var> operator+(const <del>LhsD</del><ins>d</ins>uration<ins>&lt;TT1, TPS1, SPT1&gt;</ins>&amp; <var>lhs</var>, const <del>RhsD</del><ins>d</ins>uration<ins>&lt;TT2, TPS2, SPT2&gt;</ins>&amp; <var>rhs</var>)
template &lt;class <del>LhsDuration</del> <ins>TT1, long long TPS1, long long SPT1</ins>, class <del>RhsDuration</del> <ins>TT2, long long TPS2, long long SPT2</ins>&gt;
  <var><del>Finest</del><ins>Common</ins>Duration</var> operator-(const <del>LhsD</del><ins>d</ins>uration<ins>&lt;TT1, TPS1, SPT1&gt;</ins>&amp; <var>lhs</var>, const <del>RhsD</del><ins>d</ins>uration<ins>&lt;TT2, TPS2, SPT2&gt;</ins>&amp; <var>rhs</var>)

template &lt;class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
  <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins> operator*(<del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins> <var>lhs</var>, long <var>rhs</var>)
template &lt;class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
  <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins> operator*(long <var>lhs</var>, <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins> <var>rhs</var>)

template &lt;class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
  <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins> operator/(<del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins> <var>lhs</var>, long <var>rhs</var>)
}  // std
</code></pre>
</blockquote>

<p><ins>
The use of the <code>int_leastN_t</code> types above does not indicate the existence of these <code>typedef</code>s.
This use indicates that the type chosen by the implementation must be a signed integral type of at least the size
indicated.
</ins></p>

<p>
<del>Through this clause, type <code><var>FinestDuration</var></code>
is whichever of <code>LhsDuration</code> or <code>RhsDuration</code>
has the finest resolution.
If their resolutions are the same,
<code><var>FinestDuration </var></code>is <code>LhsDuration</code>.</del>
</p>

<p><ins>
The <code>CommonDuration</code> type of <code>duration&lt;T1, TPS1, SPT1&gt;</code> and
<code>duration&lt;T2, TPS2, SPT2&gt;</code> is:
</ins></p>

<ul>
<li><ins>
If <code>duration&lt;T2, TPS2, SPT2&gt;</code> is exactly convertible to
<code>duration&lt;T1, TPS1, SPT1&gt;</code>, then the <code>CommonDuration</code> type
is <code>duration&lt;T1, TPS1, SPT1&gt;</code>.
</ins></li>

<li><ins>
Else if <code>duration&lt;T1, TPS1, SPT1&gt;</code> is exactly convertible to
<code>duration&lt;T2, TPS2, SPT2&gt;</code>, then the <code>CommonDuration</code> type
is <code>duration&lt;T2, TPS2, SPT2&gt;</code>.
</ins></li>

<li><ins>
Else if <code>duration&lt;T1, TPS1, SPT1&gt;</code> and <code>duration&lt;T2, TPS2, SPT2&gt;</code>
are both non-subsecond <code>duration</code>s, then the <code>CommonDuration</code> type is
<code>duration&lt;T, TPS, SPT&gt;</code> where <code>SPT</code> is the
greatest common divisor of <code>SPT1</code> and <code>SPT2</code>, <code>TPS</code> is equal
to <code>SPT == 1</code>, and <code>T</code> is a signed integral type capable of representing a
&plusmn; 292 year range.  If the values <code>TPS</code> and <code>SPT</code>
correspond to a standard-defined duration, then <code>T</code> shall be the same type as the
<code>tick_type</code> of that standard-defined duration.
</ins></li>

<li><ins>
Else <code>duration&lt;T1, TPS1, SPT1&gt;</code> and <code>duration&lt;T2, TPS2, SPT2&gt;</code>
are both subsecond <code>duration</code>s.
The <code>CommonDuration</code> type is <code>duration&lt;T, TPS, SPT&gt;</code> where
<code>TPS</code> is the least common multiple of <code>TPS1</code> and <code>TPS2</code>,
and <code>SPT</code> is <code>0</code>.  If <code>TPS1 &lt; TPS2</code>, <code>T</code> has the same type as
<code>duration&lt;T2, TPS2, SPT2&gt;::tick_type</code>, else <code>T</code> has the same type as
<code>duration&lt;T1, TPS1, SPT1&gt;::tick_type</code>.
</ins></li>
</ul>

<p><ins>
[<i>Note:</i> Both <code>duration&lt;T1, TPS1, SPT1&gt;</code> and <code>duration&lt;T2, TPS2, SPT2&gt;</code>
are exactly convertible to their <code>CommonDuration</code> type. --<i>end note</i>]
</ins></p>

<h3>31.1 <del>Duration requirements</del> <ins>Class template <code>duration</code></ins> [time.duration<del>.requirements</del>]</h3>

<p>
This subclause describes <del>requirements on duration types used to instantiate
templates defined</del>
<ins>the class template <code>duration</code> used to represent time durations</ins>
in the C++ Standard Library.
</p>

<p>
Objects of duration types provide time length values
which can be positive or negative.
Duration types provide comparison and arithmetic operations on those values.
</p>

<p><del>
Template definitions in the C++ Standard Library refer to the named Duration
requirements for duration types whose details are specified below.
</del></p>

<p>
A duration type <code>E</code> is said to be <i>exactly convertible</i>
to another duration type <code>D</code> if and only if:
</p>

<ul>
<li>
<code>E::is_subsecond</code> is <code>false</code> and 
<code>D::is_subsecond</code> is <code>true</code>, or
</li>
<li>
<code>E::is_subsecond</code> is <code>false</code> and 
<code>D::is_subsecond</code> is <code>false</code> and
<code>E::seconds_per_tick % D::seconds_per_tick == 0</code> , or
</li>
<li>
<code>E::is_subsecond</code> is <code>true</code> and 
<code>D::is_subsecond</code> is <code>true</code> and
<code>D::ticks_per_second % E::ticks_per_second == 0</code>.
</li>
</ul>

<p><del>
A duration type shall be EqualityComparable, LessThanComparable,
CopyConstructible, DefaultConstructible, CopyAssignable, Swappable, and
Destructible.
In addition, it must meet the requirements
for well-formed expressions specified in the following table,
where <code>D</code> and <code>E</code> are duration types,
<code>d</code> denotes a value of type <code>D</code>,
<code>d0</code> denotes <code>d.tick_count()</code> at entry into the function,
<code>e</code> denotes a <code>const</code> value of type <code>E</code>,
<code>c</code> denotes a <code>long</code> value.
<code>E</code> shall be exactly convertible to <code>D</code> (diagnostic required).
</del></p>

<p>Remove this table:</p>
<table>
  <tr>
    <th>expression</th>
    <th>return type</th>
    <th>return value</th>
  </tr>
  <tr>
    <td valign="top"><code>D::tick_type</code></td>
    <td valign="top"><var><strong>implementation defined</strong></var></td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td valign="top"><code>D::ticks_per_second</code></td>
    <td valign="top"><code>D::tick_type</code></td>
    <td valign="top">The number of ticks per second,
    or 0 for types for which the number of ticks per second is less than 1.</td>
  </tr>
  <tr>
    <td valign="top"><code>D::seconds_per_tick</code></td>
    <td valign="top"><code>D::tick_type</code></td>
    <td valign="top">The number of seconds per tick,
    or 0 for types for which the number of seconds per tick is less than 1.</td>
  </tr>
  <tr>
    <td valign="top"><code>D::is_subsecond</code></td>
    <td valign="top"><code>bool</code></td>
    <td valign="top"><code>seconds_per_tick == 0</code></td>
  </tr>
  <tr>
    <td valign="top"><code>d.count()</code></td>
    <td valign="top"><code>D::tick_type</code></td>
    <td valign="top">The most recent value established by a
    non-const function's postcondition.</td>
  </tr>
  <tr>
    <td valign="top"><code>-d</code></td>
    <td valign="top"><code>D</code></td>
    <td valign="top"><code>D(-d.tick_count())</code></td>
  </tr>
  <tr>
    <th>&nbsp;</th>
    <th>&nbsp;</th>
    <th>postcondition</th>
  </tr>
  <tr>
    <td valign="top"><code>d -= e</code></td>
    <td valign="top"><code>D&amp;</code></td>
    <td valign="top"><code>d.tick_count() ==
    d0 - x</code>,
    where <code>x</code> is <code>e.tick_count()</code>
    converted to the resolution of <code>D</code>.</td>
  </tr>
  <tr>
    <td valign="top"><code>d += e</code></td>
    <td valign="top"><code>D&amp;</code></td>
    <td valign="top"><code>d.tick_count() == d0 + x</code>,
    where <code>x</code> is <code>e.tick_count()</code>
    converted to the resolution of <code>D</code>.</td>
  </tr>
  <tr>
    <td valign="top"><code>d /= c</code></td>
    <td valign="top"><code>D&amp;</code></td>
    <td valign="top"><code>d.tick_count() == d0 / c</code></td>
  </tr>
  <tr>
    <td valign="top"><code>d *= c</code></td>
    <td valign="top"><code>D&amp;</code></td>
    <td valign="top"><code>d.tick_count()
    ==  d0 * c</code></td>
  </tr>
</table>

<blockquote><pre><ins>
template &lt;class TickType, long long TicksPerSecond, long long SecondsPerTick&gt;
class duration
{
    TickType <var>ticks</var>;  // exposition only
public:
    // traits information
    typedef TickType tick_type;
    static const long long ticks_per_second = TicksPerSecond;
    static const long long seconds_per_tick = SecondsPerTick;
    static const bool is_subsecond = seconds_per_tick == 0;

    static_assert(ticks_per_second &gt;  1 &amp;&amp; seconds_per_tick == 0 ||
                  ticks_per_second == 0 &amp;&amp; seconds_per_tick &gt;  1 ||
                  ticks_per_second == 1 &amp;&amp; seconds_per_tick == 1,
                  "duration has inconsistent type");

    duration();
    duration(const tick_type&amp; <var>tick</var>);

    // conversions
    template &lt;class TT, long long TPS, long long SPT&gt;
      duration(const duration&lt;TT, TPS, SPT&gt;&amp; <var>d</var>);

    // observer

    tick_type count() const;

    // arithmetic

    template &lt;class TT, long long TPS, long long SPT&gt;
      duration&amp;
      operator-=(const duration&lt;TT, TPS, SPT&gt;&amp; <var>d</var>);

    template &lt;class TT, long long TPS, long long SPT&gt;
      duration&amp;
      operator+=(const duration&lt;TT, TPS, SPT&gt;&amp; <var>d</var>);

    duration operator-() const;

    duration&amp; operator*=(tick_type <var>rhs</var>);
    duration&amp; operator/=(tick_type <var>rhs</var>);
};
</ins></pre></blockquote>

<p><ins>
The template parameter <code>TickType</code> must behave as an arithmetic type (supporting binary <code>+</code>,
<code>-</code>, <code>*</code>, <code>/</code>, unary <code>-</code>, the compound assignment operators <code>+=</code>,
<code>-=</code>, <code>*=</code>, <code>/=</code>, support all six comparison operators) and be explicitly convertible
to and from <code>long long</code>.
</ins></p>

<pre><code><ins>
duration();
</ins></code></pre>

<blockquote>
<dl>
<dt><ins>Effects:</ins></dt>
<dd>
<ins>Default constructs an object of type <code>duration</code>.</ins>
</dd>

<dt><ins>Postcondition:</ins></dt>
<dd>
<ins><code>count() == tick_type();</code></ins>
</dd>
</dl>
</blockquote>

<pre><code><ins>
duration(const tick_type&amp; <var>t</var>);
</ins></code></pre>

<blockquote>
<dl>
<dt><ins>Effects:</ins></dt>
<dd>
<ins>Constructs an object of type <code>duration</code>.</ins>
</dd>

<dt><ins>Postcondition:</ins></dt>
<dd>
<ins><code>count() == <var>t</var>;</code></ins>
</dd>
</dl>
</blockquote>

<pre><code><ins>
template &lt;class TT, long long TPS, long long SPT&gt;
  duration(const duration&lt;TT, TPS, SPT&gt;&amp; <var>d</var>);
</ins></code></pre>

<blockquote>

<dl>
<dt><ins>Requires:</ins></dt>
<dd>
<ins><code>duration&lt;TT, TPS, SPT&gt;</code> is exactly convertible to this <code>duration</code> type (diagnostic required).</ins>
</dd>

<dt><ins>Effects:</ins></dt>
<dd>
<ins>Constructs an object of type <code>duration</code>.</ins>
</dd>

<dt><ins>Postcondition:</ins></dt>
<dd>
<ins><code>count() == duration_cast&lt;duration&gt;(<var>d</var>).count()</code></ins>
</dd>
</dl>
</blockquote>

<pre><code><ins>
tick_type count() const;
</ins></code></pre>

<blockquote>

<dl>
<dt><ins>Returns:</ins></dt>
<dd>
<ins><code><var>ticks</var></code></ins>
</dd>

</dl>
</blockquote>

<pre><code><ins>
template &lt;class TT, long long TPS, long long SPT&gt;
  duration&amp;
  operator-=(const duration&lt;TT, TPS, SPT&gt;&amp; <var>d</var>);
</ins></code></pre>

<blockquote>
<dl>
<dt><ins>Requires:</ins></dt>
<dd>
<ins><code>duration&lt;TT, TPS, SPT&gt;</code> is exactly convertible to this <code>duration</code> type (diagnostic required).</ins>
</dd>

<dt><ins>Effects:</ins></dt>
<dd>
<ins><code><var>ticks</var> -= duration_cast&lt;duration&gt;(<var>d</var>).count()</code>.</ins>
</dd>

<dt><ins>Returns:</ins></dt>
<dd>
<ins><code>*this</code>.</ins>
</dd>

</dl>
</blockquote>

<pre><code><ins>
template &lt;class TT, long long TPS, long long SPT&gt;
  duration&amp;
  operator+=(const duration&lt;TT, TPS, SPT&gt;&amp; <var>d</var>);
</ins></code></pre>

<blockquote>

<dl>
<dt><ins>Requires:</ins></dt>
<dd>
<ins><code>duration&lt;TT, TPS, SPT&gt;</code> is exactly convertible to this <code>duration</code> type (diagnostic required).</ins>
</dd>

<dt><ins>Effects:</ins></dt>
<dd>
<ins><code><var>ticks</var> += duration_cast&lt;duration&gt;(<var>d</var>).count()</code>.</ins>
</dd>

<dt><ins>Returns:</ins></dt>
<dd>
<ins><code>*this</code>.</ins>
</dd>

</dl>
</blockquote>

<pre><code><ins>
duration operator-() const;
</ins></code></pre>

<blockquote>

<dl>
<dt><ins>Returns:</ins></dt>
<dd>
<ins><code>-<var>ticks</var></code>.</ins>
</dd>

</dl>
</blockquote>

<pre><code><ins>
duration&amp; operator*=(tick_type <var>rhs</var>);
</ins></code></pre>

<blockquote>

<dl>
<dt><ins>Effects:</ins></dt>
<dd>
<ins><code><var>ticks</var> *= <var>rhs</var></code>.</ins>
</dd>

<dt><ins>Returns:</ins></dt>
<dd>
<ins><code>*this</code>.</ins>
</dd>

</dl>
</blockquote>

<pre><code><ins>
duration&amp; operator/=(tick_type <var>rhs</var>);
</ins></code></pre>

<blockquote>

<dl>
<dt><ins>Effects:</ins></dt>
<dd>
<ins><code><var>ticks</var> /= <var>rhs</var></code>.</ins>
</dd>

<dt><ins>Returns:</ins></dt>
<dd>
<ins><code>*this</code>.</ins>
</dd>

</dl>
</blockquote>

<p>
Remove section 31.2 Class nanoseconds [time.nanoseconds].
</p>

<p>
Remove section 31.3 Class microseconds [time.microseconds].
</p>

<p>
Remove section 31.4 Class milliseconds [time.milliseconds].
</p>

<p>
Remove section 31.5 Class seconds [time.seconds].
</p>

<p>
Remove section 31.6 Class minutes [time.minutes].
</p>

<p>
Remove section 31.7 Class hours [time.hours].
</p>

<p>
Add section 31.2 <code>duration_cast</code> [duration.cast]
</p>

<h3><a name="duration_cast_spec"></a>31.2 <code>duration_cast</code> [duration.cast]</h3>

<pre><code>
template &lt;class To, class TT, long long TPS, long long SPT&gt;
  To duration_cast(const duration&lt;TT, TPS, SPT&gt;&amp; fd);
</code></pre>

<blockquote>

<dl>
<dt>Requires:</dt>
<dd>
<code>To</code> is a <code>duration</code>.
</dd>

<dt>Effects:</dt>
<dd><p>
Converts <code>duration&lt;TT, TPS, SPT&gt;</code> to <code>To</code> either exactly, or if the
conversion is inexact, rounds according to the rules for division of the <code>tick_type</code> being used
for the conversion (typically round towards zero when converting among standard-defined duration types).
The computation is done using the <code>tick_type</code>
of the duration of finer resolution among <code>To</code> and <code>duration&lt;TT, TPS, SPT&gt;</code>.
If <code>duration&lt;TT, TPS, SPT&gt;</code> is exactly convertible to <code>To</code>, but not vice-versa,
exactly one multiplication is used for the conversion.
If <code>To</code> is exactly convertible to <code>duration&lt;TT, TPS, SPT&gt;</code>, but not vice-versa,
exactly one division is used for the conversion.
If <code>duration&lt;TT, TPS, SPT&gt;</code> is exactly convertible to <code>To</code>, and vice-versa,
<code>fd.count()</code> is simply explicitly converted to <code>To::tick_type</code> and used to
construct the result.
If neither <code>duration&lt;TT, TPS, SPT&gt;</code> is exactly convertible to <code>To</code>, nor vice-versa,
one multiplication and one division is used for the conversion.  In this case the constants used in the conversion
are first reduced to a minimum value in order to reduce the chances of overflow.
Only explicit conversions are used between <code>To::tick_type</code>
and <code>duration&lt;TT, TPS, SPT&gt;::tick_type</code>.
</p></dd>

<dt>Returns:</dt>
<dd>
<p>
In the following table, <code>FinerTickType</code> is the same type as <code>duration&lt;TT, TPS, SPT&gt;::tick_type</code>
if the resolution of <code>duration&lt;TT, TPS, SPT&gt;</code> is finer than the resolution of <code>To</code>,
else <code>FinerTickType</code> is the same type as <code>To::tick_type</code>.  <code>From</code> is the same type as
<code>duration&lt;TT, TPS, SPT&gt;</code>.
<code>GCD_SPT</code> is an integral constant with the value of the greatest common divisor of
<code>duration&lt;TT, TPS, SPT&gt;::seconds_per_tick</code> and <code>To::seconds_per_tick</code>.
<code>GCD_TPS</code> is an integral constant with the value of the greatest common divisor of
<code>duration&lt;TT, TPS, SPT&gt;::ticks_per_second</code> and <code>To::ticks_per_second</code>.
</p>

<table>
<caption><code>duration_cast</code> return value</caption>
<tr>
<th><code>From:: is_subsecond</code></th>
<th><code>To::<br/>is_subsecond</code></th>
<th><code>From</code> is<br/>exactly<br/>convertible<br/>to <code>To</code></th>
<th><code>To</code> is<br/>exactly<br/>convertible<br/>to <code>From</code></th>
<th>Comments / Returns:</th>
</tr>

<tr>
<td><code>false</code></td>
<td><code>false</code></td>
<td><code>false</code></td>
<td><code>false</code></td>
<td><code>static_cast&lt;typename To::tick_type&gt;(<br/>
static_cast&lt;FinerTickType&gt;(fd.count())*<br/>
static_cast&lt;FinerTickType&gt;(From::seconds_per_tick/GCD_SPT)/<br/>
static_cast&lt;FinerTickType&gt;(To::seconds_per_tick/GCD_SPT))
</code></td>
</tr>

<tr>
<td><code>false</code></td>
<td><code>false</code></td>
<td><code>false</code></td>
<td><code>true</code></td>
<td><code>static_cast&lt;typename To::tick_type&gt;(<br/>
static_cast&lt;FinerTickType&gt;(fd.count())/<br/>
static_cast&lt;FinerTickType&gt;(To::seconds_per_tick/From::seconds_per_tick))
</code></td>
</tr>

<tr>
<td><code>false</code></td>
<td><code>false</code></td>
<td><code>true</code></td>
<td><code>false</code></td>
<td><code>static_cast&lt;typename To::tick_type&gt;(<br/>
static_cast&lt;FinerTickType&gt;(fd.count())*<br/>
static_cast&lt;FinerTickType&gt;(From::seconds_per_tick/To::seconds_per_tick))
</code></td>
</tr>

<tr>
<td><code>false</code></td>
<td><code>false</code></td>
<td><code>true</code></td>
<td><code>true</code></td>
<td><code>static_cast&lt;typename To::tick_type&gt;(fd.count())</code></td>
</tr>

<tr>
<td><code>false</code></td>
<td><code>true</code></td>
<td><code>false</code></td>
<td><code>false</code></td>
<td>Not possible</td>
</tr>

<tr>
<td><code>false</code></td>
<td><code>true</code></td>
<td><code>false</code></td>
<td><code>true</code></td>
<td>Not possible</td>
</tr>

<tr>
<td><code>false</code></td>
<td><code>true</code></td>
<td><code>true</code></td>
<td><code>false</code></td>
<td><code>static_cast&lt;typename To::tick_type&gt;(<br/>
static_cast&lt;FinerTickType&gt;(fd.count())*<br/>
static_cast&lt;FinerTickType&gt;(From::seconds_per_tick*To::ticks_per_second))
</code></td>
</tr>

<tr>
<td><code>false</code></td>
<td><code>true</code></td>
<td><code>true</code></td>
<td><code>true</code></td>
<td>Not possible</td>
</tr>

<tr>
<td><code>true</code></td>
<td><code>false</code></td>
<td><code>false</code></td>
<td><code>false</code></td>
<td>Not possible</td>
</tr>

<tr>
<td><code>true</code></td>
<td><code>false</code></td>
<td><code>false</code></td>
<td><code>true</code></td>
<td><code>static_cast&lt;typename To::tick_type&gt;(<br/>
static_cast&lt;FinerTickType&gt;(fd.count())/<br/>
static_cast&lt;FinerTickType&gt;(From::ticks_per_second*To::seconds_per_tick))
</code></td>
</tr>

<tr>
<td><code>true</code></td>
<td><code>false</code></td>
<td><code>true</code></td>
<td><code>false</code></td>
<td>Not possible</td>
</tr>

<tr>
<td><code>true</code></td>
<td><code>false</code></td>
<td><code>true</code></td>
<td><code>true</code></td>
<td>Not possible</td>
</tr>

<tr>
<td><code>true</code></td>
<td><code>true</code></td>
<td><code>false</code></td>
<td><code>false</code></td>
<td><code>static_cast&lt;typename To::tick_type&gt;(<br/>
static_cast&lt;FinerTickType&gt;(fd.count())*<br/>
static_cast&lt;FinerTickType&gt;(To::ticks_per_second/GCD_TPS)/<br/>
static_cast&lt;FinerTickType&gt;(From::ticks_per_second/GCD_TPS))
</code></td>
</tr>

<tr>
<td><code>true</code></td>
<td><code>true</code></td>
<td><code>false</code></td>
<td><code>true</code></td>
<td><code>static_cast&lt;typename To::tick_type&gt;(<br/>
static_cast&lt;FinerTickType&gt;(fd.count())/<br/>
static_cast&lt;FinerTickType&gt;(From::ticks_per_second/To::ticks_per_second))
</code></td>
</tr>

<tr>
<td><code>true</code></td>
<td><code>true</code></td>
<td><code>true</code></td>
<td><code>false</code></td>
<td><code>static_cast&lt;typename To::tick_type&gt;(<br/>
static_cast&lt;FinerTickType&gt;(fd.count())*<br/>
static_cast&lt;FinerTickType&gt;(To::ticks_per_second/From::ticks_per_second))
</code></td>
</tr>

<tr>
<td><code>true</code></td>
<td><code>true</code></td>
<td><code>true</code></td>
<td><code>true</code></td>
<td><code>static_cast&lt;typename To::tick_type&gt;(fd.count())</code></td>
</tr>
</table>
</dd>
</dl>

</blockquote>

<h3>31.8 Class system_time [time.system]</h3>

<p>...</p>

<blockquote>
<pre><code>
class system_time
{
public:

    system_time();
    explicit system_time(time_t, nanoseconds <var>ns</var>=0);

    time_t seconds_since_epoch() const;
    nanoseconds nanoseconds_since_epoch() const;

    // <em>traits</em>
    typedef <var><strong>implementation defined</strong></var> tick_type;
    static const tick_type ticks_per_second = nanoseconds::ticks_per_second;
    static const tick_type seconds_per_tick = 0;
    static const bool is_subsecond = true;

    // <em>comparison functions</em>
    bool operator==(const system_time&amp; <var>rhs</var>) const;
    bool operator!=(const system_time&amp; <var>rhs</var>) const;
    bool operator&gt;(const system_time&amp; <var>rhs</var>) const;
    bool operator&gt;=(const system_time&amp; <var>rhs</var>) const;
    bool operator&lt;(const system_time&amp; <var>rhs</var>) const;
    bool operator&lt;=(const system_time&amp; <var>rhs</var>) const;

    // <em>arithmetic functions</em>
    nanoseconds operator-(const system_time&amp; <var>rhs</var>) const

    template&lt;typename <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
    system_time operator+(const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>td</var>) const;

    template&lt;typename <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
    system_time&amp; operator+=(const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>td</var>);

    template&lt;typename <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
    system_time operator-(const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>td</var>) const;

    template&lt;typename <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
    system_time&amp; operator-=(const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>td</var>)
};
</code></pre>
</blockquote>

<p>...</p>

<pre><code>
template&lt;typename <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
  system_time operator+(const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>td</var>) const;
</code></pre>

<p>...</p>

<pre><code>
template&lt;typename <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
    system_time&amp; operator+=(const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>td</var>);
</code></pre>

<p>...</p>

<pre><code>
template&lt;typename <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
  system_time operator-(const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>td</var>) const;
</code></pre>

<p>...</p>

<pre><code>
template&lt;typename <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
  system_time&amp; operator-=(const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>td</var>)
</code></pre>

<h3><a name="time.nonmembers">31.9 Non-member functions [time.nonmembers]</a></h3>

<p>...</p>

<pre><code>
template&lt;typename <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
  system_time operator+(const <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins>&amp; <var>td</var>, const system_time&amp; <var>rhs</var>);
</code></pre>

<p>...</p>

<pre><code>
template &lt;class <del>LhsDuration</del> <ins>TT1, long long TPS1, long long SPT1</ins>, class <del>RhsDuration</del> <ins>TT2, long long TPS2, long long SPT2</ins>&gt;
  bool operator==(const <del>LhsD</del><ins>d</ins>uration<ins>&lt;TT1, TPS1, SPT1&gt;</ins>&amp; <var>lhs</var>, const <del>RhsD</del><ins>d</ins>uration<ins>&lt;TT2, TPS2, SPT2&gt;</ins>&amp; <var>rhs</var>);
</code></pre>
<blockquote>
<dl>

<dt><del>Requires:</del></dt>
<dd>
<del>Either
<code>LhsDuration</code> shall be exactly convertible to <code>RhsDuration</code> or
<code>RhsDuration</code> shall be exactly convertible to <code>LhsDuration</code> (diagnostic required).</del>
</dd>

<dt>Returns:</dt>
<dd>
<code><del>Finest</del><ins>Common</ins>Duration(<var>lhs</var><ins>)</ins>.count()<del>)</del> == <del>Finest</del><ins>Common</ins>Duration(<var>rhs</var><ins>)</ins>.count()<del>)</del><br>
<br>
</code>See [time] for description of <code><del>Finest</del><ins>Common</ins>Duration</code>.</dd>

</dl>
</blockquote>
<pre><code>
template &lt;class <del>LhsDuration</del> <ins>TT1, long long TPS1, long long SPT1</ins>, class <del>RhsDuration</del> <ins>TT2, long long TPS2, long long SPT2</ins>&gt;
  bool operator!=(const <del>LhsD</del><ins>d</ins>uration<ins>&lt;TT1, TPS1, SPT1&gt;</ins>&amp; <var>lhs</var>, const <del>RhsD</del><ins>d</ins>uration<ins>&lt;TT2, TPS2, SPT2&gt;</ins>&amp; <var>rhs</var>);
</code></pre>
<blockquote>
<dl>

<dt><del>Requires:</del></dt>
<dd>
<del>Either
<code>LhsDuration</code> shall be exactly convertible to <code>RhsDuration</code> or
<code>RhsDuration</code> shall be exactly convertible to <code>LhsDuration</code> (diagnostic required).</del>
</dd>

<dt>Returns:</dt>
<dd>
<code>!(<var>lhs</var>==<var>rhs</var>)</code>.
</dd>

</dl>
</blockquote>
<pre><code>
template &lt;class <del>LhsDuration</del> <ins>TT1, long long TPS1, long long SPT1</ins>, class <del>RhsDuration</del> <ins>TT2, long long TPS2, long long SPT2</ins>&gt;
  bool operator&lt; (const <del>LhsD</del><ins>d</ins>uration<ins>&lt;TT1, TPS1, SPT1&gt;</ins>&amp; <var>lhs</var>, const <del>RhsD</del><ins>d</ins>uration<ins>&lt;TT2, TPS2, SPT2&gt;</ins>&amp; <var>rhs</var>);
</code></pre>
<blockquote>
<dl>

<dt><del>Requires:</del></dt>
<dd>
<del>Either
<code>LhsDuration</code> shall be exactly convertible to <code>RhsDuration</code> or
<code>RhsDuration</code> shall be exactly convertible to <code>LhsDuration</code> (diagnostic required).</del>
</dd>

<dt>Returns:</dt>
<dd>
<code><del>Finest</del><ins>Common</ins>Duration(<var>lhs</var><ins>)</ins>.count()<del>)</del> &lt; <del>Finest</del><ins>Common</ins>Duration(<var>rhs</var><ins>)</ins>.count()<del>)</del><br>
<br>
</code>See [time] for description of <code><del>Finest</del><ins>Common</ins>Duration</code>.</dd>

</dl>
</blockquote>
<pre><code>
template &lt;class <del>LhsDuration</del> <ins>TT1, long long TPS1, long long SPT1</ins>, class <del>RhsDuration</del> <ins>TT2, long long TPS2, long long SPT2</ins>&gt;
  bool operator&lt;=(const <del>LhsD</del><ins>d</ins>uration<ins>&lt;TT1, TPS1, SPT1&gt;</ins>&amp; <var>lhs</var>, const <del>RhsD</del><ins>d</ins>uration<ins>&lt;TT2, TPS2, SPT2&gt;</ins>&amp; <var>rhs</var>);
</code></pre>
<blockquote>
<dl>

<dt><del>Requires:</del></dt>
<dd>
<del>Either
<code>LhsDuration</code> shall be exactly convertible to <code>RhsDuration</code> or
<code>RhsDuration</code> shall be exactly convertible to <code>LhsDuration</code> (diagnostic required).</del>
</dd>

<dt>Returns:</dt>
<dd>
<code>!(<var>rhs</var>&lt;<var>lhs</var>)</code>.
</dd>

</dl>
</blockquote>
<pre><code>
template &lt;class <del>LhsDuration</del> <ins>TT1, long long TPS1, long long SPT1</ins>, class <del>RhsDuration</del> <ins>TT2, long long TPS2, long long SPT2</ins>&gt;
  bool operator&gt; (const <del>LhsD</del><ins>d</ins>uration<ins>&lt;TT1, TPS1, SPT1&gt;</ins>&amp; <var>lhs</var>, const <del>RhsD</del><ins>d</ins>uration<ins>&lt;TT2, TPS2, SPT2&gt;</ins>&amp; <var>rhs</var>);
</code></pre>
<blockquote>
<dl>

<dt><del>Requires:</del></dt>
<dd>
<del>Either
<code>LhsDuration</code> shall be exactly convertible to <code>RhsDuration</code> or
<code>RhsDuration</code> shall be exactly convertible to <code>LhsDuration</code> (diagnostic required).</del>
</dd>

<dt>Returns:</dt>
<dd>
<code><var>rhs</var>&lt;<var>lhs</var></code>.
</dd>

</dl>
</blockquote>
<pre><code>
template &lt;class <del>LhsDuration</del> <ins>TT1, long long TPS1, long long SPT1</ins>, class <del>RhsDuration</del> <ins>TT2, long long TPS2, long long SPT2</ins>&gt;
  bool operator&gt;=(const <del>LhsD</del><ins>d</ins>uration<ins>&lt;TT1, TPS1, SPT1&gt;</ins>&amp; <var>lhs</var>, const <del>RhsD</del><ins>d</ins>uration<ins>&lt;TT2, TPS2, SPT2&gt;</ins>&amp; <var>rhs</var>);
</code></pre>
<blockquote>
<dl>

<dt><del>Requires:</del></dt>
<dd>
<del>Either
<code>LhsDuration</code> shall be exactly convertible to <code>RhsDuration</code> or
<code>RhsDuration</code> shall be exactly convertible to <code>LhsDuration</code> (diagnostic required).</del>
</dd>

<dt>Returns:</dt>
<dd>
<code>!(<var>lhs</var>&lt;<var>rhs</var>)</code>.
</dd>

</dl>
</blockquote>
<pre><code>
template &lt;class <del>LhsDuration</del> <ins>TT1, long long TPS1, long long SPT1</ins>, class <del>RhsDuration</del> <ins>TT2, long long TPS2, long long SPT2</ins>&gt;
  <var><del>Finest</del><ins>Common</ins>Duration</var> operator+(const <del>LhsD</del><ins>d</ins>uration<ins>&lt;TT1, TPS1, SPT1&gt;</ins>&amp; <var>lhs</var>, const <del>RhsD</del><ins>d</ins>uration<ins>&lt;TT2, TPS2, SPT2&gt;</ins>&amp; <var>rhs</var>)
</code></pre>
<blockquote>
<dl>

<dt><del>Requires:</del></dt>
<dd>
<del>Either
<code>LhsDuration</code> shall be exactly convertible to <code>RhsDuration</code> or
<code>RhsDuration</code> shall be exactly convertible to <code>LhsDuration</code> (diagnostic required).</del>
</dd>

<dt>Returns:</dt>
<dd>
<code><del>Finest</del><ins>Common</ins>Duration(<var>lhs</var><ins>)</ins>.count()<del>)</del>+<del>Finest</del><ins>Common</ins>Duration(<var>rhs</var><ins>)</ins>.count()<del>)</del><br>
<br>
</code>See [time] for description of <code><del>Finest</del><ins>Common</ins>Duration</code>.</dd>

</dl>
</blockquote>
<pre><code>
template &lt;class <del>LhsDuration</del> <ins>TT1, long long TPS1, long long SPT1</ins>, class <del>RhsDuration</del> <ins>TT2, long long TPS2, long long SPT2</ins>&gt;
  <var><del>Finest</del><ins>Common</ins>Duration</var> operator-(const <del>LhsD</del><ins>d</ins>uration<ins>&lt;TT1, TPS1, SPT1&gt;</ins>&amp; <var>lhs</var>, const <del>RhsD</del><ins>d</ins>uration<ins>&lt;TT2, TPS2, SPT2&gt;</ins>&amp; <var>rhs</var>)
</code></pre>
<blockquote>
<dl>

<dt><del>Requires:</del></dt>
<dd>
<del>Either
<code>LhsDuration</code> shall be exactly convertible to <code>RhsDuration</code> or
<code>RhsDuration</code> shall be exactly convertible to <code>LhsDuration</code> (diagnostic required).</del>
</dd>

<dt>Returns:</dt>
<dd>
<code><del>Finest</del><ins>Common</ins>Duration(<var>lhs</var><ins>)</ins>.count()<del>)</del>-<del>Finest</del><ins>Common</ins>Duration(<var>rhs</var><ins>)</ins>.count()<del>)</del><br>
<br>
</code>See [time] for description of <code><del>Finest</del><ins>Common</ins>Duration</code>.</dd>

</dl>
</blockquote>

<pre><code>
template &lt;class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
  <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins> operator*(<del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins> <var>lhs</var>, <del>long</del> <ins>typename duration&lt;TT, TPS, SPT&gt;::tick_type</ins> <var>rhs</var>)
</code></pre>
<blockquote>
<dl>

<dt>Returns:</dt>
<dd>
<code><var>lhs</var> *= <var>rhs</var></code>.
</dd>

</dl>
</blockquote>

<pre><code>
template &lt;class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
   <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins> operator*(<del>long</del> <ins>typename duration&lt;TT, TPS, SPT&gt;::tick_type</ins> <var>lhs</var>, <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins> <var>rhs</var>)
</code></pre>
<blockquote>
<dl>

<dt>Returns:</dt>
<dd>
<code><var>rhs</var> *= <var>lhs</var></code>.
</dd>

</dl>
</blockquote>

<pre><code>
template &lt;class <del>Duration</del> <ins>TT, long long TPS, long long SPT</ins>&gt;
   <del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins> operator/(<del>D</del><ins>d</ins>uration<ins>&lt;TT, TPS, SPT&gt;</ins> <var>lhs</var>, <del>long</del> <ins>typename duration&lt;TT, TPS, SPT&gt;::tick_type</ins> <var>rhs</var>)
</code></pre>
<blockquote>
<dl>

<dt>Returns:</dt>
<dd>
<code><var>lhs</var> /= <var>rhs</var></code>.
</dd>

</dl>
</blockquote>

<h2><a name="Acknowledgments">Acknowledgments</a></h2>

<p>
Much thanks to Daniel Kr&uuml;gler for the excellent review and suggestions.
</p>

</body>
</html>
