business_time 0.7.4 → 0.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5bdd88444abb3662202edb5a58a7966198095d0c
4
- data.tar.gz: d3bb972b85a2f229c34a88511bcb6eb9595f8589
3
+ metadata.gz: 6a751f4e1f9392f84ebca332f961e63434779054
4
+ data.tar.gz: aed6514ab58ee91cac9d45414459d12cdb7b9e7f
5
5
  SHA512:
6
- metadata.gz: b4d19b1491299ca47b3a765f701ba6ba909a5af84925005c75262679b4d193c70520d7938bc23c694fc03d5ee509c742f472285d82da75050aa457513d2f5f5f
7
- data.tar.gz: c959f75f0cc63e165e7a55bceaddbc9dceefb0db9491cbeec38bf75944359c0113e20aa9a22460ee650071e6a7af515b7de6e3c3ceb4fa71004bda8f76f5e0fd
6
+ metadata.gz: 4e98626ba766dccef9d6f7826b456e17eada6258ad1e130d39a6fa423b4e99b9e301b8fb0748dfe6af5d172073b84c646ff96edaa4544fb1fa1ce60f4a49674d
7
+ data.tar.gz: 147619baf4a120328a78df160e4469874a040559b7acd4fb1fff5eacd0fb199ad904a3c239b25f376bdd63ffb6e1ecbeb722d8078163c69ea3a41adbf050e321
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009,2010,2011,2012 bokmann
1
+ Copyright (c) 2009-2016 bokmann
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -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
- * install the gem
18
+ === install the gem
19
19
 
20
20
  gem install business_time
21
21
 
22
- * open up your console
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
- # and we can do it from any Date or Time object.
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
- # We can adjust the start and end time of our business hours
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
- # and we can add holidays that don't count as business days
61
- # July 5 in 2010 is a monday that the U.S. takes off because our independence day falls on that Sunday.
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
- # plus, we can change the work week:
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
- # as alternative we also can change the business hours for each work day:
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
- # you can also calculate business duration between two dates
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
- # or you can calculate business duration between two Time objects
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
- # you can also determine if a given time is within business hours
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
- # note that counterintuitively, durations might not be quite what you expect when involving weekends.
97
- # Consider the following example:
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
- # why does this happen? Feb 4 2012 is a Saturday. That time will roll over to
103
- # Monday, Feb 6th 2012, 9:00am. The business time between 10:40am friday and 9am monday is
104
- # 6 hours and 20 minutes. From a quick inspection of the code, it looks like it should be 8 hours.
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
- # or you can calculate business dates between two dates
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
- # you can get the first workday after a time or return itself if it is a workday
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,2011,2012,2013 bokmann. See LICENSE for details.
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 = time + 1.day
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 = time - 1.day
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
@@ -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
- old = config().dup
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.config = old
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 = default_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
- (self...to_date).select { |day| day.workday? }
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
@@ -1,3 +1,3 @@
1
1
  module BusinessTime
2
- VERSION = "0.7.4"
2
+ VERSION = "0.7.5"
3
3
  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
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: 2015-04-12 00:00:00.000000000 Z
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@codesherpas.com
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.2.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