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 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