On a Date with Ruby

I recently had to deal with lots of date manipulation in Ruby-on-Rails. The application services Christian organizations, so most operations are centered around Sunday.

There is a complex set of rules to be applied but the final 'manipulation' of the data required a date to be forced to next Sunday. Any date could be supplied, representing any day of the week, and it had to be returned as the following Sunday.

Here is a simple RSpec test if you want to try this as a personal challenge. I recommend trying this on Cyber-Dojo.

describe "next sunday" do

  context 'given a date' do
    it 'will return _next_ Sunday' do
      date = Date.parse('2015-10-30')
      expect(next_sunday(date)).to eq "2015-11-01"
    end
  end

end  

Handling dates and date calculations is really tough in software.

Computers easily understand binary, octal, hexadecimal and decimal. But the week has seven days.
"What was God thinking?!"

During the development of this functionality I discovered some helpful features of Ruby (and Rails).

One of the most attractive features of Ruby is its English-like syntax (Thanks Matz).
I was already familiar with

  • wday
  • 1.week
  • 1.day

So it was no surprise to me there is a method beginning_of_week

And my first iteration included some shenanigans like:

if date.wday > 0  
   (date.beginning_of_week - 1.day) + 1.week
end  

If this looks familiar to you I have a treat.

Digging into the Rails source code I discovered you can actually set the beginning_of_week.

It is always enlightening to read the Rails source code.

My final solution was very simple, and quite 'English'.

date.beginning_of_week(:sunday) + 1.week  

That's it! If the date is Sunday we add one week. If not, a week is added to the Sunday that just passed.