views:

331

answers:

4

Hi,

I have the following date object in ruby

Date.new(2009, 11, 19)

How would you find the next friday?

Cheers

+1  A: 

Rails' ActiveSupport::CoreExtensions::Date::Calculations has methods that can help you. If you're not using Rails, you could just require ActiveSupport.

bensie
+4  A: 

You could use end_of_week (AFAIK only available in Rails)

>> Date.new(2009, 11, 19).end_of_week - 2
=> Fri, 20 Nov 2009

But this might not work, depending what exactly you want. Another way could be to

>> d = Date.new(2009, 11, 19)
>> (d..(d+7)).find{|d| d.cwday == 5}
=> Fri, 20 Nov 2009

lets assume you want to have the next friday if d is already a friday:

>> d = Date.new(2009, 11, 20) # was friday
>> ((d+1)..(d+7)).find{|d| d.cwday == 5}
=> Fri, 27 Nov 2009
reto
Well, `require activesupport` (after a suitable `gem install` of course) would be enough, I'd think.
Mike Woodhouse
Your first example would return yesterday, if the date happened to be a Saturday.
ScottJ
Yap, scott thats what I mean with 'dependening what you want that might not work'. It finds the friday of the current week :).
reto
+2  A: 
bhups
+1  A: 

As Ruby's modulo operation (%) returns positive numbers when your divisor is positive, you can do this:

some_date = Date.new(2009, 11, 19)
next_friday = some_date + (5 - some_date.cwday) % 7

The only issue I can see here is that if some_date is a Friday, next_friday will be the same date as some_date. If that's not the desired behavior, a slight modification can be used instead:

some_date = Date.new(...)
day_increment = (5 - some_date.cwday) % 7
day_increment = 7 if day_increment == 0
next_friday = some_date + day_increment

This code doesn't rely on additional external dependencies, and relies mostly on integer arithmetic.

Ian
Instead of doing an additional check, couldn't you just add one day to 'some_day' before applying your algo. date + 1 + (4 - date.cwday) % 7 works fine.
reto
@reto, I think you're absolutely correct, good call :)
Ian