LoginSignup
3
1

More than 5 years have passed since last update.

【Rails】 3日後は、3.days.since(time)とtime.since(3.days)、どちらで書くべきか?

Last updated at Posted at 2018-09-29

結論

少なくとも全体で統一した方が良い。 こんな感じの使い分けかと考えています。

3.days.since(time) time.since(3.days)
• 「3daysという期間」の意味合いを主張したい。
• 英語の「3 days ago」と同じ語順にしたい。
Timeを主語に書きたい

[備考]
Rails4.2のコードを参照しましたが、確認した限りRails5でも仕様には変更ないようです。
(コードの変更自体はあります →参考になる記事)

コードレベルで2つを比較する

paiza.ioにコードを置いてあります。

はじめに

sincerails/active-supportにより提供されている機能です。
まず、そもそも両者は異なるclassというのが大事です。

puts 3.days.class # => ActiveSupport::Duration
puts current_time.class # => Time

それぞれのsinceの挙動を確認しましょう

Durationのsince

rails/activesupport/lib/active_support/duration.rb
# Calculates a new Time or Date that is as far in the future
# as this Duration represents.
def since(time = ::Time.current)
  sum(1, time)
end
alias :from_now :since

sinceは、↓のsumメソッドを呼んでいるのがわかる。

rails/activesupport/lib/active_support/duration.rb
def sum(sign, time = ::Time.current) #:nodoc:
  parts.inject(time) do |t,(type,number)|
    if t.acts_like?(:time) || t.acts_like?(:date)
      if type == :seconds
        t.since(sign * number)
      else
        t.advance(type => sign * number)
      end
    else
       raise ::ArgumentError, "expected a time or date, got #{time.inspect}"
    end
  end
end

引数のtimeに対して、 値を加算しているのがわかる
partsはDurationインスタンス生成時に生成される期間パラメータの格納先であり、例えばputs 3.days.parts # => {:days=>3}である。
各期間(dayやmonth,year)をtimeに対して順に加算していく、という挙動をする。

Timeのsince

rails/activesupport/lib/active_support/core_ext/time/calculations.rb
# Returns a new Time representing the time a number of seconds since the instance time
def since(seconds)
  self + seconds
  rescue
    to_datetime.since(seconds)
  end
alias :in :since

コードそのままであり、time.since()は引数の秒数を現在時刻に足すことを意味する。
例えばputs 3.days # => 259200秒なので、time.since()はtime自身に259200秒を足すという挙動をする。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1