Rubyで日付・時刻を扱うならTimeクラスに決まり!

結論から言えば、Rubyで時刻を扱うにはTimeクラスがメリットが多いのでおすすめです。

Rubyには時間を取り扱うクラスはたくさんありますが、なかでもよく使われるDateTime、Timeについて以下の内容で解説していきます。


【基礎】Time型、DateTime、Date型の違い
【基礎】各クラスの日時の表示のさせ方
【基礎】各クラスの計算方法
【発展】各クラスを他のTime系のクラスに変換する方法

この記事ではそんなTime、DateTimeの違いや使い方についてわかりやすくまとめていますので、ぜひ参考にしてください!

目次

Time、DateTime、Dateとは

日付を扱うことのできるクラスは、

  • Dateクラス
  • DateTimeクラス
  • Timeクラス

の3つがあります。

Dateクラスは日付のみしか扱うことができませんが、DateTimeクラス、Timeクラスは時間も扱うことができます。

で、時間や日付を扱うのには主にこの3つがあるのですが結局どれが一番よいのでしょうか?

結論からいってしまうとTimeクラスが基本です。

メリットとして、

  • Datetimeより早い
  • サマータイム、うるう秒が扱える
  • requireで読み込む必要がない

と、この辺りでしょうか。

Datetimeより、早く読み込めますし、requireで事前に読み込む必要がないので基本的にはTimeをサクッと使ってしまえば問題ないです。

ただ、Datetimeは時差が確認できたり、より柔軟に日時を表現することが可能なので必要であれば使うこともあるでしょう。

ここらへんの詳しい説明は以下で説明しているので知りたい方は参考にしてください。

Timeを使ってみよう!

ではそんな便利なTimeクラスの実際の使い方を見ていきましょう。

現在時刻はTime.newTime.nowでオブジェクトを作成することができます。

時間を指定する場合はTime.local(カンマで区切って時刻指定)です。

日時を取得する

それでは実際に現在の日時を表示させてみましょう。

nowis = Time.new    
p nowis
2018-03-20 22:43:15 +0900

はい、特に説明はいりませんね。

Time.newでオブジェクトが生成できています。

では、現在の日時だけではなく、様々な時間の切り取り方をしてみましょう。

nowis = Time.new
p [nowis.year, nowis.month, nowis.day, nowis.hour, nowis.min, nowis.sec]
[2018, 3, 20, 22, 50, 14]

はい、このように作成したオブジェクトから細かい値を個別に取り出すことも可能です。

他にもタイムゾーンや曜日に番号を振ったものなど色々あるので応用してみるとよいでしょう。

では次は、日時を指定して表示してみましょう。

nowis = Time.local(2018,3,22,10)
p nowis
2018-03-22 10:00:00 +0900

思ったように動作していますね。

文字列を日付型に変換する

次は文字列として表示されている時間を実際の時間に変換してみましょう。

変換するにはまずrequireでtimeを読み込む必要があります。

また、Time.parceが基本です。

実際にみてみましょう。

require "time"
time = "20180320224618"
p Time.parse(time)

このように無造作に並んでいても、

2018-03-20 22:46:18 +0900

キレイに時間として変換してくれます。

かなり柔軟にパースしてくれるのでみなさんも色々試してみてください!

日時を計算する

もちろんTimeをつかって時間同士や日付の計算をすることも可能です。

基本1の単位は秒であるということを覚えておくと良いでしょう。

nowis = Time.new
p nowis + 10
p nowis + 60*60*24

このように今から10秒後を表示したければ10ですし、1日後であれば1秒を基準に計算してやれば良いです。

2018-03-20 23:05:51 +0900
2018-03-21 23:05:41 +0900

はい、うまく表示されました。

Timeを使った計算についてより詳しく知りたい方はこちらの記事で書かれているのでぜひ見てみてください。

Dateを使ってみよう!

では、日付を表示するDateの使い方も簡単に見ておきましょう。

Dateクラスを使うときはrequireでdateを読み込む必要があります。

現在の日付であればDate.today、日付を指定するのであればDate.new(カンマ区切りで日付)が基本です。

では現在の日付から取得してみましょう。

require "date"

p Date.today
#<Date: 2018-03-20 ((2458198j,0s,0n),+0s,2299161j)>

日付を指定して取得すると、

require "date"

p Date.new(2018,3,23)
#<Date: 2018-03-23 ((2458201j,0s,0n),+0s,2299161j)>

はい、簡単ですね。

因みに月末などを指定することもでき、-1を指定してやれば良いです。

require "date"

p Date.new(2030,4,-1)
#<Date: 2030-04-30 ((2462622j,0s,0n),+0s,2299161j)>

その月が何日まであるかパッとわからないときなどに便利ですね。

DateTimeを使ってみよう!

基本的には余り使うことのないDatetimeですが、DateとTimeの良いとこを兼ね合わせているので説明しておきます!

require “date”をする必要があるので忘れないようにしましょう。

オブジェクトは現在時刻ならDatetime.now、特定の日時ならDatetime.now(日時)ですね。

日時を取得する

なにはともあれまずは実際に使ってみましょう。

現在の時刻を表示してみます。

require "date"

nowis = DateTime.now
nowis2 = DateTime.now.to_time
p nowis
p nowis2
#<DateTime: 2018-03-21T20:47:47+09:00 ((2458199j,42467s,235623000n),+32400s,2299161j)>
2018-03-21 20:47:47 +0900

