本記事はメモ記事ですので修正・加筆する可能性が高いです。
ご了承下さい。
自分も勉強しながらなので記事はちょっとずつ整っていく予定です。
私の環境
環境
- Windows Subsystem for Linux (Ubuntu 18.04)
- Rails 5.2.0
- Ruby 2.5.3
超基本事項
とりあえずこれは知ってないとマズいという事項を。
普段、そんなにいろいろ暗記する必要はないと思う、とは言っていますがこれくらいは暗記必須ですね。
Timeクラス
Time.now #=> 2019-02-25 21:03:19 +0900 # ENV['TZ']またはOSのTimeZoneを見ている Time.current #=> Mon, 25 Feb 2019 12:03:19 UTC +00:00 # Railsのapplication.rbのconfig.time_zoneをみている Time.new(2019,1,2,3,4,5) #=> 2019-01-02 03:04:05 +0900
『今』の情報がほしければ『Time.now』。これは覚えておきましょう。
『Time.current』でも今の情報が取れますがnow
とは参照するタイムゾーンが異なります(タイムゾーンに関しては後述)。
特定の日時オブジェクトがほしければ『Time.new』に年、月、日、時、分、秒の順に引数を指定すればOKです。
Dateクラス
Date.today #=> Mon, 25 Feb 2019 Date.new(2019,1,2) #=> Fri, 01 Mar 2019
『今日』という情報がほしければ『Date.today』。必須ですが覚えやすいですよね。
これに関しても『Date.current』でTimeと同じようにapplication.rbの設定を参照する『今日』が取得できます。
こちらも『Date.new』に年、月、日の引数を指定すればOKです。
DateTimeクラス
DateTime.now #=> Mon, 25 Feb 2019 21:03:27 +0900
Dateクラスのサブクラスで時間情報も扱えるようになったもの。
時間情報があるので『DateTime.now』で今の情報が取れます。
これも『DateTime.current』は先の2つと同様です。
ここで『Timeクラスとどう違うのか』という疑問が生まれますが、多少の違いはあれど大きな差はなく『基本的にTimeクラスを使っておけばいい』らしいので、今回は難しいことを考えずDateTimeクラスはおいておくことにします。
タイムゾーンについて
タイムゾーン(TZ)という概念を知っておかなくてはいけません。
要は『時差』を考慮する方法のことですね。
コンピュータの世界では標準をUTC (協定世界時:Coordinated Universal Time)としています。これは日本よりも9時間遅い時刻、つまりUTCからみるとJST (日本標準時:Japan Standard Time) は9時間進んでいると表現することができます。
先程Time.now
で得られたオブジェクトに書かれていた2019-02-25 21:03:19 +0900
の後ろについている『+0900』というのがそれを表しています(おそらく +09時間00分という意味)。
これはどこの設定を見ているかと言うと、次のようになっています。
素のRubyの場合
優先されるのは環境変数`TZ`の値。これが設定されていなければシステム (OS)の設定が利用されるようです。
というわけで.bash_profileなどに`export TZ=”Asia/Tokyo”`とか書いてsourceしておけばOKです。
(タイムゾーンの設定用IDに関してはこちらに書いてありました)
Railsの場合
config/application.rb
に設定を書いておくことができます。
config.time_zone = 'Tokyo' config.time_zone = 'Asia/Tokyo' # どちらでもOK
上にも少し書きましたが、『Time.now』『Date.today』『DateTime.now』は環境変数またはシステムのタイムゾーン設定を、『Time.current』などのcurrent
は`application.rb`に設定したタイムゾーン設定が利用されます。
つまりこれらを同じにしている場合はnowもcurrentも値は同じ、みたいなことになります。
Time.now #=> 2019-02-25 22:24:00 +0900 Time.current #=> Mon, 25 Feb 2019 13:24:00 UTC +00:00 # application.rb に config.time_zone = 'Tokyo' を設定後 Time.current #=> Mon, 25 Feb 2019 22:24:00 JST +09:00
各クラスのメソッド
Timeクラス
とりあえず調べたのをひたすらまとめておきますが、もちろん全部覚える必要はないので使いやすくて覚えやすい書き方をおさえておけばいいと思います。
time = Time.now time + 10 # 10秒後 time + 10.seconds # これも10秒後 time + 10.minutes # 10分後 time + 10.hours # 10時間後 time + 10.days # 10日後 time + 10.weeks # 10週後 time + 10.months # 10ヶ月後 time + 10.years # 10年後 time.tomorrow # 翌日 time.yesterday # 昨日 time.next_month # 翌月 time.prev_month # 前月 time.next_year # 翌年 time.prev_year # 前月 time.ago(2.months) # 2ヶ月前 time.since(2.months) # 2ヶ月後 time.ago(2.years) # 2年前 time.since(2.years) # 2年後 time.beginning_of_month # 月初 time.end_of_month # 月末 time.beginning_of_year # 年初 time.end_of_year # 年末 time.next_occurring(:wednesday) # 次の水曜日 time.prev_occurring(:wednesday) # 前の水曜日 time.prev_week(:monday) # 先週の月曜日 time.next_week(:monday) # 来週の月曜日 time.year # 年 を取り出す time.month # 月 を取り出す time.day # 日 を取り出す time.hour # 時 を取り出す time.min # 分 を取り出す time.sec # 秒 を取り出す time.wday # 曜日 を取り出す(0:Sunday, 1:Monday, ……) time.yday # 1/1からの経過日数
次の○曜日、前の○曜日を取得するnext_occurring
, prev_occurring
はRails5.2から追加されたメソッドらしいので、現時点では新しいRailsを利用していないと使えないと思います。
単数形と複数形について
dayとdays, monthとmonths, yearとyears のような単数形、複数形はどちらを用いても同じです(aliasとなるよう設定されています)。
time.ago(2.month) #=> 2018-12-25 22:00:00 +0900 time.ago(2.months) #=> 2018-12-25 22:00:00 +0900 # これらは同じ
まぁそれでも間違えていると気持ち悪いので数字に合わせて単数か複数かは適切に使用したいですね。
Dateクラス
基本的にTimeクラスのオブジェクトに使えたメソッドが同じように使えますので重複しているものは省略します。
date = Date.now date >> 2 # 2ヶ月後 date << 2 # 2ヶ月前
ただしこちらは時間情報を持っていないので、時分秒を取得するメソッドなどはエラーとなります。
date = Date.today date.hour # これはエラー date - 1.hour => Mon, 25 Feb 2019 23:00:00 HST -10:00 # エラーにならない # application.rb のTZをHSTに設定している
時間の減算はエラーになりませんでした。
1時間引いて23時になったので、おそらく0時という情報を持ってはいるのでしょう。というか加算・減算をすると時間情報が姿を表すようですね。
ちなみに
date.class => Date date = date - 1.hour date.class => ActiveSupport::TimeWithZone
もともとはもちろんDateクラスなのですが、減算して時間情報をもたせるとTimeWithZoneというクラスに変わっていました。やっぱりDateクラスは時間情報を持てないんですね。
TimeWithZoneについては後述します。
DateTimeクラス
さて、あまり使わなくていい気がするDateTimeクラスですが、ちょっと変わったところがあります。
# now に 2019年2月25日22時00分00秒 のTimeオブジェクトを代入 DateTime.new(2019,2,25,22,00,00) #=> Mon, 25 Feb 2019 22:00:00 +0000 # TimeZoneがUTCになっている!! datetime2 = DateTime.now #=> Tue, 25 Feb 2019 22:00:00 +0900 # 他と一緒(システムの設定) datetime3 = DateTime.current #=> Mon, 25 Feb 2019 13:00:00 +0000 # 他と一緒(application.rbの設定)
nowやcurrentでインスタンスを生んだときはTimeやDateと同じようなタイムゾーンになりますが、newで生むと必ずUTCで生まれるようです。
これに対してTimeクラスにnewしたときはシステムのタイムゾーン設定依存ですので異なります。
TimeWithZoneクラスに関して
TimeWithZoneクラスとは?
日付と時間情報を扱えるクラスです。Rails独自のクラスでTimeクラスと完全な互換性をもっています。親はObjectクラスで、Timeクラスを継承しているわけではありません。
まぁTimeクラスと大きな差はなさそうなので親戚くらいの認識でいいのでしょうか。
Time.current.class => ActiveSupport::TimeWithZone Time.zone.now.class # .zone.now は .current と同じらしい => ActiveSupport::TimeWithZone date = Date.today date.ago(1.day) => Mon, 25 Feb 2019 00:00:00 HST -10:00 date.ago(1.day).class => ActiveSupport::TimeWithZone
current
メソッドやzone.now
メソッドを使うとTimeWithZoneクラスになるようです。
また、さきほどのようにDateクラスのオブジェクトから1時間引いてみたり、.ago
メソッドなどを使うとTimeWithZoneクラスになりました。
よく見るとタイムゾーンがHSTになっているのが分かりますね。今回はわかりやすくするためにapplication.rbのタイムゾーン設定をHSTにしておきました。
TimeWithZoneクラスはapplication.rbのタイムゾーン設定が利用されます。
current
メソッドを使うとapplication.rbのタイムゾーンが利用される、と前述しましたが、これはTimeWithZoneクラスになっていたからなんですね。
Timeクラスと大差ないとは思いますが、Timeクラスのタイムゾーンは環境変数(システム)依存、TimeWithZoneクラスのタイムゾーンはapplication.rb依存というのは覚えておくと良さそうですね。
メソッドのエイリアスについて
.month
と.months
はエイリアスになっているということは前述しましたが、次のようなものが設定されているようです。
alias :second :seconds alias :minute :minutes alias :hour :hours alias :day :days alias :week :weeks alias :until :ago alias :from_now :since
追記予定:strftime, strptime, time_formats
参考サイト
参考サイト