Class: BusinessCalendar::Calendar

Inherits:
Object
  • Object
show all
Defined in:
lib/business_calendar/calendar.rb

Constant Summary collapse

DEFAULT_TIME_TO_LIVE =
24 * 60 * 60

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(holiday_determiner, options = {}) ⇒ Calendar

Returns a new instance of Calendar.

Parameters:

  • ] (Proc[Date -> Boolean)

    a proc which returns whether or not a date is a holiday.



7
8
9
10
11
12
13
# File 'lib/business_calendar/calendar.rb', line 7

def initialize(holiday_determiner, options = {})
  ttl = options['ttl']
  @time_to_live = ttl.nil? ? DEFAULT_TIME_TO_LIVE : ttl
  @options = options
  @holiday_cache = {}
  @holiday_determiner = holiday_determiner
end

Instance Attribute Details

#holiday_determinerObject (readonly)

Returns the value of attribute holiday_determiner.



3
4
5
# File 'lib/business_calendar/calendar.rb', line 3

def holiday_determiner
  @holiday_determiner
end

Instance Method Details

#add_business_days(date_or_dates, num = 1, initial_direction = :forward) ⇒ Date Also known as: add_business_day

Note:

‘Adding a business day’ means moving one full business day from the start of the given day – meaning that adding one business day to a Saturday will return the following Tuesday, not Monday.

Returns The result of adding <num> business days to <date>.

Parameters:

  • date_or_dates (Date or Array)

    The day(s) to start from.

  • num (Integer) (defaults to: 1)

    Number of days to advance. If negative, this will call ‘subtract_business_days`.

  • direction (Symbol)

    Either ‘:forward` or `:backward`; the direction to move if today is not a business day.

Returns:

  • (Date)

    The result of adding <num> business days to <date>.



43
44
45
46
47
48
49
50
51
# File 'lib/business_calendar/calendar.rb', line 43

def add_business_days(date_or_dates, num=1, initial_direction = :forward)
  return subtract_business_days(date_or_dates, -num) if num < 0

  with_one_or_many(date_or_dates) do |date|
    d = nearest_business_day(date, initial_direction)
    num.times { d = following_business_day(d) }
    d
  end
end

#following_business_day(date_or_dates) ⇒ Date

Returns The nearest (going forward in time) business day from <date> which is not <date> itself.

Parameters:

  • date_or_dates (Date or Array)

    The day(s) to start from.

Returns:

  • (Date)

    The nearest (going forward in time) business day from <date> which is not <date> itself.



107
108
109
110
111
# File 'lib/business_calendar/calendar.rb', line 107

def following_business_day(date_or_dates)
  with_one_or_many(date_or_dates) do |date|
    nearest_business_day(date + 1)
  end
end

#is_business_day?(date) ⇒ Boolean

Returns Whether or not banking can be done on <date>.

Parameters:

  • date (Date)

Returns:

  • (Boolean)

    Whether or not banking can be done on <date>.



27
28
29
30
31
# File 'lib/business_calendar/calendar.rb', line 27

def is_business_day?(date)
  return false if !@options['business_weekends'] && (date.saturday? || date.sunday?)
  return false if is_holiday?(date)
  true
end

#is_holiday?(date) ⇒ Boolean

Returns Whether or not this calendar’s list of holidays includes <date>.

Parameters:

  • date (Date)

Returns:

  • (Boolean)

    Whether or not this calendar’s list of holidays includes <date>.



17
18
19
20
21
22
23
# File 'lib/business_calendar/calendar.rb', line 17

def is_holiday?(date)
  date = date.send(:to_date) if date.respond_to?(:to_date, true)

  clear_cache if should_clear_cache?

  @holiday_cache[date] ||= holiday_determiner.call(date)
end

#nearest_business_day(date_or_dates, direction = :forward) ⇒ Date

Returns The nearest (going <direction> in time) business day from <date>. If <date> is already a business day, it will be returned.

Parameters:

  • date_or_dates (Date or Array)

    The day(s) to start from.

  • direction (Symbol) (defaults to: :forward)

    Either ‘:forward` or `:backward`; the direction to move if today is not a business day.

Returns:

  • (Date)

    The nearest (going <direction> in time) business day from <date>. If <date> is already a business day, it will be returned.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/business_calendar/calendar.rb', line 87

def nearest_business_day(date_or_dates, direction = :forward)
  with_one_or_many(date_or_dates) do |date|
    until is_business_day? date
      date += case direction
              when :forward
                1
              when :backward
                -1
              else
                raise ArgumentError, "Invalid direction supplied: '#{direction}' should instead be :forward or :backward"
              end
    end

    date
  end
end

#preceding_business_day(date_or_dates) ⇒ Date

Returns The business day immediately prior to <date>.

Parameters:

  • date_or_dates (Date or Array)

    The day(s) to start from.

Returns:

  • (Date)

    The business day immediately prior to <date>.



71
72
73
74
75
76
77
78
79
# File 'lib/business_calendar/calendar.rb', line 71

def preceding_business_day(date_or_dates)
  with_one_or_many(date_or_dates) do |date|
    begin
      date = date - 1
    end until is_business_day? date

    date
  end
end

#subtract_business_days(date_or_dates, num = 1) ⇒ Date Also known as: subtract_business_day

Returns The business date to which adding <num> business dats would arrive at <date>.

Parameters:

  • date_or_dates (Date or Array)

    The day(s) to start from.

  • num (Integer) (defaults to: 1)

    Number of days to retreat. If negative, this will call ‘add_business_days`.

Returns:

  • (Date)

    The business date to which adding <num> business dats would arrive at <date>.



59
60
61
62
63
64
65
66
# File 'lib/business_calendar/calendar.rb', line 59

def subtract_business_days(date_or_dates, num=1)
  return add_business_days(date_or_dates, -num) if num < 0

  with_one_or_many(date_or_dates) do |date|
    num.times { date = preceding_business_day(date) }
    date
  end
end