余談ですが、to_timeオプションを追加することで人間に見やすい状態で表示してくれます。

では時刻を指定して使ってみます。

require "date"

nowis = DateTime.new(2020,4,5,9,20,30)
p nowis.to_time
2020-04-05 18:20:30 +0900

日時を計算する

では、Datetimeを使った計算を見てみましょう。

Timeでは1の単位は秒でしたが、DateTimeでは1の単位を日として扱うため、1時間を1/24、1分を1/(24×60)、1秒を1/(24×60×60)として計算に使用することができます。

2020年4月1日0時0分0秒にそれぞれ1日、1時間、1分、1秒を足すには以下のように記述します。

Rationalクラスを使用すると分数を扱うことができます。

さらに、出力後の表示がわかりやすいようにto_datetimeを付けて実行してみましょう。

require 'date'
 
n =  Time.new(2020,4,1,0,0,0).to_datetime
 
day = n + 1
hour = n + Rational(1,24)
min = n + Rational(1,24*60)
sec = n + Rational(1,24*60*60)

p day.to_time
p hour.to_time
p min.to_time
p sec.to_time

[実行結果]

2020-04-02 00:00:00 +0900
2020-04-01 01:00:00 +0900
2020-04-01 00:01:00 +0900
2020-04-01 00:00:01 +0900

それぞれ1ずつ加算されていることがわかりました。

減算も加算と同じように1を1日として計算します。

記述も加算の+(プラス)部分を-(マイナス)に変更するだけです。

2020年4月1日0時0分0秒にそれぞれ1日、1時間、1分、1秒を引くには以下のように記述します。

require 'time'

n =  Time.new(2020,4,1,0,0,0).to_datetime

day  = n - 1
hour = n - Rational(1,24)
min  = n - Rational(1,24*60)
sec  = n - Rational(1,24*60*60)

p day.to_time
p hour.to_time
p min.to_time
p sec.to_time

[実行結果]

2020-03-31 00:00:00 +0000
2020-03-31 23:00:00 +0000
2020-03-31 23:59:00 +0000
2020-03-31 23:59:59 +0000

フォーマットを指定する

では今まで、日時を指定してきましたが、日時の何円何月などformatを指定したいというときもあると思います。

そのようなときはstrftimeオプションを指定してやれば良いです。

require "date"
 
nowis = DateTime.new(2020,4,5,10)
p nowis.strftime("%Y年 %m月 %d日")
"2020年 04月 05日"

このように対応した値が%Y、%m、%dなどに埋め込まれています。

指定できる値は、

指定フォーマットで文字列に変換する

こちらに詳しく書かれているので参照してみましょう。

DateTime・Date・Timeの変換

DateTime型、Date型、Time型は互いに型変換することができます。

以下、それぞれの変換方法を見ていきましょう。

DateTimeの変換

DateTime型をDate型、Time型に変換して出力してみます。

DateTime型の変数にto_date、to_timeメソッドを使用することで変換することができます。

require "date"
dtime =  DateTime.new(2020,4,1,12,30,25)

p dtime
p dtime.to_date
p dtime.to_time

[実行結果]

#<DateTime: 2020-04-01T12:30:25+00:00 ((2458941j,45025s,0n),+0s,2299161j)>
#<Date: 2020-04-01 ((2458941j,0s,0n),+0s,2299161j)>
2020-04-01 21:30:25 +0900

最初に出力したDatetime型がDate型、Time型に変換されているのがわかります。

Dateの変換

今度はDate型をDateTime型、Time型に変換して出力してみます。

上でも書いたようにDate型は日付しか扱えないので日付を変換してみましょう。

Date型を入れた変数にto_datetime、to_timeメソッドを使用します。

require "date"
d =  Date.new(2020,4,1)

p d
p d.to_datetime
p d.to_time

[実行結果]

#<Date: 2020-04-01 ((2458941j,0s,0n),+0s,2299161j)>
#<DateTime: 2020-04-01T00:00:00+00:00 ((2458941j,0s,0n),+0s,2299161j)>
2020-04-01 00:00:00 +0900

最初に出力したDate型がDatetime型、Time型に変換されているのがわかります。

Timeの変換

最後にTime型をDateTime型、Date型に変換して出力してみます。

Time型を入れた変数にto_datetime、to_dateメソッドを使用します。

require "date"
t =  Time.new(2020,4,1,12,30,25)

p t
p t.to_datetime
p t.to_date

[実行結果]

2020-04-01 12:30:25 +0900
#<DateTime: 2020-04-01T12:30:25+09:00 ((2458941j,12625s,0n),+32400s,2299161j)>
#<Date: 2020-04-01 ((2458941j,0s,0n),+0s,2299161j)>

最初に出力したTime型がDatetime型、Date型に変換されているのがわかります。

すべてto_変換したい型名メソッドを使用するだけなので簡単に変換できますね。

まとめ

はい、今回は

・Datetime、Time、Dateの違い
・日時の表示のさせ方
・計算の仕方
・変換の仕方

など紹介してきました。

基本的にはTimeを使えば事足りるということを覚えておくと良いでしょう。

日時の取り扱いは必須事項なので是非マスターシておいてください!それでは!

この記事を書いた人

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

目次