Class: Timecalculator::Calculator
- Inherits:
-
Object
- Object
- Timecalculator::Calculator
- Defined in:
- lib/timecalculator/calculator.rb
Instance Method Summary collapse
- #batch_working_minutes_between_to_datetimes(dates = []) ⇒ Object
- #datetime_from_date_and_time(date, hour) ⇒ Object
- #days_between_dates(date1, date2) ⇒ Object
- #ending_time(date_time) ⇒ Object
- #full_day_minutes ⇒ Object
- #full_day_minutes_between_dates(date1, date2) ⇒ Object
- #full_day_minutes_between_dates_with_boundaries(dt1, dt2) ⇒ Object
- #holiday?(date) ⇒ Boolean
-
#initialize(**options) ⇒ Calculator
constructor
def initialize(day_hour_begin = 9, day_hour_end = 18, lunch_time=13, holidays = []).
- #lunch_time(time1, time2) ⇒ Object
- #min_max_time(time1 = {}, time2 = {}) ⇒ Object
- #minutes_between_two_times(time1 = {}, time2 = {}) ⇒ Object
- #start_time(date_time) ⇒ Object
- #weekdays ⇒ Object
- #weekend?(date) ⇒ Boolean
- #working_day?(date) ⇒ Boolean
- #working_days_between_dates(date1, date2) ⇒ Object
- #working_minutes_between_to_datetimes(dt1, dt2) ⇒ Object
- #working_minutes_between_to_times(time1, time2) ⇒ Object
Constructor Details
#initialize(**options) ⇒ Calculator
def initialize(day_hour_begin = 9, day_hour_end = 18, lunch_time=13, holidays = [])
6 7 8 9 10 11 |
# File 'lib/timecalculator/calculator.rb', line 6 def initialize(**) @day_hour_begin = .fetch(:day_hour_begin, 9) @day_hour_end = .fetch(:day_hour_end, 18) @lunch_time = .fetch(:lunch_time, [13]) @holidays = .fetch(:holidays, []).reject { |e| e.to_s.empty? }.map(&:to_date) end |
Instance Method Details
#batch_working_minutes_between_to_datetimes(dates = []) ⇒ Object
13 14 15 16 17 |
# File 'lib/timecalculator/calculator.rb', line 13 def batch_working_minutes_between_to_datetimes(dates = []) dates.reduce(0) do |sum, batch| sum + working_minutes_between_to_datetimes(DateTime.parse(batch.first), DateTime.parse(batch.last)) end end |
#datetime_from_date_and_time(date, hour) ⇒ Object
51 52 53 |
# File 'lib/timecalculator/calculator.rb', line 51 def datetime_from_date_and_time(date, hour) DateTime.new(date.year, date.month, date.day, hour, 0, 0, now.zone) end |
#days_between_dates(date1, date2) ⇒ Object
109 110 111 |
# File 'lib/timecalculator/calculator.rb', line 109 def days_between_dates(date1, date2) (date1.to_date...date2.to_date) end |
#ending_time(date_time) ⇒ Object
71 72 73 74 75 76 77 78 79 80 |
# File 'lib/timecalculator/calculator.rb', line 71 def ending_time(date_time) hour = date_time.fetch(:h, 0) minute = date_time.fetch(:m, 0) if hour == @lunch_time.include?(hour) minute = 0 elsif hour >= @day_hour_end hour, minute = @day_hour_end, 0 end { h: hour, m: minute } end |
#full_day_minutes ⇒ Object
86 87 88 |
# File 'lib/timecalculator/calculator.rb', line 86 def full_day_minutes @full_day_minutes ||= (@day_hour_end - @day_hour_begin - @lunch_time.count) * 60 end |
#full_day_minutes_between_dates(date1, date2) ⇒ Object
39 40 41 |
# File 'lib/timecalculator/calculator.rb', line 39 def full_day_minutes_between_dates(date1, date2) working_days_between_dates(date1, date2).count * full_day_minutes end |
#full_day_minutes_between_dates_with_boundaries(dt1, dt2) ⇒ Object
29 30 31 32 33 34 35 36 37 |
# File 'lib/timecalculator/calculator.rb', line 29 def full_day_minutes_between_dates_with_boundaries(dt1, dt2) minutes = 0 unless holiday?(dt1) || dt1.hour >= @day_hour_end minutes += working_minutes_between_to_times({ h: dt1.hour, m: dt1.minute }, { h: @day_hour_end }) end minutes += full_day_minutes_between_dates(dt1, dt2) minutes += working_minutes_between_to_times({ h: @day_hour_begin }, { h: dt2.hour, m: dt2.minute }) unless holiday?(dt2) minutes end |
#holiday?(date) ⇒ Boolean
123 124 125 126 127 |
# File 'lib/timecalculator/calculator.rb', line 123 def holiday?(date) return false unless date @holidays.include?(date.to_date) end |
#lunch_time(time1, time2) ⇒ Object
55 56 57 58 |
# File 'lib/timecalculator/calculator.rb', line 55 def lunch_time(time1, time2) time_range = (time1...time2) @lunch_time.reduce(0) { |sum, lunch_time| sum + (time_range.cover?(lunch_time) ? 60 : 0) } end |
#min_max_time(time1 = {}, time2 = {}) ⇒ Object
99 100 101 102 103 104 105 106 107 |
# File 'lib/timecalculator/calculator.rb', line 99 def min_max_time(time1 = {}, time2 = {}) if time1.fetch(:h, 0) == time2.fetch(:h, 0) { min: time1.fetch(:m, 0) < time2.fetch(:m, 0) ? time1 : time2, max: time1.fetch(:m, 0) > time2.fetch(:m, 0) ? time1 : time2 } else { min: time1.fetch(:h, 0) < time2.fetch(:h, 0) ? time1 : time2, max: time1.fetch(:h, 0) > time2.fetch(:h, 0) ? time1 : time2 } end end |
#minutes_between_two_times(time1 = {}, time2 = {}) ⇒ Object
90 91 92 93 94 95 96 97 |
# File 'lib/timecalculator/calculator.rb', line 90 def minutes_between_two_times(time1 = {}, time2 = {}) sorted_times = min_max_time(time1, time2) max_h = sorted_times[:max].fetch(:h, 0) min_h = sorted_times[:min].fetch(:h, 0) max_m = sorted_times[:max].fetch(:m, 0) min_m = sorted_times[:min].fetch(:m, 0) ((max_h - min_h) * 60) + (max_m - min_m) end |
#start_time(date_time) ⇒ Object
60 61 62 63 64 65 66 67 68 69 |
# File 'lib/timecalculator/calculator.rb', line 60 def start_time(date_time) hour = date_time.fetch(:h, 0) minute = date_time.fetch(:m, 0) if @lunch_time.include?(hour) hour, minute = hour + 1, 0 elsif hour < @day_hour_begin hour, minute = @day_hour_begin, 0 end { h: hour, m: minute } end |
#weekdays ⇒ Object
113 114 115 |
# File 'lib/timecalculator/calculator.rb', line 113 def weekdays @weekdays ||= [0, 6] end |
#weekend?(date) ⇒ Boolean
117 118 119 120 121 |
# File 'lib/timecalculator/calculator.rb', line 117 def weekend?(date) return false unless date weekdays.include?(date.wday) end |
#working_day?(date) ⇒ Boolean
129 130 131 |
# File 'lib/timecalculator/calculator.rb', line 129 def working_day?(date) !(weekend?(date) || holiday?(date)) end |
#working_days_between_dates(date1, date2) ⇒ Object
82 83 84 |
# File 'lib/timecalculator/calculator.rb', line 82 def working_days_between_dates(date1, date2) days_between_dates(date1 + 1, date2).filter { |date| working_day?(date) } end |
#working_minutes_between_to_datetimes(dt1, dt2) ⇒ Object
19 20 21 22 23 24 25 26 27 |
# File 'lib/timecalculator/calculator.rb', line 19 def working_minutes_between_to_datetimes(dt1, dt2) if dt1.to_date == dt2.to_date working_minutes_between_to_times({ h: dt1.hour, m: dt1.minute }, { h: dt2.hour, m: dt2.minute }) elsif dt1 < dt2 full_day_minutes_between_dates_with_boundaries(dt1, dt2) else full_day_minutes_between_dates_with_boundaries(dt2, dt1) end end |
#working_minutes_between_to_times(time1, time2) ⇒ Object
43 44 45 46 47 48 49 |
# File 'lib/timecalculator/calculator.rb', line 43 def working_minutes_between_to_times(time1, time2) sorted_times = min_max_time(time1, time2) start_time = start_time(sorted_times[:min]) ending_time = ending_time(sorted_times[:max]) offset = minutes_between_two_times(start_time, ending_time) offset - lunch_time(start_time[:h], ending_time[:h]) end |