Class: BusinessDaysSingleton
- Inherits:
-
Object
- Object
- BusinessDaysSingleton
- Includes:
- Singleton
- Defined in:
- lib/business-days.rb
Instance Method Summary collapse
-
#add_holiday(date) ⇒ Object
Consider the given date as a non-business day for all commands after this.
-
#business_day?(date) ⇒ Boolean
Check if the given date is a business day.
-
#business_days(from, to) ⇒ Integer
Number of business days between the two dates.
-
#business_days_from_utc_time(days, time) ⇒ Time
Compute the date obtained by adding the given amount of business days to the given time.
-
#initialize ⇒ BusinessDaysSingleton
constructor
A new instance of BusinessDaysSingleton.
-
#next(date) ⇒ Date
Returns the first business day after the given date.
-
#previous(date) ⇒ Date
Returns the first business day before the given date.
-
#remove_holiday(date) ⇒ Object
Remove given date from holidays list for all commands after this.
-
#remove_latest_non_bank_business_days ⇒ Object
Remove latest holiday for each year.
Constructor Details
#initialize ⇒ BusinessDaysSingleton
Returns a new instance of BusinessDaysSingleton.
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/business-days.rb', line 8 def initialize @holidays = [] # Setup holidays in an interval of 3 years from = Time.current.year - 1 to = Time.current.year + 2 # 1. Get all holidays in given years interval from Holidays gem Holidays.between(Date.civil(from, 1, 1), Date.civil(to, 12, 31), :br, :informal).each do |holiday| # Include holiday @holidays.push(holiday[:date]) # 2. If Carnaval, include the day before it (it's a bank holiday) if holiday[:name] == "Carnaval" @holidays.push(holiday[:date] - 1.day) end end # 3. Add the latest business day in each year (it's a bank holiday) # (from..to).each do |year| # @holidays.push(latest_non_bank_business_day(year)) # end end |
Instance Method Details
#add_holiday(date) ⇒ Object
Consider the given date as a non-business day for all commands after this.
92 93 94 95 96 |
# File 'lib/business-days.rb', line 92 def add_holiday(date) raise ArgumentError.new('Not a date') unless date.kind_of?(Date) @holidays.push(date) end |
#business_day?(date) ⇒ Boolean
Check if the given date is a business day
82 83 84 85 86 87 |
# File 'lib/business-days.rb', line 82 def business_day?(date) raise ArgumentError.new('Not a date') unless date.kind_of?(Date) weekend = [6, 7].include?(date.cwday) !(weekend || @holidays.include?(date)) end |
#business_days(from, to) ⇒ Integer
Returns number of business days between the two dates.
65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/business-days.rb', line 65 def business_days(from, to) raise ArgumentError.new('Not a date: from') unless from.kind_of?(Date) raise ArgumentError.new('Not a date: to') unless to.kind_of?(Date) count = 0 while from <= to count +=1 if self.business_day?(from) from = from + 1.day end count end |
#business_days_from_utc_time(days, time) ⇒ Time
Compute the date obtained by adding the given amount of business days to the given time.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/business-days.rb', line 37 def business_days_from_utc_time(days, time) # Get offset from reference data (based on Brasilia timezone) offset = time.in_time_zone('Brasilia').formatted_offset() # Get date from time in reference offset date = (time + offset.to_i.hours).to_date # Add days until we reach the specified business days count = 0 while count < days time += 24*60*60 offset = time.in_time_zone('Brasilia').formatted_offset() date = (time + offset.to_i.hours).to_date if business_day?(date) count +=1 end end (date.to_time.utc.midnight - offset.to_i.hours) end |
#next(date) ⇒ Date
Returns the first business day after the given date.
120 121 122 123 124 125 126 127 128 129 |
# File 'lib/business-days.rb', line 120 def next(date) raise ArgumentError.new('Not a date') unless date.kind_of?(Date) date = date + 1.days while !business_day?(date) date = date + 1.days end date end |
#previous(date) ⇒ Date
Returns the first business day before the given date.
135 136 137 138 139 140 141 142 143 144 |
# File 'lib/business-days.rb', line 135 def previous(date) raise ArgumentError.new('Not a date') unless date.kind_of?(Date) date = date - 1.days while !business_day?(date) date = date - 1.days end date end |
#remove_holiday(date) ⇒ Object
Remove given date from holidays list for all commands after this.
101 102 103 104 105 |
# File 'lib/business-days.rb', line 101 def remove_holiday(date) raise ArgumentError.new('Not a date') unless date.kind_of?(Date) @holidays.delete(date) end |
#remove_latest_non_bank_business_days ⇒ Object
Remove latest holiday for each year
108 109 110 111 112 113 114 |
# File 'lib/business-days.rb', line 108 def remove_latest_non_bank_business_days years = Set.new(@holidays.map { |d| d.year }) years.each do |year| max_date = @holidays.select { |d| d.year == year }.max self.remove_holiday(max_date) if max_date.strftime('%m%d') >= "1229" end end |