Class: Time

Inherits:
Object
  • Object
show all
Defined in:
lib/business_time/core_ext/time.rb,
lib/business_time/core_ext/time.rb

Overview

Add workday and weekday concepts to the Time class

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.after_business_hours?(time) ⇒ Boolean

Returns:

  • (Boolean)


39
40
41
# File 'lib/business_time/core_ext/time.rb', line 39

def after_business_hours?(time)
  time.to_i > end_of_workday(time).to_i
end

.before_business_hours?(time) ⇒ Boolean

Returns:

  • (Boolean)


35
36
37
# File 'lib/business_time/core_ext/time.rb', line 35

def before_business_hours?(time)
  time.to_i < beginning_of_workday(time).to_i
end

.beginning_of_workday(day) ⇒ Object

Gives the time at the beginning of the workday, assuming that this time falls on a workday. Note: It pretends that this day is a workday whether or not it really is a workday.



18
19
20
21
# File 'lib/business_time/core_ext/time.rb', line 18

def beginning_of_workday(day)
  beginning_of_workday = Time.parse(BusinessTime::Config.beginning_of_workday(day))
  change_time(day,beginning_of_workday.hour,beginning_of_workday.min,beginning_of_workday.sec)
end

.end_of_workday(day) ⇒ Object

Gives the time at the end of the workday, assuming that this time falls on a workday. Note: It pretends that this day is a workday whether or not it really is a workday.



9
10
11
12
# File 'lib/business_time/core_ext/time.rb', line 9

def end_of_workday(day)
  end_of_workday = Time.parse(BusinessTime::Config.end_of_workday(day))
  change_time(day,end_of_workday.hour,end_of_workday.min,end_of_workday.sec)
end

.roll_backward(time) ⇒ Object

Rolls backwards to the previous end_of_workday when the time is outside of business hours



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/business_time/core_ext/time.rb', line 64

def roll_backward(time)
  if (Time.before_business_hours?(time) || !Time.workday?(time))
    prev_business_time = Time.end_of_workday(time) - 1.day
  elsif Time.after_business_hours?(time)
    prev_business_time = Time.end_of_workday(time)
  else
    prev_business_time = time.clone
  end

  while !Time.workday?(prev_business_time)
    prev_business_time -= 1.day
  end

  prev_business_time
end

.roll_forward(time) ⇒ Object

Rolls forward to the next beginning_of_workday when the time is outside of business hours



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/business_time/core_ext/time.rb', line 45

def roll_forward(time)

  if (Time.before_business_hours?(time) || !Time.workday?(time))
    next_business_time = Time.beginning_of_workday(time)
  elsif Time.after_business_hours?(time) || Time.end_of_workday(time) == time
    next_business_time = Time.beginning_of_workday(time + 1.day)
  else
    next_business_time = time.clone
  end

  while !Time.workday?(next_business_time)
    next_business_time = Time.beginning_of_workday(next_business_time + 1.day)
  end

  next_business_time
end

.weekday?(day) ⇒ Boolean

True if this time falls on a weekday.

Returns:

  • (Boolean)


31
32
33
# File 'lib/business_time/core_ext/time.rb', line 31

def weekday?(day)
  BusinessTime::Config.weekdays.include? day.wday
end

.workday?(day) ⇒ Boolean

True if this time is on a workday (between 00:00:00 and 23:59:59), even if this time falls outside of normal business hours.

Returns:

  • (Boolean)


25
26
27
28
# File 'lib/business_time/core_ext/time.rb', line 25

def workday?(day)
  Time.weekday?(day) &&
      !BusinessTime::Config.holidays.include?(day.to_date)
end

Instance Method Details

#business_time_until(to_time) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/business_time/core_ext/time.rb', line 96

def business_time_until(to_time)

  # Make sure that we will calculate time from A to B "clockwise"
  direction = 1
  if self < to_time
    time_a = self
    time_b = to_time
  else
    time_a = to_time
    time_b = self
    direction = -1
  end

  # Align both times to the closest business hours
  time_a = Time::roll_forward(time_a)
  time_b = Time::roll_forward(time_b)

  # If same date, then calculate difference straight forward
  if time_a.to_date == time_b.to_date
    result = time_b - time_a
    return result *= direction
  end

  # Both times are in different dates
  #result = Time.parse(time_a.strftime('%Y-%m-%d ') + BusinessTime::Config.end_of_workday) - time_a   # First day
  #result += time_b - Time.parse(time_b.strftime('%Y-%m-%d ') + BusinessTime::Config.beginning_of_workday) # Last day

  result = 0

  # All days in between
  time_c = time_a
  while time_c.to_i < time_b.to_i do
    end_of_workday = Time.end_of_workday(time_c)
    if time_c.to_date == time_b.to_date
      if end_of_workday < time_b
        result += end_of_workday - time_c
        break
      else
        result += time_b - time_c
        break
      end
    else
      result += end_of_workday - time_c
      time_c = Time::roll_forward(end_of_workday)
    end
    result += 1 if end_of_workday.to_s =~ /23:59:59/
  end

  # Make sure that sign is correct
  result *= direction
end