I recently cooked these up, thought someone else might find them handy. Now you can say date.first_of_month, date.first_of_year, etc.
module DateExtensions
def first_of_week
self - self.wday
end
def first_of_month
self - self.day+1
end
def first_of_quarter
(self << (self.month%3 - 1 )%3) - self.day+1
end
def first_of_year
(self << self.month-1) - self.day+1
end
end
Date.send :include, DateExtensions
Addendum: oops, looks like there are already similar methods in Rails’ ActiveSupport:
beginning_of_* rather than first_of_*
However, begining_of_week assumes Monday is the first day of the week, while my version assumes Sunday is the first day.
Here are my tests:
require File.dirname(__FILE__) + '/../test_helper'
class DateExtensionsTest < Test::Rails::TestCase
def test_first_of_week
day = Date.new( 2008, 1, 1 )
w = day.first_of_week
# sunday is first day of week
assert_equal 0, w.wday
assert_equal 30, w.day
end
def test_first_of_month
day = Date.new( 2008, 1, 15 )
assert_equal 1, day.first_of_month.day
end
def test_first_of_year
day = Date.new( 2008, 5, 27 )
y = day.first_of_year
assert_equal 1, y.month
assert_equal 1, y.day
end
def test_first_of_quarter_q1
[1,2,3].each do |month|
day = Date.new( 2008, month, 13 )
q = day.first_of_quarter
assert_equal 1, q.day
assert_equal 1, q.month
end
end
def test_first_of_quarter_q2
[4,5,6].each do |month|
day = Date.new( 2008, month, 13 )
q = day.first_of_quarter
assert_equal 1, q.day
assert_equal 4, q.month
end
end
def test_first_of_quarter_q3
[7,8,9].each do |month|
day = Date.new( 2008, month, 13 )
q = day.first_of_quarter
assert_equal 1, q.day
assert_equal 7, q.month
end
end
def test_first_of_quarter_q4
[10,11,12].each do |month|
day = Date.new( 2008, month, 13 )
q = day.first_of_quarter
assert_equal 1, q.day
assert_equal 10, q.month
end
end
end

Leave a Reply