Posted at

RubyのTimeクラスとDateクラスの使い分け

More than 3 years have passed since last update.

RubyとRailsにおけるTime, Date, DateTime, TimeWithZoneの違い - Qiita

上記記事ではTimeクラスを使おうと結論付けられていて、基本は自分もそうしているのだけれど、当然クラスが違えば振る舞いも違ってくるので、あえてDateクラスを遣う場面もあるなぁという話。


日付処理はDateクラス便利

日付に関係した処理はかなり充実している。

[1] pry(main)> Date.today

=> #<Date: 2015-12-01 ((2457358j,0s,0n),+0s,2299161j)>
[2] pry(main)> Date.today.next_month
=> #<Date: 2016-01-01 ((2457389j,0s,0n),+0s,2299161j)>
[3] pry(main)> Date.today.tuesday?
=> true
[4] pry(main)> Date.today.next_year.leap?
=> true

特に#leap?なんぞはよくある閏年の計算を書かずに済むので便利だったり。また日付のインクリメント、デクリメントに相当する操作も楽にできる。Timeクラスだとこのあたりの操作は秒が基本単位になるので、日付の処理であれば個人的にはDateクラスを遣うほうが楽。

[5] pry(main)> Date.today >> 2

=> #<Date: 2016-02-01 ((2457420j,0s,0n),+0s,2299161j)>
[6] pry(main)> Date.today << 1
=> #<Date: 2015-11-01 ((2457328j,0s,0n),+0s,2299161j)>
[7] pry(main)> Date.today + 1
=> #<Date: 2015-12-02 ((2457359j,0s,0n),+0s,2299161j)>
[8] pry(main)> Date.today - 1
=> #<Date: 2015-11-30 ((2457357j,0s,0n),+0s,2299161j)>


現在(日付|時刻)を取得するときの相違

TimeクラスとDateクラスで混同しやすいのが現在日時の取得方法。例えば引数なしの.newでTimeクラスは現在日時を返すが、Dateクラスは返してくれない。

[9] pry(main)> Time.new

=> 2015-12-01 00:00:00 +0900
[10] pry(main)> Date.new
=> #<Date: -4712-01-01 ((0j,0s,0n),+0s,2299161j)>

いつやねん って話だが、イタリアがグレゴリオ暦を用い始めた日らしい。何か特別な呼び方がありそうなものだが、少し探した範囲では見つからず。

Dateクラスで実行日の日付を取得するには.today。またTimeクラスでは.newの他に.nowも使うことができる。

[11] pry(main)> Date.today

=> #<Date: 2015-12-01 ((2457358j,0s,0n),+0s,2299161j)>
[12] pry(main)> Time.now
=> 2015-12-01 00:00:00 +0900


特定フォーマットで日時を出力する

これはいずれも#strftimeが使える。よく日付を二桁で取得したいことがあるので便利。ただし#monthなどで出力した場合はIntegerで返されるのに対し、#strftimeはStringで返されるという違いはある。

[13] pry(main)> Date.today.prev_month(4).mon

=> 8
[14] pry(main)> Date.today.prev_month(4).strftime('%m')
=> "08"


結論

RubyでもTimeWithZoneで1.weeks.agoとかやりたい。