N2800 - 20.8 Time utilities の翻訳

chrono について調べる必要が出てきたので、理解を深めるために該当箇所を翻訳してみました。

duration クラス

duration クラスは C# で言うところの TimeSpan。つまり時間の距離を表す。
テンプレート引数の Rep というのは単なる整数か浮動小数点の値で、Period というのは ratio クラスのことで、Rep の tick(インクリメント)が何秒になるのかという量を決める(たとえば Period が ratio<1, 1000> なら Rep がインクリメントされると 1/1000 秒進む)。
duration がいろんなスケールで値が表現できて結構嬉しかったり。


異なる Period な duration 間で計算すると自動的に最大公約数な Period にしてくれる。これは common_type というメタ関数のおかげ。
たとえば duration> と duration> 同士で計算すると、duration> になる。


あと、duration> から duration> の変換は可能(前者の Rep を 10 倍して後者の duration に代入するだけ)だけど、その逆は(10 で割ると切捨てが起こる可能性があるので)ダメ。
切捨て起こってもいいから型変換したい場合は明示的に duration_cast を使う。

time_point

時間軸のある一点を表すクラス。C# で言うところの DateTime。基準となる時間(epoch)からの差分(duration)によって記述する。
epoch は Clock によって決定する。例えば system_clock であればシステムの基準時刻(1985年1月1日 00:00とか)が epoch になるはず。
この time_point に対して duration を足したり引いたりすることが可能。当然 duration 同士の変換は考慮される。time_point が持ってる duration を明示的にキャストしたいときは time_point_cast を使う。


Clock の異なる time_point 同士で計算することは不可能。というか time_point 同士での演算は減算しか無いので困ることはないはず。
ただし、異なる Clock である C1, C2 という Clock の C1::time_point と C2::time_point は同じ Clock を共有する可能性がある。同じ epoch である場合はそのまま計算できて欲しいからだと思われる。

Clock

まあこれは現在時刻 now() を持ってたり、時間が逆行しない時計かどうかを持ってたり(is_monotonic)その Clock の精度(period)や距離(duration)が typedef されているだけ。
is_monotonic の制限は結構うれしい。システムの時計を弄ると時間が戻ってしまうことがあったりなので。


しかしこれ、monotonic_clock や high_resolution_clock の time_point の Clock は unspecified になってる。もしここが system_clock だったりなんかすると、monotonic_clock や high_resolution_clock は system_clock と同じ epoch ということになる。
まあそれ自体は全然いいんだけど、異なる Clock 間での time_point の計算が出来ているように見えてしまうので「system_clock と monotonic_clock 間で計算できるのは当たり前でしょ」みたいにならないかどうかがちょと心配。

void foo(monotonic_clock::time_point t);

foo(system_clock::now() + milliseconds(1000));

とか書いてあるコードとか普通に出てきそうで怖い。
「同じかもしれませんよ?」というのは全然メリットが感じられないので、標準できちんと Clock を分けて欲しいなぁ……。