Rails の Date, Time 拡張

ActiveSupport による Date, Time クラスの拡張まとめ。バージョンは 2.0.2 準拠。ソースを読んで script/console で動作確認を行っています。

相互置換

Date でも Time でも、それぞれ to_time および to_date で相互に置換できます。
必要であれば to_datetime で DateTime 型への変換も可能です。

to_s の拡張

to_s に引数をつける事で、所定の形式で出力してくれます。

Time.now.to_s(:db)
=> "2008-2-23 17:49:29"

引数と出力の対応は以下のとおり。

Time

引数出力
:db%Y-%m-%d %H:%M:%S
:time%H:%M
:short%d %b %H:%M
:long%B %d, %Y %H:%M
:long_ordinallambda { |time| time.strftime("%B #{time.day.ordinalize}, %Y %H:%M") }
:rfc822%a, %d %b %Y %H:%M:%S %z

Date

引数出力
:db%Y-%m-%d
:short%e %b
:long%B %e, %Y
:long_ordinallambda { |date| date.strftime("%B #{date.day.ordinalize}, %Y") }
:rfc822%e %b %Y

(:db) は DB に値を保存するとき、 (:rfc822) はフィードを作る時などに便利です。
ちなみにこのメソッドは to_formatted_s メソッドを定義して、 to_s をそのエイリアスにしています。

各種計算

days_in_month(month, year=nil)

その月の日数をうるう年まで考慮して計算してくれます。year は省略可能で、省いた場合うるう年を考慮せずに計算されます。これはクラスメソッドなので、 Time.days_in_month(12, 2000) のようにインスタンスを作らずに使用します。

utc_time(*args), local_time(*args)

どちらも内部では time_with_datetime_fallback メソッドを呼び出します。これもクラスメソッドです。
utc_time で UTCが、 local_time でローカル時刻が得られます。引数は time_with_datetime_fallback で説明します。

time_with_datetime_fallback(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0, usec=0)

時刻を計算して、値を返します。引数は見てのとおりですが、不正な値を指定すると ArgumentError になるようです。

seconds_since_midnight

その日の 00:00:00 から何秒経過したか計算します。

change(options)

:year => 2000 のように指定すると、その部分だけ現在の時刻から変更してくれます。
引数には :year, :month, :day, :hour, :min, :sec, :usec が指定可能。
時刻が UTC かどうかも判定してくれるようです。

advance(options)

:years, :months, :days, :hours, :minutes, :seconds を指定すると、現在時刻から指定した時間だけ移動した時刻を返します。こちらの引数は複数形なので注意して下さい。

ago(seconds)

seconds 秒前の時刻を返します。内部的には since(-seconds) を実行しています。
Date 型のオブジェクトでも利用可能ですが、 Time 型の値が返されるので注意して下さい。

since(seconds)

seconds 秒先の時刻を返します。エイリアスとして in が利用可能。
これも Date 型で使うと Time 型が返るので注意。

months_ago(months)

months だけ月を戻した値を返します。advance(:months => -month) を実行しています。

months_since(months)

months だけ月を進めた値を返します。advance(:months => month) を実行しています。

years_ago(years)

months だけ年を戻した値を返します。advance(:years => -year) を実行しています。

years_since(years)

months だけ年を進めた値を返します。advance(:years => year) を実行しています。

last_year

1年前の同じ日付/時刻を返します。years_ago(1) を実行しています。

next_year

1年先の同じ日付/時刻を返します。years_since(1) を実行しています。

last_month

先月の同じ日付/時刻を返します。months_ago(1) を実行しています。

next_month

来月の同じ日付/時刻を返します。months_since(1) を実行しています。

beginning_of_week

該当する日付/時刻が属する週の頭の日付/時刻を返します。時刻は 00:00:00 になります。

next_week(day = :monday)

該当する日付/時刻から見て次の週の指定した曜日の日付/時刻を返します。時刻は 00:00:00 になります。
念のために引数を書いておくと :monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday になります。スペルミスに注意。

beginning_of_day

その日の 00:00:00 を返します。
(self - self.seconds_since_midnight).change(:usec => 0) を実行しており、ミリ秒単位で正確です。
Time 型でしか利用できません。

end_of_day

その日の 23:59:59 を返します。
こちらは change(:hour => 23, :min => 59, :sec => 59) を実行します。
これも Time 型でしか利用できません。

beginning_of_month

該当する日付/時刻が属する月の頭の日付/時刻を返します。時刻は 00:00:00 になります。
change(:day => 1,:hour => 0, :min => 0, :sec => 0, :usec => 0) を実行します。

end_of_month

該当する日付/時刻が属する月の終わりの日付/時刻を返します。時刻は 00:00:00 になります。うるう年も考慮されています。

beginning_of_quarter

指定した日付/時刻の所属する四半期の頭の日付/時刻を返します。時刻は 00:00:00 になります。
学生には馴染みが薄いですが、四半期は1月、4月、7月、10月の1日が頭になります。

beginning_of_year

該当する日付/時刻が属する年初の日付/時刻を返します。時刻は 00:00:00 になります。

yesterday

該当する日付/時刻の1日(24時間)前の日付/時刻を返します。
Date 型ではクラスメソッドとしても使用でき、現在時刻から計算した24時間前の日付を Date 型で返します。

tomorrow

該当する日付/時刻の1日(24時間)後の日付/時刻を返します。
これも Date 型ではクラスメソッドとしても利用可能です。

plus_with_duration

ドキュメントが存在しませんでした。plus_with_duration(3600) とすると1時間進むので、そのように使うものと予想されます。
分かる方がいれば、コメントして頂けると幸いです。

minus_with_duration

上に同じ。