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
精彩评论