RubyのDateTimeにタイムゾーンを指定する

Ruby

時刻を扱うのはどの言語でも大変です。今回私がプログラムを書いていく中で時差に悩まされたのですが、そのときに少しでも知っておけば楽だったなぁということについて書いていこうと思います。

DateTimeオブジェクトを作る

DateTimeを使うためには標準ライブラリを読み込む必要があります。なので忘れずに読み込むようにしましょう。
以下のようにしてDateTimeオブジェクトを作成します。

require 'date'

datetime = DateTime.now # 現在時刻を取得
datetime = DateTime.new(2010, 2, 3, 4, 55, 50, "+09:00") # => 2010年2月3日4時55分50秒 日本時刻(時差9時間)で作成
datetime = DateTime.parse("2018-06-19T17:36:25+09:00")

これでDateTimeオブジェクトを作成することが出来ました。次に上のコードで指定してあるタイムゾーンを変更したいと思います。変更するには主に2つのやり方がわかりやすいかと思います。

DateTimeにタイムゾーンを設定する2つの方法

以下の2つのやり方で変更可能です。コードはさきほどのものと同じ部分も書いてあります。

require 'date'

datetime = DateTime.now # 現在時刻を取得
datetime = DateTime.new(2010, 2, 3, 4, 55, 50, "+09:00") # => 2010年2月3日4時55分50秒 日本時刻(時差9時間)で作成
datetime = DateTime.parse("2018-06-19T17:36:25+09:00")

new_datetime = datetime.new_offset(Rational(1, 24)) # Rationalの第1引数に時差を入力する
new_datetime.to_s # => "2018-06-19T09:36:25+01:00"

new_datetime = datetime.new_offset('-01:00') # 時差を左の形で入力する
new_datetime.to_s # => "2018-06-19T07:36:25-01:00"

これがあればタイムゾーンに関してはある程度耐えきれるかと思います。

時刻表示に関する色々な種類

タイムゾーンを付与した表示形式は色々な提案がなされており、種類がたくさんあってなかなか骨が折れます。例えば"Tue, 19 Jun 2018 17:36:25 +0900"RFC2822から出来ていますし、"2018-06-19T17:36:25+09:00"ISO 8601と呼ばれる種類です。ある程度の種類を知っておくことで見たことがあれば焦ることも減りますので以下にDateTimeで表示出来る形式の一覧を書き出しておきます。

require 'date'

datetime = DateTime.parse("2018-06-19T17:36:25+09:00")

# RFC2616で定義されているrfc1123-date形式
datetime.httpdate # => "Tue, 19 Jun 2018 08:36:25 GMT"
# RFC2822
datetime.rfc2822 # => "Tue, 19 Jun 2018 17:36:25 +0900"
# RFC3339
datetime.rfc3339 # => "2018-06-19T17:36:25+09:00"
# JISX0301
datetime.jisx0301 # => "H30.06.19T17:36:25+09:00"

datetime.zone # => "+09:00"

参考リンク