business_time 0.7.4 → 0.7.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.rdoc +30 -19
- data/lib/business_time/business_days.rb +24 -2
- data/lib/business_time/business_hours.rb +10 -0
- data/lib/business_time/config.rb +18 -3
- data/lib/business_time/core_ext/date.rb +9 -5
- data/lib/business_time/time_extensions.rb +11 -1
- data/lib/business_time/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a751f4e1f9392f84ebca332f961e63434779054
|
4
|
+
data.tar.gz: aed6514ab58ee91cac9d45414459d12cdb7b9e7f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e98626ba766dccef9d6f7826b456e17eada6258ad1e130d39a6fa423b4e99b9e301b8fb0748dfe6af5d172073b84c646ff96edaa4544fb1fa1ce60f4a49674d
|
7
|
+
data.tar.gz: 147619baf4a120328a78df160e4469874a040559b7acd4fb1fff5eacd0fb199ad904a3c239b25f376bdd63ffb6e1ecbeb722d8078163c69ea3a41adbf050e321
|
data/LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -15,11 +15,11 @@ as well as helpers to do that from any provided date or time.
|
|
15
15
|
I needed this, but taking into account business hours/days and holidays.
|
16
16
|
|
17
17
|
== Usage
|
18
|
-
|
18
|
+
=== install the gem
|
19
19
|
|
20
20
|
gem install business_time
|
21
21
|
|
22
|
-
|
22
|
+
=== open up your console
|
23
23
|
|
24
24
|
# if in irb, add these lines:
|
25
25
|
|
@@ -42,8 +42,12 @@ I needed this, but taking into account business hours/days and holidays.
|
|
42
42
|
1.business_day.ago
|
43
43
|
4.business_days.ago
|
44
44
|
8.business_days.ago
|
45
|
+
|
46
|
+
Date.today.workday?
|
47
|
+
Date.parse("2015-12-09").workday?
|
48
|
+
Date.parse("2015-12-12").workday?
|
45
49
|
|
46
|
-
|
50
|
+
And we can do it from any Date or Time object.
|
47
51
|
my_birthday = Date.parse("August 4th, 1969")
|
48
52
|
8.business_days.after(my_birthday)
|
49
53
|
8.business_days.before(my_birthday)
|
@@ -53,24 +57,24 @@ I needed this, but taking into account business hours/days and holidays.
|
|
53
57
|
8.business_days.before(my_birthday)
|
54
58
|
|
55
59
|
|
56
|
-
|
60
|
+
We can adjust the start and end time of our business hours
|
57
61
|
BusinessTime::Config.beginning_of_workday = "8:30 am"
|
58
62
|
BusinessTime::Config.end_of_workday = "5:30 pm"
|
59
63
|
|
60
|
-
|
61
|
-
|
64
|
+
and we can add holidays that don't count as business days
|
65
|
+
July 5 in 2010 is a monday that the U.S. takes off because our independence day falls on that Sunday.
|
62
66
|
three_day_weekend = Date.parse("July 5th, 2010")
|
63
67
|
BusinessTime::Config.holidays << three_day_weekend
|
64
68
|
friday_afternoon = Time.parse("July 2nd, 2010, 4:50 pm")
|
65
69
|
tuesday_morning = 1.business_hour.after(friday_afternoon)
|
66
70
|
|
67
|
-
|
71
|
+
plus, we can change the work week:
|
68
72
|
# July 9th in 2010 is a Friday.
|
69
73
|
BusinessTime::Config.work_week = [:sun, :mon, :tue, :wed, :thu]
|
70
74
|
thursday_afternoon = Time.parse("July 8th, 2010, 4:50 pm")
|
71
75
|
sunday_morning = 1.business_hour.after(thursday_afternoon)
|
72
76
|
|
73
|
-
|
77
|
+
As alternative we also can change the business hours for each work day:
|
74
78
|
BusinessTime::Config.work_hours = {
|
75
79
|
:mon=>["9:00","17:00"],
|
76
80
|
:fri=>["9:00","17:00"],
|
@@ -80,39 +84,46 @@ I needed this, but taking into account business hours/days and holidays.
|
|
80
84
|
monday = Time.parse("December 27, 2010 11:00")
|
81
85
|
working_hours = friday.business_time_until(monday) # 9.hours
|
82
86
|
|
83
|
-
|
87
|
+
You can also calculate business duration between two dates
|
84
88
|
friday = Date.parse("December 24, 2010")
|
85
89
|
monday = Date.parse("December 27, 2010")
|
86
90
|
friday.business_days_until(monday) #=> 1
|
87
91
|
|
88
|
-
|
92
|
+
Or you can calculate business duration between two Time objects
|
89
93
|
ticket_reported = Time.parse("February 3, 2012, 10:40 am")
|
90
94
|
ticket_resolved = Time.parse("February 4, 2012, 10:50 am")
|
91
95
|
ticket_reported.business_time_until(ticket_resolved) #=> 8.hours + 10.minutes
|
92
96
|
|
93
|
-
|
97
|
+
You can also determine if a given time is within business hours
|
94
98
|
Time.parse("February 3, 2012, 10:00 am").during_business_hours?
|
95
99
|
|
96
|
-
|
97
|
-
|
100
|
+
Note that counterintuitively, durations might not be quite what you expect when involving weekends.
|
101
|
+
Consider the following example:
|
98
102
|
ticket_reported = Time.parse("February 3, 2012, 10:40 am")
|
99
103
|
ticket_resolved = Time.parse("February 4, 2012, 10:40 am")
|
100
104
|
ticket_reported.business_time_until(ticket_resolved) # will equal 6 hours and 20 minutes!
|
101
105
|
|
102
|
-
|
103
|
-
|
104
|
-
|
106
|
+
Why does this happen? Feb 4 2012 is a Saturday. That time will roll over to
|
107
|
+
Monday, Feb 6th 2012, 9:00am. The business time between 10:40am friday and 9am monday is
|
108
|
+
6 hours and 20 minutes. From a quick inspection of the code, it looks like it should be 8 hours.
|
105
109
|
|
106
|
-
|
110
|
+
Or you can calculate business dates between two dates
|
107
111
|
monday = Date.parse("December 20, 2010")
|
108
112
|
wednesday = Date.parse("December 22, 2010")
|
109
113
|
monday.business_dates_until(wednesday) #=> [Mon, 20 Dec 2010, Tue, 21 Dec 2010]
|
110
114
|
|
111
|
-
|
115
|
+
You can get the first workday after a time or return itself if it is a workday
|
112
116
|
saturday = Time.parse("Sat Aug 9, 18:00:00, 2014")
|
113
117
|
monday = Time.parse("Mon Aug 11, 18:00:00, 2014")
|
114
118
|
Time.first_business_day(saturday) #=> "Mon Aug 11, 18:00:00, 2014"
|
115
119
|
Time.first_business_day(monday) #=> "Mon Aug 11, 18:00:00, 2014"
|
120
|
+
|
121
|
+
# similar to Time#first_business_day Time#previous_business_day only cares about
|
122
|
+
# workdays:
|
123
|
+
saturday = Time.parse("Sat Aug 9, 18:00:00, 2014")
|
124
|
+
monday = Time.parse("Mon Aug 11, 18:00:00, 2014")
|
125
|
+
Time.previous_business_day(saturday) #=> "Fri Aug 8, 18:00:00, 2014"
|
126
|
+
Time.previous_business_day(monday) #=> "Mon Aug 11, 18:00:00, 2014"
|
116
127
|
== Rails generator
|
117
128
|
|
118
129
|
rails generate business_time:config
|
@@ -205,4 +216,4 @@ I'm hoping Arild and I write some good blog entries on the subject at http://blo
|
|
205
216
|
|
206
217
|
== Copyright
|
207
218
|
|
208
|
-
Copyright (c) 2010
|
219
|
+
Copyright (c) 2010-2016 bokmann. See LICENSE for details.
|
@@ -2,15 +2,30 @@ require 'active_support/time'
|
|
2
2
|
|
3
3
|
module BusinessTime
|
4
4
|
class BusinessDays
|
5
|
+
include Comparable
|
6
|
+
attr_reader :days
|
7
|
+
|
5
8
|
def initialize(days)
|
6
9
|
@days = days
|
7
10
|
end
|
8
11
|
|
12
|
+
def <=>(other)
|
13
|
+
if other.class != self.class
|
14
|
+
raise ArgumentError.new("#{self.class} can't be compared with #{other.class}")
|
15
|
+
end
|
16
|
+
self.days <=> other.days
|
17
|
+
end
|
18
|
+
|
9
19
|
def after(time = Time.current)
|
10
20
|
days = @days
|
11
21
|
while days > 0 || !time.workday?
|
12
22
|
days -= 1 if time.workday?
|
13
|
-
time
|
23
|
+
time += 1.day
|
24
|
+
end
|
25
|
+
# If we have a Time or DateTime object, we can roll_forward to the
|
26
|
+
# beginning of the next business day
|
27
|
+
if time.is_a?(Time) || time.is_a?(DateTime)
|
28
|
+
time = Time.roll_forward(time) unless time.during_business_hours?
|
14
29
|
end
|
15
30
|
time
|
16
31
|
end
|
@@ -22,7 +37,14 @@ module BusinessTime
|
|
22
37
|
days = @days
|
23
38
|
while days > 0 || !time.workday?
|
24
39
|
days -= 1 if time.workday?
|
25
|
-
time
|
40
|
+
time -= 1.day
|
41
|
+
end
|
42
|
+
# If we have a Time or DateTime object, we can roll_backward to the
|
43
|
+
# beginning of the previous business day
|
44
|
+
if time.is_a?(Time) || time.is_a?(DateTime)
|
45
|
+
unless time.during_business_hours?
|
46
|
+
time = Time.beginning_of_workday(Time.roll_backward(time))
|
47
|
+
end
|
26
48
|
end
|
27
49
|
time
|
28
50
|
end
|
@@ -1,10 +1,20 @@
|
|
1
1
|
module BusinessTime
|
2
2
|
|
3
3
|
class BusinessHours
|
4
|
+
include Comparable
|
5
|
+
attr_reader :hours
|
6
|
+
|
4
7
|
def initialize(hours)
|
5
8
|
@hours = hours
|
6
9
|
end
|
7
10
|
|
11
|
+
def <=>(other)
|
12
|
+
if other.class != self.class
|
13
|
+
raise ArgumentError.new("#{self.class.to_s} can't be compared with #{other.class.to_s}")
|
14
|
+
end
|
15
|
+
self.hours <=> other.hours
|
16
|
+
end
|
17
|
+
|
8
18
|
def ago
|
9
19
|
Time.zone ? before(Time.zone.now) : before(Time.now)
|
10
20
|
end
|
data/lib/business_time/config.rb
CHANGED
@@ -20,13 +20,27 @@ module BusinessTime
|
|
20
20
|
private
|
21
21
|
|
22
22
|
def config
|
23
|
+
return local_config if local_config?
|
23
24
|
Thread.main[:business_time_config] ||= default_config
|
24
25
|
end
|
25
26
|
|
26
27
|
def config=(config)
|
28
|
+
return self.local_config = config if local_config?
|
27
29
|
Thread.main[:business_time_config] = config
|
28
30
|
end
|
29
31
|
|
32
|
+
def local_config
|
33
|
+
Thread.current[:business_time_local_config]
|
34
|
+
end
|
35
|
+
|
36
|
+
def local_config=(config)
|
37
|
+
Thread.current[:business_time_local_config] = config
|
38
|
+
end
|
39
|
+
|
40
|
+
def local_config?
|
41
|
+
!local_config.nil?
|
42
|
+
end
|
43
|
+
|
30
44
|
def threadsafe_cattr_accessor(name)
|
31
45
|
define_singleton_method name do
|
32
46
|
config[name]
|
@@ -131,11 +145,11 @@ module BusinessTime
|
|
131
145
|
end
|
132
146
|
|
133
147
|
def with(config)
|
134
|
-
|
148
|
+
self.local_config = config().dup
|
135
149
|
config.each { |k,v| send("#{k}=", v) } # calculations are done on setting
|
136
150
|
yield
|
137
151
|
ensure
|
138
|
-
self.
|
152
|
+
self.local_config = nil
|
139
153
|
end
|
140
154
|
|
141
155
|
def default_config
|
@@ -154,7 +168,8 @@ module BusinessTime
|
|
154
168
|
end
|
155
169
|
|
156
170
|
def reset
|
157
|
-
self.config
|
171
|
+
self.config = default_config
|
172
|
+
self.local_config = nil
|
158
173
|
end
|
159
174
|
|
160
175
|
def deep_dup(object)
|
@@ -2,11 +2,15 @@
|
|
2
2
|
class Date
|
3
3
|
include BusinessTime::TimeExtensions
|
4
4
|
|
5
|
-
def business_days_until(to_date)
|
6
|
-
business_dates_until(to_date).size
|
5
|
+
def business_days_until(to_date, inclusive = false)
|
6
|
+
business_dates_until(to_date, inclusive).size
|
7
7
|
end
|
8
8
|
|
9
|
-
def business_dates_until(to_date)
|
10
|
-
|
9
|
+
def business_dates_until(to_date, inclusive = false)
|
10
|
+
if inclusive
|
11
|
+
(self..to_date).select(&:workday?)
|
12
|
+
else
|
13
|
+
(self...to_date).select(&:workday?)
|
14
|
+
end
|
11
15
|
end
|
12
|
-
end
|
16
|
+
end
|
@@ -98,6 +98,16 @@ module BusinessTime
|
|
98
98
|
prev_business_time
|
99
99
|
end
|
100
100
|
|
101
|
+
# Returns the time parameter itself if it is a business day
|
102
|
+
# or else returns the previous business day
|
103
|
+
def previous_business_day(time)
|
104
|
+
while !time.workday?
|
105
|
+
time = time - 1.day
|
106
|
+
end
|
107
|
+
|
108
|
+
time
|
109
|
+
end
|
110
|
+
|
101
111
|
def work_hours_total(day)
|
102
112
|
return 0 unless day.workday?
|
103
113
|
|
@@ -159,7 +169,7 @@ module BusinessTime
|
|
159
169
|
first_day + days_in_between + last_day
|
160
170
|
end * direction
|
161
171
|
end
|
162
|
-
|
172
|
+
|
163
173
|
def during_business_hours?
|
164
174
|
self.workday? && self.to_i.between?(Time.beginning_of_workday(self).to_i, Time.end_of_workday(self).to_i)
|
165
175
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: business_time
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- bokmann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-04-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -96,7 +96,7 @@ dependencies:
|
|
96
96
|
version: '0'
|
97
97
|
description: Have you ever wanted to do things like "6.business_days.from_now" and
|
98
98
|
have weekends and holidays taken into account? Now you can.
|
99
|
-
email: dbock@
|
99
|
+
email: dbock@javaguy.org
|
100
100
|
executables: []
|
101
101
|
extensions: []
|
102
102
|
extra_rdoc_files: []
|
@@ -137,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
137
|
version: '0'
|
138
138
|
requirements: []
|
139
139
|
rubyforge_project:
|
140
|
-
rubygems_version: 2.
|
140
|
+
rubygems_version: 2.4.5
|
141
141
|
signing_key:
|
142
142
|
specification_version: 4
|
143
143
|
summary: Support for doing time math in business hours and days
|