Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
126
Help us understand the problem. What is going on with this article?
@ykyk1218

すぐ忘れるので、RubyとRailsの日付操作周りについてまとめました

More than 3 years have passed since last update.

日付の操作はしょっちゅうするのですが、なんか毎回調べているにも関わらず、いっこうに頭に入ってこないのでまとめました。

それぞれの日付型の意味についてはこちらの記事を参照してみてください。
RubyとRailsにおけるTime, Date, DateTime, TimeWithZoneの違い

x日前

ruby

Date型なら -1 するだけです

require "date"
d = Date.today
p d
p d-1

#<Date: 2017-09-07 ((2458004j,0s,0n),+0s,2299161j)>
#<Date: 2017-09-06 ((2458003j,0s,0n),+0s,2299161j)>

DateTimeも -1でいけるよ

require "date"
d = DateTime.now
p d
p d-1

#<DateTime: 2017-09-15T17:52:04+09:00 ((2458012j,31924s,725447000n),+32400s,2299161j)>
#<DateTime: 2017-09-14T17:52:04+09:00 ((2458011j,31924s,725447000n),+32400s,2299161j)>

Timeは1秒マイナスするだけや

now = Time.now
p now
p now -1

# 2017-09-07 17:52:54 +0900
# 2017-09-07 17:52:53 +0900

rails(ActiveSupport)

-1.days

[2] pry(main)> Time.current
=> Fri, 18 Aug 2017 18:12:21 JST +09:00
[3] pry(main)> Time.current - 1.days
=> Thu, 17 Aug 2017 18:12:26 JST +09:00

x月前

ruby

<<演算子で前の月の日付オブジェクトを返します


require "date"
d = Date.new(2017,9,7)
p d
p d << 2
# d.prev_month(2)でも同じ

#<Date: 2017-09-07 ((2458004j,0s,0n),+0s,2299161j)>
#<Date: 2017-07-07 ((2457973j,0s,0n),+0s,2299161j)>

rails(ActiveSupport)

Time.current-2.month

[1] pry(main)> Time.current
=> Fri, 15 Sep 2017 18:22:33 JST +09:00
[2] pry(main)> Time.current-2.month
=> Tue, 15 Aug 2017 18:22:42 JST +09:00

x時間、x分、x秒後

俺は15分後が何時何分何秒か知りたいのだ、そんな時に。

require "date"
d =  DateTime.new(2017,4,1,0,0,0)

p d + Rational(1,24)
p d + Rational(1,24*60)
p d + Rational(1,24*60*60)

#<DateTime: 2017-04-01T01:00:00+00:00 ((2457845j,3600s,0n),+0s,2299161j)>
#<DateTime: 2017-04-01T00:01:00+00:00 ((2457845j,60s,0n),+0s,2299161j)>
#<DateTime: 2017-04-01T00:00:01+00:00 ((2457845j,1s,0n),+0s,2299161j)>

フォーマットの変更(日付型→文字列型)

よく使うやつ

strftime

Date.new(2017,9,7).strftime("%Y-%m-%d")
Time.new(2017,9,1).strftime("%Y-%m-%d")

rails

config/initializers/time_formats.rbを作成

Time::DATE_FORMATS[:ja] = "%Y年%m月%d日 %H時%M分"
Time::DATE_FORMATS[:ymd] = "%Y%m%d"

みたいな感じで好きにフォーマットつくれます。

使い方

Time.new(2017,9,1).to_s(:ja)

デフォルトで用意されているフォーマット

Time.new(2017,9,1).to_s(:default)=> "2017-09-01 00:00:00 +0900"
Time.new(2017,9,1).to_s(:long)=> "September 01, 2017 00:00"
Time.new(2017,9,1).to_s(:short)=> "01 Sep 00:00"
Time.new(2017,9,1).to_s(:db)=> "2017-09-01 00:00:00"

※defaultフォーマットを上書きすることで、デフォルトを変えることも可能

ja.ymlを使う

config/initializers/locale.rbを作成

I18n.default_locale = :ja

config/locales/ja.ymlを作成
https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/ja.yml
を流用させていただきます

irb(main):001:0> I18n.l(Time.current, format: :long)
=> "2017年09月20日(水) 19時46分15秒 +0900"

文字列を日付型に変換

strptime

date = Date.strptime('2017年9月1日','%Y年%m月%d日')
p date

#<Date: 2017-09-01 ((2457998j,0s,0n),+0s,2299161j)>

ハイフン区切り、スラッシュ区切りの日付なら、parseでいけます。

date = Date.parse('2017-9-7')
p date

#<Date: 2017-09-01 ((2457998j,0s,0n),+0s,2299161j)>

_strptimeとか_parse

Dateクラスには通常のメソッドにアンダースコア(_)が先頭についたメソッドがいくつかありまして、要素をハッシュで返してくれるようになります。

date = Date._strptime('2017年9月1日','%Y年%m月%d日')
p date
# {:year=>2017, :mon=>9, :mday=>1}

日付の差分

Date型は、ただ引くだけ

d = Date.new(2017,9,7)
d2 = Date.new(2017,10,11)

p d2-d
# (34/1)

# Rational型で返るので分子の値だけを取れば日付の差分が取得できます
p (d2-d).numerator
# 34

Timeでやると、秒数で出ちゃうので割ります

t  = Time.new(2017,9,7)
t2 = Time.new(2017,10,11)
p t2-t
p (t2-t)/24/60/60
# 2937600.0
# 34

月末、月初

ruby

月末はDateオブジェクトを作る時に日付の値に-1をいれてあげよう。

require "date"
d = Date.new(2017,9,-1)
p d
#<Date: 2017-09-30 ((2458027j,0s,0n),+0s,2299161j)>

dt = DateTime.new(2017,9,-1)
p dt
#<DateTime: 2017-09-30T00:00:00+00:00 ((2458027j,0s,0n),+0s,2299161j)>

t = Time.new(2017,9,-1)
p t
# /tmp/sample.rb:6:in `initialize': argument out of range (ArgumentError)
# Timeはエラー

rails(ActiveSupport)

rails使う場合は月末、月初を出すメソッドあります。
beginning_of_monthend_of_month

t = Time.new(2017,9.7)
# => 2017-09-01 00:00:00 +0900
t.beginning_of_month
# => 2017-09-01 00:00:00 +0900
t.end_of_month
# => 2017-09-30 23:59:59 +0900

23:59:59で出してくれるので助かるー

指定した日付の曜日を出す

require "date"
d = Date.new(2017,9,7)
p %w(日 月 火 水 木 金 土)[d.wday]

今週(来週)のhoge曜日の日付を出す

require "date"
this_day = Date.today
this_monday    = this_day - (this_day.wday - 1) # 今週
this_tuesday   = this_day - (this_day.wday - 2) # 今週
this_wednesday = this_day - (this_day.wday - 3) # 今週
next_wednesday = this_day - (this_day.wday - 3) + 7 # 来週

rails(activesupport)

t = Time.current
t.prev_week(:friday) # 先週の金曜日
t.next_week(:friday) # 来週の金曜日

t + (5 - t.wday).days # 今週の金曜日
t + (4 - t.wday).days # 今週の木曜日
126
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ykyk1218

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
126
Help us understand the problem. What is going on with this article?