🖥

#Ruby と #Rails の Time や Time.zone の扱いががマジで分からないし混沌としてるのでちょっとだけ整理したい。

2019/11/29に公開

Try at

この時間に試しました

  • JST 2019-11-28 hour 19
  • UTC 2019-11-28 hour 10

For Ruby

require ‘active_support/core_ext’

No Time zone setting

タイムゾーン指定がないとメソッドが使えなかったり

Time.zone
# nil

Time.zone.now
# NoMethodError: undefined method `now’ for nil:NilClass

Timezone指定

Time.zone は ActiveSupportのインスタンスになる
タイムゾーンを切り替えるには Time.zone= メソッドを実行

Railsであればapplication.rb の configに書くだろうが

タイムゾーン指定自体は Tokyo でも Asia/Tokyo でも同じようにはからってくれるっぽい
ちなみに Time.zone = ‘JST’ じゃ動かないとか信じられるかい

Time.zone = 'UTC'
=> "UTC"
Time.zone
=> #<ActiveSupport::TimeZone:0x00007f8610941ef0 @name="UTC", @tzinfo=#<TZInfo::DataTimezone: Etc/UTC>, @utc_offset=nil>

=> #<ActiveSupport::TimeZone:0x00007f86108d1a38 @name="Asia/Tokyo", @tzinfo=#<TZInfo::DataTimezone: Asia/Tokyo>, @utc_offset=nil>
Time.zone = 'Tokyo'
=> "Tokyo"
Time.zone

Time.zone = 'Asia/Tokyo'
=> "Asia/Tokyo"
Time.zone
=> #<ActiveSupport::TimeZone:0x00007f86108d1a38 @name="Asia/Tokyo", @tzinfo=#<TZInfo::DataTimezone: Asia/Tokyo>, @utc_offset=nil>


Time.zone = 'JST'
# ArgumentError: Invalid Timezone: JST

UTC

UTCをtimezone指定した場合

Time.zone =UTC# => “UTC”

Time.zone
# => #<ActiveSupport::TimeZone:0x00007fe40e15ed08 @name=“UTC”, @tzinfo=#<TZInfo::DataTimezone: Etc/UTC>, @utc_offset=nil>

Time.zone.now
# => Thu, 28 Nov 2019 10:00:31 UTC +00:00

Time.zone.parse(2020-01-01 00:00:00)
# => Wed, 01 Jan 2020 00:00:00 UTC +00:00

JST

JSTをtimezone指定した場合

Time.zone = ‘Tokyo’
# => “Tokyo”

Time.zone
# => #<ActiveSupport::TimeZone:0x00007fe40d2721a0 @name=“Tokyo”, @tzinfo=#<TZInfo::DataTimezone: Asia/Tokyo>, @utc_offset=nil>

Time.zone.now
# => Thu, 28 Nov 2019 19:00:47 JST +09:00

Time.zone.parse(2020-01-01 00:00:00)
# => Wed, 01 Jan 2020 00:00:00 JST +09:00

Time系

こちらはRuby系なので Time.zone を参照しない、というより Time.zone なんていうメソッドもクラスもない
Rails = ActiveSupport の Time.zone 系メソッドとは分けて考えること

Ruby で最初から出来るかと思いきや、 一部のメソッドは requireが必要という罠 -> Time.parse とか
require active support でも動くようになるので、まさかのactivesupportのメソッドかと思って驚いたが違った

タイムゾーンを変えるには ruby実行時の環境変数を変える

TZ=UTC ruby ...
TZ=Asia/Tokyo ruby ...

環境変数指定もしくはシステムのタイムゾーンによって結果が変わる
Rubyだけの処理でもタイムゾーン情報を持っているようだ

Time.now
# => 2019-11-28 10:19:37 +0000

Time.now
# => 2019-11-28 19:19:43 +0900

# Time.parse / Time.zone.parse

Time.parse(2020-01-01 00:00:00)
# NoMethodError: undefined method `parse’ for Time:Class

Time.parse(2020-01-01 00:00:00)
# => 2020-01-01 00:00:00 +0900

Time.zone =UTC# => “UTC”

Time.zone.parse(2020-01-01 00:00:00)
# => Wed, 01 Jan 2020 00:00:00 UTC +00:00

RubyっぽいのにRails? current系

nowじゃなくてcurrentっていう名前のメソッドはRubyじゃなくてRails/AcviveSupportのものだ

Time.current
# NoMethodError: undefined method `current’ for Time:Class

require ‘active_support/core_ext’

Time.current
# => 2019-11-28 19:21:56 +0900

なのにclassTimeという奇特なやつ

Time.current.class
# => Time

ちなみに Date.today は Ruby のものだが Date.current Date.yesterday Date.tomorrow は Railsのものだという大いなる罠もある

Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2774

チャットメンバー募集

何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ

Twitter

https://twitter.com/YumaInaura

公開日時

2019-11-29

Discussion