Class: Rupee::Calendar
- Inherits:
-
Object
- Object
- Rupee::Calendar
- Extended by:
- FindInstance
- Defined in:
- lib/rupee/calendar.rb,
lib/rupee/calendar/us.rb,
lib/rupee/calendar/japan.rb
Overview
An object representing a calendar, for use in determining the next payout date for a cash flow. Simple example:
require "rupee/calendar"
module Rupee
class Calendar
# It's recommended that you store your calendar inside the Calendar
# class, as that way you'll have access to them as "constants." Also,
# it gives you access to the month constants (JANUARY, FEBRUARY,
# MARCH, etc.)
MyCalendar = Rupee::Calendar.new("Sample calendar")
# Weekends
MyCalendar.has_weekends_off
# Thanksgiving (fourth Thursday of November
MyCalendar.has_day_off_on :thanksgiving do |date|
date.month == NOVEMBER && date.thursday? && week_of(date) == 4
end
# Christmas (December 25 or nearest weekday)
MyCalendar.has_day_off_on :christmas do |date|
date.month == DECEMBER && nearest_weekday(date, 25)
end
# New Year's Day (January 1 or next weekday)
MyCalendar.has_day_off_on :new_years do |date|
date.month == JANUARY && next_weekday(date, 1)
end
end
end
# Christmas falls on a Sunday in 2011...
Rupee::Calendar::MyCalendar.day_off?(Time.new(2011, 12, 25))
# => true
# ... so we have the following Monday off...
Rupee::Calendar::MyCalendar.day_off?(Time.new(2011, 12, 26))
# => true
# ...then it's back to work
Rupee::Calendar::MyCalendar.day_off?(Time.new(2011, 12, 27))
# => false
You can also inherit from other calendars easily:
require "rupee/calendar"
class Rupee::Calendar
# Pirates generally observe the Federal Reserve holiday schedule
Blackbeard = US.copy
# But they do observe Talk Like a Pirate Day
Blackbeard.has_day_off_on :talk_like_a_pirate_day do |date|
date.month == SEPTEMBER && date.day == 19
end
# And curse the Spanish Crown
Blackbeard.remove_day_off_for :columbus_day
end
# Talk Like a Pirate Day
Rupee::Calendar::Blackbeard.day_off?(Time.new(2011, 9, 19))
# => true
Rupee::Calendar::US.day_off?(Time.new(2011, 9, 19))
# => false
# Columbus Day
Rupee::Calendar::Blackbeard.day_off?(Time.new(2011, 10, 10))
# => false
Rupee::Calendar::US.day_off?(Time.new(2011, 10, 10))
# => true
Constant Summary collapse
- JANUARY =
A constant representing the month of January
1
- FEBRUARY =
A constant representing the month of February
2
- MARCH =
A constant representing the month of March
3
- APRIL =
A constant representing the month of April
4
- MAY =
A constant representing the month of May
5
- JUNE =
A constant representing the month of June
6
- JULY =
A constant representing the month of July
7
- AUGUST =
A constant representing the month of August
8
- SEPTEMBER =
A constant representing the month of September
9
- OCTOBER =
A constant representing the month of October
10
- NOVEMBER =
A constant representing the month of November
11
- DECEMBER =
A constant representing the month of December
12
- US =
The US Federal Reserve calendar
Calendar.new("The Federal Reserve Calendar")
- Japan =
The national Japanese calendar
Calendar.new("The national Japanese calendar")
Instance Attribute Summary collapse
-
#days_off ⇒ Object
readonly
Functions used to determine whether a day is off.
-
#description ⇒ Object
readonly
A description of the calendar.
Class Method Summary collapse
-
.last_week?(date) ⇒ Boolean
Whether the provided date falls in the last week of the month.
-
.nearest_weekday(date, day) ⇒ Object
Calculates whether the provided date is the nearest weekday relative to the provided day of the month.
-
.next_monday_if_sunday(date, day) ⇒ Object
Calculates whether the provided date is the day requested or, if the day requested falls on a Sunday, the following Monday.
-
.next_weekday(date, day) ⇒ Object
Calculates whether the provided date is the nearest weekday relative to the provided day of the month.
-
.previous_weekday(date, day) ⇒ Object
Calculates whether the provided date is the nearest weekday relative to the provided day of the month.
-
.week_of(date) ⇒ Object
Calculates the week of the month in which the given date falls.
Instance Method Summary collapse
-
#copy ⇒ Object
Makes a copy of the calendar.
-
#day_off?(date) ⇒ Boolean
Returns true if the specified date is a holiday or day off.
-
#has_day_off_on(key, &block) ⇒ Object
Provides a function telling that calendar how to evaluate whether a particular day is off.
-
#has_weekends_off ⇒ Object
A simple helper method for the commonality among most countries that weekends are not workdays or trading days:.
-
#initialize(description) ⇒ Calendar
constructor
Builds a calendar.
-
#remove_day_off_for(key) ⇒ Object
Removes the day off for the specified key.
Methods included from FindInstance
Constructor Details
#initialize(description) ⇒ Calendar
Builds a calendar
112 113 114 115 |
# File 'lib/rupee/calendar.rb', line 112 def initialize(description) @description = description @days_off = {} end |
Instance Attribute Details
#days_off ⇒ Object (readonly)
Functions used to determine whether a day is off
109 110 111 |
# File 'lib/rupee/calendar.rb', line 109 def days_off @days_off end |
#description ⇒ Object (readonly)
A description of the calendar
107 108 109 |
# File 'lib/rupee/calendar.rb', line 107 def description @description end |
Class Method Details
.last_week?(date) ⇒ Boolean
Whether the provided date falls in the last week of the month
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/rupee/calendar.rb', line 184 def last_week?(date) case date.month when 9, 4, 6, 11 # Thirty days hath September # April, June and November date.day > 23 when 1, 3, 5, 7, 8, 10, 12 # All the rest have thirty-one date.day > 24 when 2 # Save February, with twenty-eight days clear # And twenty-nine each leap year ;) date.day > (date.year % 4 == 0 && (date.year % 100 != 0 || date.year % 400 == 0)) ? 22 : 21 end end |
.nearest_weekday(date, day) ⇒ Object
Calculates whether the provided date is the nearest weekday relative to the provided day of the month
202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/rupee/calendar.rb', line 202 def nearest_weekday(date, day) case date.wday when 1 # Monday date.day.between?(day, day + 1) when 5 # Friday date.day.between?(day - 1, day) when 0, 6 # Weekends false else # Tuesday - Thursday date.day == day end end |
.next_monday_if_sunday(date, day) ⇒ Object
Calculates whether the provided date is the day requested or, if the day requested falls on a Sunday, the following Monday
243 244 245 246 247 248 249 250 251 252 |
# File 'lib/rupee/calendar.rb', line 243 def next_monday_if_sunday(date, day) case date.wday when 1 # Monday date.day.between?(day, day + 1) when 0, 6 # Weekends false else # Tuesday - Friday date.day == day end end |
.next_weekday(date, day) ⇒ Object
Calculates whether the provided date is the nearest weekday relative to the provided day of the month
217 218 219 220 221 222 223 224 225 226 |
# File 'lib/rupee/calendar.rb', line 217 def next_weekday(date, day) case date.wday when 1 # Monday date.day.between?(day, day + 2) when 0, 6 # Weekends false else # Tuesday - Friday date.day == day end end |
.previous_weekday(date, day) ⇒ Object
Calculates whether the provided date is the nearest weekday relative to the provided day of the month
230 231 232 233 234 235 236 237 238 239 |
# File 'lib/rupee/calendar.rb', line 230 def previous_weekday(date, day) case date.wday when 5 # Friday date.day.between?(day - 2, day) when 0, 6 # Weekends false else # Monday - Thursday date.day == day end end |
.week_of(date) ⇒ Object
Calculates the week of the month in which the given date falls
179 180 181 |
# File 'lib/rupee/calendar.rb', line 179 def week_of(date) (date.day - 1) / 7 + 1 end |
Instance Method Details
#copy ⇒ Object
Makes a copy of the calendar
118 119 120 121 122 123 124 125 126 |
# File 'lib/rupee/calendar.rb', line 118 def copy new_cal = Calendar.new @description.dup @days_off.each_pair do |key, day_off| new_cal.days_off[key] = day_off end new_cal end |
#day_off?(date) ⇒ Boolean
Returns true if the specified date is a holiday or day off
167 168 169 170 171 172 173 |
# File 'lib/rupee/calendar.rb', line 167 def day_off?(date) @days_off.each_value do |day_off| return true if day_off.call(date) end false end |
#has_day_off_on(key, &block) ⇒ Object
Provides a function telling that calendar how to evaluate whether a particular day is off. Note that within this block you can use the helper methods week_of, nearest_weekday, next_weekday and previous_weekday:
# Thanksgiving (fourth Thursday of November
MyCalendar.has_day_off_on :thanksgiving do |date|
date.month == NOVEMBER && date.thursday? && week_of(date) == 4
end
# Christmas (December 25 or nearest weekday)
MyCalendar.has_day_off_on :christmas do |date|
date.month == DECEMBER && nearest_weekday(date, 25)
end
# New Year's Day (January 1 or next weekday)
MyCalendar.has_day_off_on :new_years do |date|
date.month == JANUARY && next_weekday(date, 1)
end
147 148 149 |
# File 'lib/rupee/calendar.rb', line 147 def has_day_off_on(key, &block) @days_off[key] = block end |
#has_weekends_off ⇒ Object
A simple helper method for the commonality among most countries that weekends are not workdays or trading days:
MyCalendar.has_weekends_off
160 161 162 163 164 |
# File 'lib/rupee/calendar.rb', line 160 def has_weekends_off @days_off[:weekends] = Proc.new do |date| date.saturday? || date.sunday? end end |
#remove_day_off_for(key) ⇒ Object
Removes the day off for the specified key
152 153 154 |
# File 'lib/rupee/calendar.rb', line 152 def remove_day_off_for(key) @days_off.delete key end |