コード日進月歩

しんくうの技術的な小話、メモ、つれづれ、など

Railsで使えるTimeクラスのいろいろシリーズ

お前、そんなパターンもあるのかって気持ちになるので一覧

環境

rails (5.2.0)

四則演算用の時間

まずは基本として、Integerインスタンスは、時間の単語にまつわるメソッドを持っていて、それらが時間を表現してくれる。

# 1秒
1.second
# 2分
2.minute
# 3時間
3.hour
# 4日
4.day
# 5週間
5.week
# 6週間
6.month
# 7年
7.year

使い方としては足したり引いたりで使う

Time.zone.parse("2017-1-10 10:50:25") + 1.hour
=> Tue, 10 Jan 2017 11:50:25 JST +09:00

始まりと終わりタイプ

Timeクラスのインスタンスが持つメソッド。 その時間からの始まりや終わりを指し示す

▼始まり系

beginning_of_minute
beginning_of_hour
beginning_of_week
beginning_of_day
beginning_of_month
beginning_of_quarter
beginning_of_year

▼終わり系

end_of_minute
end_of_hour
end_of_week
end_of_day
end_of_month
end_of_quarter
end_of_year

基本的には その日の始まりその月の終わり のような時間を教えてくれる

Time.zone.parse("2017-11-10 10:50:25").beginning_of_day
# => Fri, 10 Nov 2017 00:00:00 JST +09:00
Time.zone.parse("2017-11-10 10:50:25").end_of_month
# => Thu, 30 Nov 2017 23:59:59 JST +09:00

大体は直感的に分かるが分かりにくい/勘違いしやすいのが2つあるので例を込みで紹介。

まずは quarter で、四半期を表す。1月〜3月、4月〜6月、7月〜9月、10月〜12月の4つに別れる。

Time.zone.parse("2017-2-10 10:50:25").beginning_of_quarter
# => Sun, 01 Jan 2017 00:00:00 JST +09:00
Time.zone.parse("2017-6-10 10:50:25").beginning_of_quarter
#=> Sat, 01 Apr 2017 00:00:00 JST +09:00
Time.zone.parse("2017-8-10 10:50:25").beginning_of_quarter
# => Sat, 01 Jul 2017 00:00:00 JST +09:00
Time.zone.parse("2017-11-10 10:50:25").beginning_of_quarter
# => Sun, 01 Oct 2017 00:00:00 JST +09:00

もうひとつは week。ここでは月曜始まりなので、beginning_of_week は月曜日で、end_of_week は日曜日となる。

1つ前/後タイプ

1日前や、1ヶ月後など、1つ前の単位日付などを算出するのに使う。日本語表現で行くと、先月、翌月、去年、来年にあたる単位のものを渡してくれる。

なお、最小単位は「日」からで、時刻絡みのものはない。

▼前

prev_day
prev_week
prev_month
prev_quarter
prev_year

▼後

next_day
next_week
next_month
next_quarter
next_year

target_time = Time.zone.parse("2017-8-10 10:50:25")
# => Thu, 10 Aug 2017 10:50:25 JST +09:00
target_time.prev_day
# => Wed, 09 Aug 2017 10:50:25 JST +09:00
target_time.prev_week
# => Mon, 31 Jul 2017 00:00:00 JST +09:00
target_time.prev_month
# => Mon, 10 Jul 2017 10:50:25 JST +09:00
target_time.prev_quarter
# => Wed, 10 May 2017 10:50:25 JST +09:00
target_time.prev_year
# => Wed, 10 Aug 2016 10:50:25 JST +09:00
target_time.next_day
# => Fri, 11 Aug 2017 10:50:25 JST +09:00
target_time.next_week
# => Mon, 14 Aug 2017 00:00:00 JST +09:00
target_time.next_month
# => Sun, 10 Sep 2017 10:50:25 JST +09:00
target_time.next_quarter
# => Fri, 10 Nov 2017 10:50:25 JST +09:00
target_time.next_year
# => Fri, 10 Aug 2018 10:50:25 JST +09:00

間隔タイプ

引数に値を指定して、単位に準じた数値分前後する。

▼前(ago系)

ago
days_ago
months_ago
weeks_ago
years_ago

▼後(since系)

since
days_since
months_since
weeks_since
years_since

target_time = Time.zone.parse("2017-8-10 10:50:25")
# => Thu, 10 Aug 2017 10:50:25 UTC +00:00

target_time.ago(1.second)
# => Thu, 10 Aug 2017 10:50:24 UTC +00:00
target_time.ago(1)
# => Thu, 10 Aug 2017 10:50:24 UTC +00:00
target_time.days_ago(1)
# => Wed, 09 Aug 2017 10:50:25 UTC +00:00
target_time.weeks_ago(1)
# => Thu, 03 Aug 2017 10:50:25 UTC +00:00
target_time.months_ago(1)
# => Mon, 10 Jul 2017 10:50:25 UTC +00:00
target_time.years_ago(1)
# => Wed, 10 Aug 2016 10:50:25 UTC +00:00

target_time.since(1)
# => Thu, 10 Aug 2017 10:50:26 UTC +00:00
target_time.days_since(1)
# => Fri, 11 Aug 2017 10:50:25 UTC +00:00
target_time.weeks_since(1)
# => Thu, 17 Aug 2017 10:50:25 UTC +00:00
target_time.months_since(1)
# => Sun, 10 Sep 2017 10:50:25 UTC +00:00
target_time.years_since(1)
# => Fri, 10 Aug 2018 10:50:25 UTC +00:00

agoとsinseは引数に 1.days とかも指定できる

target_time = Time.zone.parse("2017-8-10 10:50:25")
# => Thu, 10 Aug 2017 10:50:25 UTC +00:00

target_time.ago(3.days)
# => Mon, 07 Aug 2017 10:50:25 UTC +00:00
target_time.since(2.week)
# => Thu, 24 Aug 2017 10:50:25 UTC +00:00

自然な言葉シリーズ

普通の英語として書ける系のシリーズ。大体何かのエイリアス

# 昨日
yesterday
# 明日
tomorrow
# その日の0時ちょうど
midnight

target_time = Time.zone.parse("2017-11-10 0:10:25")
# => Fri, 10 Nov 2017 00:10:25 JST +09:00
target_time.yesterday
# => Thu, 09 Nov 2017 00:10:25 JST +09:00
target_time.tomorrow
# => Sat, 11 Nov 2017 00:10:25 JST +09:00
target_time.midnight
# => Fri, 10 Nov 2017 00:00:00 JST +09:00

(番外編)その日からの経過秒数

すごい言葉の並び的に似てるけど違うものとして『その日の0時からの経過秒数』を表す seconds_since_midnight がある。

Time.zone.parse("2017-11-10 0:10:25").seconds_since_midnight
# => 625.0

参考リンク