bouzuya.hatenablog.com

ぼうずやのにっき

DateTime における Duration を考えている

bouzuya/rust-sandbox の date-time で Duration を Seconds にした。

自動変換して内部的には秒を持つ Duration より秒なら Seconds としたほうが単位間の相互変換をより明示できそうな気がしたからだ。また ISO8601 における P1MT1S のようなものを表現したくなったとき困りにくそうだからだ。

DateTime における Duration を考えている。

Duration は期間を表すものだ。たとえば「 2021-02-03 に 1 日という期間 (時間量) を足すと 2021-02-04 となる」。 "1 日という期間 (時間量) " がここでの Duration だ。

java.time における Duration は実質的に秒 (とナノ秒) だ。ファクトリメソッド (コンストラクタ) として ofDays, ofHours, ofSeconds などを提供している。 https://docs.oracle.com/javase/jp/8/docs/api/java/time/Duration.html

しかし ofMonthofYear は提供していない。これは月や年は一定の期間にならないためだ。たとえば月は 10 月なら 31 日だし 11 月なら 30 日だ。年は 2020 年なら 366 日だし 2021 年なら 365 日だ。

この月・年の扱いをどうするかは Duration を考える上で悩ましいところだと思う。

「自動変換して内部的には秒を持つ Duration 」の場合は 1 ヶ月を表現できない。 1 ヶ月は一定の秒で表せない。でも 1 ヶ月という考え方は確かにある。

たとえば YearMonth(2021-01) に対して Months(1) を足せば YearMonth(2021-02) になってほしい。月単位で計算するとき 1 ヶ月が何日であるかに関心はない。これは「 1 ヶ月」を足しているのではあって「 1 ヶ月分の秒」を足しているのではない。こういう状況があるので「月」が欲しくなる。

java.time では Duration をあくまでも時間に対してのものとしておき代わりに Period を提供している。これは年・月・日の量をそれぞれ持つことで「 1 ヶ月」のような期間を表せるようになっている。 https://docs.oracle.com/javase/jp/8/docs/api/java/time/Period.html

Duration は HH:MM:SS に対応する期間で Period は YYYY-MM-DD に対応する期間のような考え方なのだと思う。 Duration と Period 。分かるような分からないような。

ぼくはひとまず SecondsDays をつくった。最初 Duration をつくってみたのだけど Seconds にしてしまった。各単位を無理にまとめる必要がないように思ったからだ。 Days から Seconds に変換できることは impl From<Days> for Seconds のように表現できる。必要な分だけ変換処理を提供しておけば良くて ISO8601 の期間形式を扱うなどまとめる必要が出たところで各単位と量をまとめるものとして Duration を導入すればいいんじゃないかと思っている。考えは変わるかもしれないけど。


今日のコミット。