【Ruby入門】日付・時刻の扱い方(Date、DateTime、Time)


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は標準ライブラリとしてインストールされているので、追加でインストールする必要はありません。

学習のポイントを振り返ってみましょう。

・Dateクラスは日付を扱える。時間は扱えない。
・DateTimeクラスは日付、時間を共に扱える。
・Timeクラスは日付、時間を共に扱える。Rubyで日付、時間を扱うときは、通常Timeクラスを扱う。
・Timeクラスを扱う時は、通常RailsのActiveSupportも使用する。
・Timeクラスで日付、時間の比較ができる。
・strftimeで、日付、時間をフォーマットされた文字列として文字列化できる。
・strptimeで、日付、時間のフォーマットされた文字列からTimeクラスのオブジェクトに戻すことができる。日本語のフォーマットでも可能。
・Timeクラスとunix時間を、to_iメソッドとatメソッドで相互変換できる。

この記事を参考に是非使ってみてください!

この記事を書いた人

【プロフィール】
DX認定取得事業者に選定されている株式会社SAMURAIのマーケティング・コミュニケーション部が運営。「質の高いIT教育を、すべての人に」をミッションに、IT・プログラミングを学び始めた初学者の方に向け記事を執筆。
累計指導者数4万5,000名以上のプログラミングスクール「侍エンジニア」、累計登録者数1万8,000人以上のオンライン学習サービス「侍テラコヤ」で扱う教材開発のノウハウ、2013年の創業から運営で得た知見に基づき、記事の執筆だけでなく編集・監修も担当しています。
【専門分野】
IT/Web開発/AI・ロボット開発/インフラ開発/ゲーム開発/AI/Webデザイン

目次