Rubyで日付の扱い方がわからない
日付を扱うクラスが多すぎてどれを使えば良いかわからない
日付の計算方法がわからない
日付や時刻の操作はプログラミングをする上で必須の知識になってきます。しかしRubyで日付や時刻を扱うとなると、上記のような疑問がでてくるのではないでしょうか?
そこでこの記事ではrubyの日付や時刻の扱い方について、基本から応用的な使い方まで解説していきます。
Ruby日付を扱うためのクラス
Rubyで日付を扱うクラスは、以下の3つがあります。
- Dateクラス
- DateTimeクラス
- Timeクラス
それでは、それぞれの使い方を見ていきましょう。
Dateクラス
Dateは日付を扱うことができるクラスで、時刻を扱うことはできません。
require "date" puts date = Date.today # 2019-06-26 puts date.year # 2019 puts date.month # 6 puts date.day # 26 puts date.wday # 3 puts date.yday # 177
上のソースコードを見ていただくとわかる通り、Dateクラスを使用するためには、dateというライブラリをrequireで読み込む必要があります。
また、yearやmonthなどのメソッドを使用することで、それぞれの値を取り出すことができます。
Dateクラスで指定した日付を取得するには以下のように記述します。
require "date" # 指定した日付を取得する puts date = Date.new(2018, 7, 30); # 2018-07-30
DateTimeクラス
DateTimeクラスは、Date Timeという名前の通り、日付と時間を扱うことができるクラスです。
require "date" puts date = DateTime.now # 2019-06-26T04:17:29+00:00 puts date.year # 2019 puts date.hour # 4 puts date.min # 17 puts date.sec # 29 puts date.wday # 3 puts date.yday # 177 puts date.zone # +00:00
DateTimeクラスにnowを指定することで現在の日時を取得することができます。DateTimeもDateと同じく、dateをrequireする必要があります。
Timeクラス
TimeクラスはDateTimeと同じく、日時と時間を扱うことができます。
puts date = Time.now # 2019-06-26 04:19:39 +0000 puts date.year # 2019 puts date.hour # 4 puts date.min # 19 puts date.sec # 39 puts date.wday # 3 puts date.yday # 177 ※この年の1月1日から何日経過したか puts date.zone # UTC ※タイムゾーンの確認
dateと同じで”.”以下に”year”や”min”などを指定することで、分や時間などの情報を切り出すことができます。
Date、DateTimeとTimeの差
ここまで三種類の、時間を扱うためのクラスを紹介していきましたが、
と感じた方も多いと思います。
しかし、些細ですが以下のような差があります。
- Timeの使用にrequireが必要ない
- サマータイムが扱える
- うるう秒を数えられる
これを見てみると、Timeの方が少し高機能になることがわかります。そのため、Rubyで日付、時間を扱う際は基本的にTimeを使用するようにしてください。
また、以降この記事の解説では日付の計算はTimeを用いて行います。
日付を自在に操る
日付を取得することができても、それを操ることができないと、実際に使用することはできません。そのため、この章では日付の計算や比較について解説していきたいと思います。
ただ、Timeはそのままだと非常に操作しにくいクラスです。
なのでactive_supportを言うgemを用いて操作していきます!
active_supportのインストール
まずはactive_supportがインストールされているか確認します。
以下のコマンドを入力してください。
$ gem list
[実行結果]に”activesupport”がない場合は次のコマンドでインストールしてください。
$ gem install activesupport
再度以下のコマンドを実行して”activesupport”があるか調べて下さい。
$ gem list
activesupportがあればOKです。
active_supportを用いた時間の加算、減算
それではactive_supportを用いて、日付の加算や減算を行いましょう。
require "active_support/time" time = Time.now puts time + 10 # 2019-06-26 13:25:31 +0900 ※10秒後 puts time + 1.hour # 2019-06-26 14:25:21 +0900 ※1時間後 puts time + 1.week # 2019-07-03 13:25:21 +0900 ※1週間後
ここで一つ注意点なのですが
require "active_support"
ではactive_supportの中の適切なライブラリが読み込まれず、実行されません。
require "active_support/time"
と書くようにしましょう。また、単純な加算や減算以外にも、昨日、明日、来週などを求めるメソッドも存在します。
require "active_support/time" time = Time.now puts time.yesterday #昨日 puts time.tomorrow #明日 puts time.prev_week#先週 puts time.next_week#来週 puts time.prev_month#先月 puts time.next_month#来月 puts time.prev_year#去年 puts time.next_year#来年
比較
数字と同じように日付も、不等号で比較を行うこともできます。
require "active_support/time" time = Time.now puts time.yesterday < time # true puts time < time.tomorrow # true
未来の方が大きな値であるといえます。DateTimeでも日付の比較を行うことができます。
詳しくは、以下の記事を参照してください。
strftimeでformatを整える
rubyでフォーマット(format)を整えるにはstrftimeメソッドを使います。
require "date" datetime = Time.new(2017, 2,5, 8, 9, 30) p datetime.strftime('%Y-%m-%d %H:%M:%S') # "2017-02-05 08:09:30" p datetime.strftime('%Y年%m月%d日 %H時%M分%S秒') # "2017年02月05日 08時09分30秒" p datetime.strftime('%Y/%m/%d %H:%M:%S') # "2017/02/05 08:09:30" p datetime.strftime('%F %T') # "2017-02-05 08:09:30"
- 年を取り出すには%Y
- 月を取り出すには%m
- 日を取り出すには%d
- 時を取り出すには%H
- 分を取り出すには%M
- 秒を取り出すには%S
小文字の%mは月で、大文字の%Mは分を表すので注意しましょう。また、それぞれの実行結果は以下のようになります。
- %F = %Y-%m-%d
- %T = %H:%M:%S
最低限この取り出し方が分かっていれば、フォーマットを指定して読みやすいように変換できます。
strptimeでformatされた時間を元に戻す
さきほどはstrftimeメソッドでフォーマットを指定しましたが、その逆でフォーマットが指定されているものからTimeに戻すにはstrptimeメソッドを使用します。
サンプルコードではstrftimeメソッドでフォーマットを指定したものを再びstrptimeメソッドでもとのTimeに戻しています。
require 'time' datetime = Time.new(2017, 2,5, 8, 9, 30) datetime_strf = datetime.strftime('%Y-%m-%d %H:%M:%S') p datetime # 2017-02-05 08:09:30 +0900 p datetime_strf # "2017-02-05 08:09:30" p Time.strptime(datetime_strf,'%Y-%m-%d %H:%M:%S') # 2017-02-05 08:09:30 +0900
このように、strptimeメソッドを使えば、strftimeメソッドでフォーマットを整えた時間をまたrubyのクラスで扱える時間に変換できます。
strptimeで日本語でformatされた時間を元に戻す
Timeクラスのstrptimeメソッドでは、日本語でフォーマットされた時間の文字列も、元のTimeクラスのオブジェクトに戻すことができます。なお、月や日の前にスペースが空いているフォーマット文字列を元に戻すには、%mや%dの前に半角スペースを置きます。
こうすることで、月や日の前にスペースが空いていても、空いていなくても、正しくeオブジェクトに戻せます。
require 'time' p Time.strptime("2020年04月01日 01:20:30","%Y年%m月%d日 %H:%M:%S") # 2020-04-01 01:20:30 +0900 p Time.strptime("2020年 2月 3日 8: 5: 0"," %Y年 %m月 %d日 %H: %M: %S") # 2020-02-03 08:05:00 +0900
以上のように、strptimeの第2に引数に年・月・日など日本語の文字を指定することにより、日本語でフォーマットされた時間の文字列から、Timeオブジェクトに変換することができます。
unix時間を扱う方法
Timeをunix時間に変換するにはto_iメソッドを使うだけです。また、unix時間から逆にTimeを得るにはatメソッドを使います。
datetime = Time.new(2017, 2,5, 8, 9, 30) unixtime = datetime.to_i p datetime # 2017-02-05 08:09:30 +0900 p unixtime # 1486249770 p Time.at(unixtime) # 2017-02-05 08:09:30 +0900
このように、作成したunix時間から再びTimeに戻すことができました。
まとめ
今回はRubyで日付を扱う方法について解説していきました。
RubyではTimeクラスで日付を扱うことがほとんどで、active_supportというgemを入れることで、Timeクラスをより使いやすくなります。
Rubyを勉強する方はRailsを使うことも多いと思いますが、Railsではこのactive_supportというgemは標準ライブラリとしてインストールされているので、追加でインストールする必要はありません。
学習のポイントを振り返ってみましょう。
・DateTimeクラスは日付、時間を共に扱える。
・Timeクラスは日付、時間を共に扱える。Rubyで日付、時間を扱うときは、通常Timeクラスを扱う。
・Timeクラスを扱う時は、通常RailsのActiveSupportも使用する。
・Timeクラスで日付、時間の比較ができる。
・strftimeで、日付、時間をフォーマットされた文字列として文字列化できる。
・strptimeで、日付、時間のフォーマットされた文字列からTimeクラスのオブジェクトに戻すことができる。日本語のフォーマットでも可能。
・Timeクラスとunix時間を、to_iメソッドとatメソッドで相互変換できる。
この記事を参考に是非使ってみてください!