For my application (a thing with fortnightly billing periods) I wanted to define a beginning of fortnight method to consistently calculate the beginning (and end) of a fortnight. Here's how it ended up (both short and sweet):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# Extend ActiveSupport to provide a beginning_of_fortnight and an | |
# end_of_fortnight method for the Time class | |
# | |
module ActiveSupport::CoreExtensions::Time::Calculations | |
# | |
# How many weeks since the beginning_of_week before unix time zero | |
# | |
def weeks_after_epoch | |
((self - ::Time.at(0).beginning_of_week) / 1.week).to_i | |
end | |
# | |
# The beginning of the current fortnight | |
# | |
# The choice of which week should begin a fortnight is arbitrary | |
# If you want to flip it then change even? to odd? below | |
# | |
def beginning_of_fortnight | |
# If there's been an even number of weeks since epoch use beginning of this week | |
# If there's been an odd number of weeks since epoch use the beginning of last week | |
(weeks_after_epoch.even? ? self : self - 1.week).beginning_of_week | |
end | |
# | |
# The end of the current fortnight | |
# | |
def end_of_fortnight | |
(beginning_of_fortnight + 13.days).end_of_day | |
end | |
end |
(Note that there's no special reason to use epoch. Any other day would work just as well probably).
Does it work?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Development]>> puts Time.now; (-5..5).each { |w| t = Time.now + w.weeks; puts "now and #{'%2d'%w} weeks: #{t.beginning_of_fortnight} - #{t.end_of_fortnight}" }; nil | |
Wed Oct 06 16:29:52 +1000 2010 | |
now and -5 weeks: Mon Aug 30 00:00:00 +1000 2010 - Sun Sep 12 23:59:59 +1000 2010 | |
now and -4 weeks: Mon Aug 30 00:00:00 +1000 2010 - Sun Sep 12 23:59:59 +1000 2010 | |
now and -3 weeks: Mon Sep 13 00:00:00 +1000 2010 - Sun Sep 26 23:59:59 +1000 2010 | |
now and -2 weeks: Mon Sep 13 00:00:00 +1000 2010 - Sun Sep 26 23:59:59 +1000 2010 | |
now and -1 weeks: Mon Sep 27 00:00:00 +1000 2010 - Sun Oct 10 23:59:59 +1000 2010 | |
now and 0 weeks: Mon Sep 27 00:00:00 +1000 2010 - Sun Oct 10 23:59:59 +1000 2010 | |
now and 1 weeks: Mon Oct 11 00:00:00 +1000 2010 - Sun Oct 24 23:59:59 +1000 2010 | |
now and 2 weeks: Mon Oct 11 00:00:00 +1000 2010 - Sun Oct 24 23:59:59 +1000 2010 | |
now and 3 weeks: Mon Oct 25 00:00:00 +1000 2010 - Sun Nov 07 23:59:59 +1000 2010 | |
now and 4 weeks: Mon Oct 25 00:00:00 +1000 2010 - Sun Nov 07 23:59:59 +1000 2010 | |
now and 5 weeks: Mon Nov 08 00:00:00 +1000 2010 - Sun Nov 21 23:59:59 +1000 2010 | |
=> nil |
Put beginning_of_fortnight.rb in config/initializers.
Note that there is already a Numeric#fortnights method in ActiveSupport so we can use things like 2.fortnights without needing any extentions.
No comments:
Post a Comment