开发者

How do I calculate the next annual occurrence of a date?

Given a Ruby date, does a one liner exist for calculating the next anniversary of that date?

For example, if the date is May 01, 2011 the next anniversary would be May 01, 2012, h开发者_开发问答owever if it is December 01, 2011, the next anniversary is December 01, 2011 (as that date hasn't yet arrived).


If you date variable is an instance of Date then you can use >>:

Return a new Date object that is n months later than the current one.

So you could do this:

one_year_later = date >> 12

The same approach applies to DateTime. If all you have is a string, then you can use the parse method:

next_year        =  Date.parse('May 01, 2011') >> 12
next_year_string = (Date.parse('May 01, 2011') >> 12).to_s

IMHO you're better off using the date libraries (Date and DateTime) as much as possible but you can use the Rails extensions (such as 1.year) if you know that Rails will always be around or you don't mind manually pulling in active_support as needed.


An excellent gem exists for doing this called recurrence. You can checkout the source code or some samples:

  • https://github.com/fnando/recurrence
  • http://blog.plataformatec.com.br/tag/recurrence/

For example, if you have a date set you could try:

date = ...
recurrence = Recurrence.new(every: :year, on: [date.month, date.day])
puts recurrence.next


You can do it using Ruby's Date class:

the_date = Date.parse('jan 1, 2011')
(the_date < Date.today) ? the_date + 365 : the_date # => Sun, 01 Jan 2012

the_date = Date.parse('dec 31, 2011')
(the_date < Date.today) ? the_date.next_year : the_date # => Sat, 31 Dec 2011

Or, for convenience use ActiveSupport's Date class extensions:

require 'active_support/core_ext/date/calculations'
the_date = Date.parse('jan 1, 2011')
(the_date < Date.today) ? the_date.next_year : the_date # => Sun, 01 Jan 2012
the_date = Date.parse('dec 31, 2011')
(the_date < Date.today) ? the_date.next_year : the_date # => Sat, 31 Dec 2011


Try this:

def next_anniversary(d)
  Date.today > d ? 1.year.from_now(d) : d
end 


Pulling in a gem just to do this is overkill.

your_date > Date.today ? your_date : your_date >> 12
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