システム開発において「日付や時刻」を扱うことは多く、Rubyでも例外なく日付処理は必須知識と言えるでしょう。
Rubyでは、日時を扱うクラスにDateTimeとTimeクラスの大きく2つが存在します。
この記事では、DateTimeクラスの使い方について解説していきます。
「DateTime」クラス
では、DateTimeクラスを使い方を見ていきましょう。
DateTimeクラスは、Dateクラスから派生したクラスで、そこに時刻を扱うためのメソッドなどが加わったイメージのクラスです。
DateTimeクラスを使い場合は、必要なライブラリを次のとおりrequireで読み込んでおく必要があるため、とりあえず入れておきましょう。
require 'date'
DateTimeの基本的な使い方
requireを行って、DateTimeクラスを使う準備ができたら、基本的な使い方から学習していきましょう。
現在時刻を取得する
現在時刻の取得は、おそらく日付処理の中でも最も多くのシーンで利用するでしょう。
RubyのDateTimeクラスでは、引数なしのnewメソッドで現在時刻が取得できます。
p DateTime.now
【実行結果】
-----------------------------------
#<DateTime: 2020-12-14T22:52:35+09:00 ((2459198j,49955s,356985000n),+32400s,2299161j)>
特定日時のDateTimeオブジェクトを作成
newメソッドの引数を指定することで、特定日時のDateTimeオブジェクトを作成できます。
## 年月日時分秒の順に指定して、DateTimeオブジェクトを作成
dt = DateTime.new(2020, 12, 14, 10, 20, 45);
## 日付オブジェクトの内容をコンソールに出力
p dt.strftime("%Y/%m/%d %H:%M:%S")
【実行結果】
-----------------------------------
"2020/12/14 10:20:45"
newメソッドの引数に存在しない日時を指定すると、次のようなエラーが発生するため、注意が必要です。
require 'date'
## 月に存在しない日付を指定して「DateTime.new」を呼び出し
dt = DateTime.new(2020, 30, 14, 10, 20, 45);
【実行結果】
-----------------------------------
Traceback (most recent call last):
1: from com.rb:4:in `<main>'
sample.rb:4:in `new': invalid date (ArgumentError)
(base) satonoMBookpuro:samples sato$
日時の計算(加算・減算)
DateTimeクラスで、日付や時間を加減算を次のようにして行えます。
月の加算・減算
dt = DateTime.new(2020, 11, 1, 10, 20, 0); # 2020/11/1 10:20:00
after = dt >> 1 #加算
before = dt << 1 #減算
日付の加算・減算
dt = DateTime.new(2020, 11, 1, 10, 20, 0); # 2020/11/1 10:20:00
before = dt + 1 #加算
after = dt - 1 #減算
時間の加算・減算
dt = DateTime.new(2020, 11, 1, 10, 20, 0); # 2020/11/1 10:20:00
dt + Rational("1/24") # 1時間後
dt - Rational("1/24") # 1時間前
分の加算・減算
dt = DateTime.new(2020, 11, 1, 10, 20, 0); # 2020/11/1 10:20:00
dt + Rational(1, 24 * 60) # 1分後
dt - Rational(1, 24 * 60) # 1分前
秒の加算・減算
dt = DateTime.new(2020, 11, 1, 10, 20, 0); # 2020/11/1 10:20:00
dt + Rational(1, 24 * 60 * 60) # 1秒後
dt - Rational(1, 24 * 60 * 60) # 1秒前
2つの時間の差分を求める
2つのDateTimeクラスのオブジェクトを–で減算することで、時間の差分を求められます。
また、時間の差分はRationalオブジェクトで返され、値が1の時は2つの日付の差が1日であることを表します。(時間の差は小数点以下の数字を計算する)
dt1 = DateTime.new(2020, 11, 1, 10, 20, 0); # 2020/11/1 10:20:00
dt2 = DateTime.new(2020, 11, 5, 11, 30, 20); # 2020/11/5 11:30:20
## 2つのDateTimeオブジェクトの差分を表示
diff = dt2 - dt1
## 差分を求めた結果は「Rational」クラスで返る
p diff.class
## 日付・時間・分・秒の差をそれぞれ表示
p "日付の差=%d" % diff.to_i
p "時間の差=%d" % (diff * 24).to_i
p "分の差=%d" % (diff * 24 * 60).to_i
p "秒の差=%d" % (diff * 24 * 60 * 60).to_i
【実行結果】
-----------------------------------
Rational
"日付の差=4"
"時間の差=97"
"分の差=5830"
"秒の差=349820"
タイムゾーン(時差)の指定
Rubyでは、タイムゾーンのデフォルト値は、はシステム(OS)の設定および、環境変数(ENV=TZ)によって決まり、環境変数の方が優先して使用されます。
DateTimeクラスにタイムゾーンを指定する
デフォルトのタイムゾーン以外に、個別にDateTimeオブジェクトに時差を指定することも可能です。
個別にタイムゾーンを指定する場合、DateTime.newメソッドの最後の引数に、世界標準時(UTC)からの時差を+0900のような形式で指定します。
## -05:00時間の時差でDateTimeオブジェクトを作成
dt = DateTime.new(2020, 12, 10, 19, 0, 0, "-0500")
p dt.rfc3339
【実行結果】
-----------------------------------
"2020-12-10T19:00:00-05:00"
インスタンス作成済みのDateTimeオブジェクトのタイムゾーンを変更する場合は、new_offsetメソッドを使用して、指定したタイムゾーンのDateTimeオブジェクトを新たに作成します。
## -05:00時間の時差でDateTimeオブジェクトを作成
dt = DateTime.new(2020, 12, 10, 19, 0, 0, "-0500")
p dt.rfc3339
## +09:00の時差に変更した新しいDateTimeオブジェクトを作成
new_dt = dt.new_offset('+0900')
p new_dt.rfc3339
【実行結果】
-----------------------------------
"2020-12-10T19:00:00-05:00"
"2020-12-11T09:00:00+09:00"
さいごに
RubyのDateTimeクラスの基本的な使い方を紹介してきました。
日付・時刻に関連する処理は、どのようなシステム開発においても必ず存在するため、是非DateTimeクラスの使い方を覚えておきましょう。
指定できるタイムゾーンの一覧は、次のリンクを確認してください。
https://en.wikipedia.org/wiki/List_of_tz_database_time_zones