Topic: advanced date help

Hi,

I need to figure out how to :

A - change the year value of a date to be 1 year ahead of now if the date and month has passed. So for example I have a day and a month, say March 11th. If today is past march 11 in the calendar year I need to create a date of march 11, 2008, if its before march 11, then create a date of march 11, 2007.

I got close with Time, but Time.today + 1.year appears to just adds 365 days which could be a differnt date.

B - to create a date for the N th weekday in a given month. So for example I want to create the date for MLK holiday, which is 3rd monday in january, for any given year.


thanks
Joel

Re: advanced date help

jnylund wrote:

A - change the year value of a date to be 1 year ahead of now if the date and month has passed. So for example I have a day and a month, say March 11th. If today is past march 11 in the calendar year I need to create a date of march 11, 2008, if its before march 11, then create a date of march 11, 2007.

Try the next_year method on a time instance.

jnylund wrote:

B - to create a date for the N th weekday in a given month. So for example I want to create the date for MLK holiday, which is 3rd monday in january, for any given year.

Try this:

time = Time.now # set however you want
time.beginning_of_month.beginning_of_week + 3.weeks # returns the 3rd monday of the current month

untested.

Railscasts - Free Ruby on Rails Screencasts

Re: advanced date help

Thanks Ryan, got me pointed in the right direction, but your 2nd one doesnt quite work (what if the month starts on a thurs, then above gives wrong answer). I found this site
http://michaelthompson.org/technikos/ho … nYear=2009 (which is pretty cool) and converted to Ruby (I think) and here is my version of the holiday method for ruby:

  # nTh - for example the 3rd, nTh would be 3
  # nTargetDay - 0-6 (sun = 0,mon=1.. sat=6) day of the week ruby style
  # nMonth - numeric month 0-12
  # 4 digit year
  def self.holiday(nTh,nTargetday,nMonth,nYear)
     
     nEarliestDate = 1 + 7 * (nTh - 1)
     d = Date.civil(nYear,nMonth,nEarliestDate)
     nWeekday = d.wday
     
     if( nTargetday==nWeekday )
          nOffset = 0
     else
       if( nTargetday < nWeekday )
            nOffset = nTargetday + (7 - nWeekday);
       else
            nOffset = (nTargetday + (7 - nWeekday)) - 7;
       end   
     end
     
     tHolidayDate = Date.new(nYear,nMonth,nEarliestDate + nOffset);
     return tHolidayDate
   end

Seems to work for me, might be a more elegant way, let me know if anyone finds any problems

Joel