カテゴリー: BackEnd

Ruby、Railsの時間に関するメソッドを使用してみた

はじめに

普段PHPのお仕事をしています、tonnyです。
半年程前からRuby on Railsの勉強を始めました。
今回はよく使う時間に関するメソッドついてまとめたいと思います。

目次

環境について

今回の環境は以下の通りです。

  • Ruby 2.4.0
  • Rails 5.0.1

用途によって使い分け

現在時刻を取得

>> time = Time.now
=> 2017-02-25 12:18:31 +0900

日付を指定したフォーマット

Rubyの組み込み関数であるstrftimeメソッドを使用します。

>> time = Time.now
=> 2017-02-25 12:18:31 +0900
>> time.strftime('%Y年%m月%d日 %H:%M:%S')
=> "2017年02月25日 12:18:31"

フォーマットはいくつか種類がありますが、基本はこの形で問題ないのかな、と思います。
Railsリファレンス-strftime-

日本語の曜日を出力する場合

フォーマットに従い、曜日を出力しようとすると、英語表記になります。

>> time.strftime('%A')
=> "Saturday"

これを日本語に直す場合は、

  1. 日曜日から始まる、曜日の配列を作成
  2. 曜日の番号を取得

これらを組み合わせるのが良いのかな、と思います。
Timeクラスには、日曜日から始まる曜日の番号を返してくれるwdayというインスタンスメソッドがあるため、それを使用します。

>> weekdays = %w(日 月 火 水 木 金 土)
=> ["日", "月", "火", "水", "木", "金", "土"]
>> Time.now.strftime("#{weekdays[Time.now.wday]}")
=> "土"

指定した日時を取得

gmで世界協定時刻を、localで設定した地域の時刻を取得することができます。
なお、localで出力される「+0900」は世界協定時からの時差です。

>> Time.gm(2017,12,31,23,59,59)
=> 2017-12-31 23:59:59 UTC
>> Time.local(2017,12,31,23,59,59)
=> 2017-12-31 23:59:59 +0900

UNIX TIMESTAMPを使ったあれこれ

現在時刻をタイムスタンプに変換、またはタイムスタンプから時刻を取得する方法は下記になります。

>> Time.now.to_i
=> 1487995894
>> Time.at(1487995894)
=> 2017-02-25 13:11:34 +0900

過去、未来の時刻を取得

経過秒数で計算することができます。

>> Time.now + 24 * 60 * 60
=> 2017-02-26 13:18:59 +0900
>> Time.now - 24 * 60 * 60
=> 2017-02-24 13:19:10 +0900

この計算をするのは少し面倒なので、Railsで用意されているTimeWithZoneクラスを使用してみたいと思います。

ActiveSupport::TimeWithZone

Railsが用意しているクラスであり、Timeクラスと互換性があります。
ただ、親クラスはObjectのようなので、継承しているわけではないようです。
もちろん、ふつうのRubyでは使用できません。
Railsリファレンス-ActiveSupport::TimeWithZone-

まずは設定

TimeWithZoneクラスは下記のように使用します。

>> Time.zone.now
=> Sat, 25 Feb 2017 05:41:53 UTC +00:00
>> Time.zone
=> #<ActiveSupport::TimeZone:0x007feecf3a3f98 @name="UTC", @utc_offset=nil, @tzinfo=#<TZInfo::DataTimezone: Etc/UTC>>

あれ、世界協定のUTCになってる。。。(このとき14時くらい)
調べてみると、ActiveSupportの設定が必要なようです。
Railsリファレンス-ActiveSupport::TimeZone-

そのため、config/application.rbに追記します。

config.time_zone = 'Tokyo'

これで再度Time.zone.nowを実行してみると、

>> Time.zone
=> #<ActiveSupport::TimeZone:0x007f8d9d8b2e28 @name="Tokyo", @utc_offset=nil, @tzinfo=#<TZInfo::DataTimezone: Asia/Tokyo>>
>> Time.zone.now
=> Sat, 25 Feb 2017 14:49:21 JST +09:00

JST時刻で表示されるようになりました!

Timeクラスとの互換性

Timeクラスのメソッドはほぼ使用できます。

>> Time.zone.now
=> Sat, 25 Feb 2017 15:19:41 JST +09:00
>> Time.zone.local(2017,12,31,23,59,59)
=> Sun, 31 Dec 2017 23:59:59 JST +09:00
>> Time.zone.now.to_i
=> 1488004050
>> Time.zone.at(1488004050)
=> Sat, 25 Feb 2017 15:27:30 JST +09:00

便利メソッド

今日 / 明日 / 昨日

>> Time.zone.today
=> Sat, 25 Feb 2017
>> Time.zone.yesterday
=> Fri, 24 Feb 2017
>> Time.zone.tomorrow
=> Sun, 26 Feb 2017

メソッドチェーンで、現在時刻から見て昨日とかもできます。

>> Time.zone.now.yesterday
=> Fri, 24 Feb 2017 15:51:26 JST +09:00

その日のはじめ / その日の終わり

「その日始まってから、その日が終わるまで」のような条件指定をすることはよくあると思います。
そういうときに、日付関数などで、日を指定して〜ではなく、下記のように取得できます。

>> Time.zone.yesterday.beginning_of_day
=> Fri, 24 Feb 2017 00:00:00 JST +09:00
>> Time.zone.yesterday.end_of_day
=> Fri, 24 Feb 2017 23:59:59 JST +09:00

個人的には、Timeクラスの中でもこういう風に書けるということが、かなり印象的でした。
見ただけで、「ああ、昨日1日が対象なんだ。」と分かります。

他にも月や年などで同じような書き方ができます。
個人的にも何かないかと思ったら、下記で調べてみようと思います。
Railsリファレンス-Time-
Railsリファレンス-Date-

さいごに

ActiveSupportをふつうのRubyでも使用することができるようです。
Rails Guides

時間関係のメソッドを試していると、ここはRuby、こっちはRailsのメソッド、と意識するようになるので、勉強になりました。
今後もこのような形式で、クラス単位で試したことを記事にしたいと思います。

naoki85

シェア
執筆者:
naoki85
タグ: Rails

最近の投稿

フロントエンドで動画デコレーション&レンダリング

はじめに 今回は、以下のように…

2週間 前

Goのクエリビルダー goqu を使ってみる

はじめに 最近携わっているとあ…

4週間 前

【Xcode15】プライバシーマニフェスト対応に備えて

はじめに こんにちは、suzu…

2か月 前

FSMを使った状態管理をGoで実装する

はじめに 一般的なアプリケーシ…

3か月 前