I was reading the docs for TimeWithZone 
(http://edgeapi.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html) and 
noticed that two different methods can be used to add an interval: +(other) and 
since(other).

I ran some manual tests (copied below) and found that the two methods return 
the same result in almost every case.

The only case where they differ is when TimeWithZone wraps a DateTime and the 
"other" value passed to "since" is in a form like "1.month":

    dt = DateTime.new(2014, 12, 01, 22, 00, 00).in_time_zone
  dt + 1.month # => Thu, 01 Jan 2015 17:00:00 EST -05:00
  dt.since 1.month # => Wed, 31 Dec 2014 17:00:00 EST -05:00  

However, this usage of "since" is explicitly discouraged by the documentation 
of DateTime#since 
(https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/date_time/calculations.rb#L86L88):

  # Returns a new DateTime representing the time a number of seconds since the
  # instance time. Do not use this method in combination with x.months, use
  # months_since instead!

And indeed, following this recommendation the correct result is returned:

  dt.months_since 1 => Thu, 01 Jan 2015 17:00:00 EST -05:00

Therefore, my proposal is to remove the method definition of TimeWithZone#since 
and instead replace it with a simple alias_method :since, :+

The rationale is that the only case where they differ is a case that is 
explicitly discouraged as "wrong". 
If you think this is a good idea that will make the code clearer to understand, 
then I will open a PR with a set of tests that demonstrate that the two methods 
are equivalent in every other case.

Thanks!

----

> t = Time.now.in_time_zone
=> Thu, 04 Dec 2014 18:56:28 EST -05:00
> t + 1 == t.since(1)
=> true
> t + 1.day == t.since(1.day)
=> true
> t + 1.month == t.since(1.month)
=> true

> d = Date.today.in_time_zone
=> Thu, 04 Dec 2014 00:00:00 EST -05:00
> d + 1 == d.since(1)
=> true
> d + 1.day == d.since(1.day)
=> true
> d + 1.month == d.since(1.month)
=> true

> dt = DateTime.now.in_time_zone
=> Thu, 04 Dec 2014 18:57:28 EST -05:00
> dt + 1 == dt.since(1)
=> true
> dt + 1.day == dt.since(1.day)
=> true
> dt + 1.month == dt.since(1.month)
=> false

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.

Reply via email to