business_time 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -92,9 +92,20 @@ The generator will add a /config/business_time.yml and a /config/initializers/bu
92
92
  == Outside of Rails
93
93
  This code does depend on ActiveSupport, but nothing else within rails. Even then, it would be pretty easy to break that dependency as well (but would add some code bloat and remove some clarity). Feel free to use it on any ruby project you'd like!
94
94
 
95
+ == Timezone support
96
+ This gem strives to be timezone-agnostic. Due to some complications in the handling of timezones in the built in Time class, and some complexities (bugs?) in the timeWithZone class, this was harder than expected... but here's the idea:
97
+ * When you configure the gem with something like 9:00am as the start time, this is agnostic of time zone.
98
+ * When you are dealing with a Time or TimeWithZone class, the timezone is preserved and the beginning and end of times for the business day are referenced in that time zone.
99
+
100
+ This can lead to some wierd looking effects if, say, you are in the Eastern time zone but doing everything in UTC times... Your business day will appear to start and end at 9:00 and 5:00 UTC. If this seems perplexing to you, I can almost guarantee you are in over your head with timezones in other ways too, this is just the first place you encountered it. Timezone relative date handling gets more and more complicated every time you look at it and takes a long time before it starts to seem simple again. I'm hoping Arild and I write some good blog entries on the subject at http://blog.codesherpas.com.
101
+
95
102
  == Contributors
96
103
  * David Bock http://github.com/bokmann
97
104
  * Enrico Bianco http://github.com/enricob
105
+ * Arild Shirazi http://github.com/ashirazi
106
+
107
+ (Special thanks for Arild on the complexities of dealing with TimeWithZone)
108
+
98
109
  == Note on Patches/Pull Requests
99
110
 
100
111
  * Fork the project.
@@ -108,7 +119,6 @@ This code does depend on ActiveSupport, but nothing else within rails. Even the
108
119
  == TODO
109
120
  * I'd like to return ActiveSupport::TimeWithZone just like the equivalent ActiveSupport helpers do.
110
121
  * if it doesn't pollute the logic too much, I'd like to vary the days counted as 'business days'. Bakers often don't work on Mondays, for instance.
111
- * We don't care much about timezones. Dunno if thats an issue.
112
122
 
113
123
  == Copyright
114
124
 
data/Rakefile CHANGED
@@ -10,7 +10,7 @@ begin
10
10
  gem.email = "dbock@codesherpas.com"
11
11
  gem.homepage = "http://github.com/bokmann/business_time"
12
12
  gem.authors = ["bokmann"]
13
- gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
13
+ gem.add_development_dependency "shoulda", ">= 0"
14
14
  gem.add_dependency('activesupport','>= 2.0.0')
15
15
  gem.files += FileList['lib/generators/**/*.rb']
16
16
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.2
1
+ 0.3.0
@@ -6,10 +6,11 @@ module BusinessTime
6
6
  end
7
7
 
8
8
  def after(time = Time.now)
9
+ time = Time.zone ? Time.zone.parse(time.to_s) : Time.parse(time.to_s)
9
10
  @days.times do
10
11
  begin
11
12
  time = time + 1.day
12
- end until time.workday?
13
+ end until Time.workday?(time)
13
14
  end
14
15
  time
15
16
  end
@@ -18,10 +19,11 @@ module BusinessTime
18
19
  alias_method :since, :after
19
20
 
20
21
  def before(time = Time.now)
22
+ time = Time.zone ? Time.zone.parse(time.to_s) : Time.parse(time.to_s)
21
23
  @days.times do
22
24
  begin
23
25
  time = time - 1.day
24
- end until time.workday?
26
+ end until Time.workday?(time)
25
27
  end
26
28
  time
27
29
  end
@@ -31,4 +33,4 @@ module BusinessTime
31
33
 
32
34
  end
33
35
 
34
- end
36
+ end
@@ -4,53 +4,66 @@ module BusinessTime
4
4
  def initialize(hours)
5
5
  @hours = hours
6
6
  end
7
-
7
+
8
8
  def ago
9
- before(Time.now)
9
+ Time.zone ? before(Time.zone.now) : before(Time.now)
10
10
  end
11
-
11
+
12
12
  def from_now
13
- after(Time.now)
13
+ Time.zone ? after(Time.zone.now) : after(Time.now)
14
14
  end
15
-
15
+
16
16
  def after(time)
17
- time = time.roll_forward
18
- @hours.times do
19
- time = time + 1.hour #add an hour
20
-
21
- if (time > time.end_of_workday)
22
- time = time + off_hours # if that pushes us past business hours,
23
- end # roll into the next day
24
-
25
- while !time.workday?
26
- time = time + 1.day # if that pushes us into a non-business day,
27
- end # find the next business day
17
+ after_time = Time.roll_forward(time)
18
+ # Step through the hours, skipping over non-business hours
19
+ @hours.times do
20
+ after_time = after_time + 1.hour
21
+
22
+ # Ignore hours before opening and after closing
23
+ if (after_time > Time.end_of_workday(after_time))
24
+ after_time = after_time + off_hours
25
+ end
26
+
27
+ # Ignore weekends and holidays
28
+ while !Time.workday?(after_time)
29
+ after_time = after_time + 1.day
30
+ end
28
31
  end
29
- time
32
+ after_time
30
33
  end
31
-
34
+
32
35
  def before(time)
33
- time = time.roll_forward
34
- @hours.times do
35
- time = time - 1.hour #subtract an hour
36
-
37
- if (time < time.beginning_of_workday)
38
- time = time - off_hours # if that pushes us before business hours,
39
- end # roll into the previous day
40
-
41
- while !time.workday?
42
- time = time - 1.day # if that pushes us into a non-business day,
43
- end # find the previous business day
36
+ before_time = Time.roll_forward(time)
37
+ # Step through the hours, skipping over non-business hours
38
+ @hours.times do
39
+ before_time = before_time - 1.hour
40
+
41
+ # Ignore hours before opening and after closing
42
+ if (before_time < Time.beginning_of_workday(before_time))
43
+ before_time = before_time - off_hours
44
+ end
45
+
46
+ # Ignore weekends and holidays
47
+ while !Time.workday?(before_time)
48
+ before_time = before_time - 1.day
49
+ end
44
50
  end
45
- time
51
+ before_time
46
52
  end
47
-
53
+
48
54
  private
49
-
55
+
50
56
  def off_hours
51
- @gap ||= Time.parse(BusinessTime::Config.beginning_of_workday) -
52
- (Time.parse(BusinessTime::Config.end_of_workday) - 1.day)
57
+ return @gap if @gap
58
+ if Time.zone
59
+ gap_end = Time.zone.parse(BusinessTime::Config.beginning_of_workday)
60
+ gap_begin = (Time.zone.parse(BusinessTime::Config.end_of_workday)-1.day)
61
+ else
62
+ gap_end = Time.parse(BusinessTime::Config.beginning_of_workday)
63
+ gap_begin = (Time.parse(BusinessTime::Config.end_of_workday) - 1.day)
64
+ end
65
+ @gap = gap_end - gap_begin
53
66
  end
54
67
  end
55
-
56
- end
68
+
69
+ end
@@ -22,6 +22,7 @@ module BusinessTime
22
22
  # BusinessTime::Config.holidays << my_holiday_date_object
23
23
  # someplace in the initializers of your application.
24
24
  attr_accessor :holidays
25
+
25
26
  end
26
27
 
27
28
  def self.reset
@@ -45,7 +46,8 @@ module BusinessTime
45
46
  self.beginning_of_workday = data["business_time"]["beginning_of_workday"]
46
47
  self.end_of_workday = data["business_time"]["end_of_workday"]
47
48
  data["business_time"]["holidays"].each do |holiday|
48
- self.holidays << Date.parse(holiday)
49
+ self.holidays <<
50
+ Time.zone ? Time.zone.parse(holiday) : Time.parse(holiday)
49
51
  end
50
52
 
51
53
  end
@@ -1,54 +1,66 @@
1
1
  # Add workday and weekday concepts to the Time class
2
2
  class Time
3
- def end_of_workday
4
- Time.parse self.strftime("%B %d %Y #{BusinessTime::Config.end_of_workday}")
5
- end
6
-
7
- def beginning_of_workday
8
- Time.parse self.strftime("%B %d %Y #{BusinessTime::Config.beginning_of_workday}")
9
- end
10
-
11
- def workday?
12
- self.weekday? && !BusinessTime::Config.holidays.include?(self.to_date)
13
- end
14
-
15
- def weekday?
16
- [1,2,3,4,5].include? self.wday
17
- end
18
-
3
+ class << self
19
4
 
20
- def outsize_business_hours?
21
- before_business_hours? || after_business_hours? || !workday?
22
- end
23
-
24
- # rolls forward to the next beginning_of_workday
25
- # when the time is outside of business hours
26
- def roll_forward
27
- next_business_time = self
28
-
29
- if (before_business_hours? || !workday?)
30
- next_business_time = beginning_of_workday
5
+ # Gives the time at the end of the workday, assuming that this time falls on a
6
+ # workday.
7
+ # Note: It pretends that this day is a workday whether or not it really is a
8
+ # workday.
9
+ def end_of_workday(day)
10
+ format = "%B %d %Y #{BusinessTime::Config.end_of_workday}"
11
+ Time.zone ? Time.zone.parse(day.strftime(format)) :
12
+ Time.parse(day.strftime(format))
31
13
  end
32
-
33
- if after_business_hours?
34
- next_business_time = beginning_of_workday + 1.day
14
+
15
+ # Gives the time at the beginning of the workday, assuming that this time
16
+ # falls on a workday.
17
+ # Note: It pretends that this day is a workday whether or not it really is a
18
+ # workday.
19
+ def beginning_of_workday(day)
20
+ format = "%B %d %Y #{BusinessTime::Config.beginning_of_workday}"
21
+ Time.zone ? Time.zone.parse(day.strftime(format)) :
22
+ Time.parse(day.strftime(format))
23
+ end
24
+
25
+ # True if this time is on a workday (between 00:00:00 and 23:59:59), even if
26
+ # this time falls outside of normal business hours.
27
+ def workday?(day)
28
+ Time.weekday?(day) &&
29
+ !BusinessTime::Config.holidays.include?(day.to_date)
30
+ end
31
+
32
+ # True if this time falls on a weekday.
33
+ def weekday?(day)
34
+ # TODO AS: Internationalize this!
35
+ [1,2,3,4,5].include? day.wday
36
+ end
37
+
38
+ def before_business_hours?(time)
39
+ time < beginning_of_workday(time)
40
+ end
41
+
42
+ def after_business_hours?(time)
43
+ time > end_of_workday(time)
44
+ end
45
+
46
+ # Rolls forward to the next beginning_of_workday
47
+ # when the time is outside of business hours
48
+ def roll_forward(time)
49
+
50
+ if (Time.before_business_hours?(time) || !Time.workday?(time))
51
+ next_business_time = Time.beginning_of_workday(time)
52
+ elsif Time.after_business_hours?(time)
53
+ next_business_time = Time.beginning_of_workday(time) + 1.day
54
+ else
55
+ next_business_time = time.clone
56
+ end
57
+
58
+ while !Time.workday?(next_business_time)
59
+ next_business_time += 1.day
60
+ end
61
+
62
+ next_business_time
35
63
  end
36
-
37
- while !next_business_time.workday?
38
- next_business_time = next_business_time + 1.day
39
- end
40
64
 
41
- next_business_time
42
- end
43
-
44
- private
45
-
46
- def before_business_hours?
47
- (self < self.beginning_of_workday)
48
- end
49
-
50
- def after_business_hours?
51
- (self > self.end_of_workday)
52
65
  end
53
-
54
- end
66
+ end
data/test/helper.rb CHANGED
@@ -6,6 +6,7 @@ if RUBY_VERSION >= '1.9'
6
6
  require 'active_support/time'
7
7
  else
8
8
  require 'active_support'
9
+ require 'active_support/core_ext'
9
10
  end
10
11
 
11
12
  require 'test/unit'
@@ -2,66 +2,68 @@ require 'helper'
2
2
 
3
3
  class TestBusinessDays < Test::Unit::TestCase
4
4
 
5
- should "move to tomorrow if we add a business day" do
6
- first = Time.parse("April 13th, 2010, 11:00 am")
7
- later = 1.business_day.after(first)
8
- expected = Time.parse("April 14th, 2010, 11:00 am")
9
- assert expected == later
10
- end
5
+ context "with a standard Time object" do
6
+
7
+ should "move to tomorrow if we add a business day" do
8
+ first = Time.parse("April 13th, 2010, 11:00 am")
9
+ later = 1.business_day.after(first)
10
+ expected = Time.parse("April 14th, 2010, 11:00 am")
11
+ assert_equal expected, later
12
+ end
11
13
 
12
- should "move to yesterday is we subtract a business day" do
13
- first = Time.parse("April 13th, 2010, 11:00 am")
14
- before = 1.business_day.before(first)
15
- expected = Time.parse("April 12th, 2010, 11:00 am")
16
- assert expected == before
17
- end
14
+ should "move to yesterday is we subtract a business day" do
15
+ first = Time.parse("April 13th, 2010, 11:00 am")
16
+ before = 1.business_day.before(first)
17
+ expected = Time.parse("April 12th, 2010, 11:00 am")
18
+ assert_equal expected, before
19
+ end
18
20
 
19
- should "take into account the weekend when adding a day" do
20
- first = Time.parse("April 9th, 2010, 12:33 pm")
21
- after = 1.business_day.after(first)
22
- expected = Time.parse("April 12th, 2010, 12:33 pm")
23
- assert expected == after
24
- end
21
+ should "take into account the weekend when adding a day" do
22
+ first = Time.parse("April 9th, 2010, 12:33 pm")
23
+ after = 1.business_day.after(first)
24
+ expected = Time.parse("April 12th, 2010, 12:33 pm")
25
+ assert_equal expected, after
26
+ end
25
27
 
26
- should "take into account the weekend when subtracting a day" do
27
- first = Time.parse("April 12th, 2010, 12:33 pm")
28
- before = 1.business_day.before(first)
29
- expected = Time.parse("April 9th, 2010, 12:33 pm")
30
- assert expected == before
31
- end
28
+ should "take into account the weekend when subtracting a day" do
29
+ first = Time.parse("April 12th, 2010, 12:33 pm")
30
+ before = 1.business_day.before(first)
31
+ expected = Time.parse("April 9th, 2010, 12:33 pm")
32
+ assert_equal expected, before
33
+ end
32
34
 
33
- should "move forward one week when adding 5 business days" do
34
- first = Time.parse("April 9th, 2010, 12:33 pm")
35
- after = 5.business_days.after(first)
36
- expected = Time.parse("April 16th, 2010, 12:33 pm")
37
- assert expected == after
38
- end
39
-
40
- should "move backward one week when subtracting 5 business days" do
41
- first = Time.parse("April 16th, 2010, 12:33 pm")
42
- before = 5.business_days.before(first)
43
- expected = Time.parse("April 9th, 2010, 12:33 pm")
44
- assert expected == before
45
- end
35
+ should "move forward one week when adding 5 business days" do
36
+ first = Time.parse("April 9th, 2010, 12:33 pm")
37
+ after = 5.business_days.after(first)
38
+ expected = Time.parse("April 16th, 2010, 12:33 pm")
39
+ assert_equal expected, after
40
+ end
46
41
 
47
- should "take into account a holiday when adding a day" do
48
- three_day_weekend = Date.parse("July 5th, 2010")
49
- BusinessTime::Config.holidays << three_day_weekend
50
- friday_afternoon = Time.parse("July 2nd, 2010, 4:50 pm")
51
- tuesday_afternoon = 1.business_day.after(friday_afternoon)
52
- expected = Time.parse("July 6th, 2010, 4:50 pm")
53
- assert expected == tuesday_afternoon
54
- end
42
+ should "move backward one week when subtracting 5 business days" do
43
+ first = Time.parse("April 16th, 2010, 12:33 pm")
44
+ before = 5.business_days.before(first)
45
+ expected = Time.parse("April 9th, 2010, 12:33 pm")
46
+ assert_equal expected, before
47
+ end
55
48
 
49
+ should "take into account a holiday when adding a day" do
50
+ three_day_weekend = Date.parse("July 5th, 2010")
51
+ BusinessTime::Config.holidays << three_day_weekend
52
+ friday_afternoon = Time.parse("July 2nd, 2010, 4:50 pm")
53
+ tuesday_afternoon = 1.business_day.after(friday_afternoon)
54
+ expected = Time.parse("July 6th, 2010, 4:50 pm")
55
+ assert_equal expected, tuesday_afternoon
56
+ end
56
57
 
57
- should "take into account a holiday on a weekend" do
58
- BusinessTime::Config.reset
59
- july_4 = Date.parse("July 4th, 2010")
60
- BusinessTime::Config.holidays << july_4
61
- friday_afternoon = Time.parse("July 2nd, 2010, 4:50 pm")
62
- monday_afternoon = 1.business_day.after(friday_afternoon)
63
- expected = Time.parse("July 5th, 2010, 4:50 pm")
64
- assert expected == monday_afternoon
58
+ should "take into account a holiday on a weekend" do
59
+ BusinessTime::Config.reset
60
+ july_4 = Date.parse("July 4th, 2010")
61
+ BusinessTime::Config.holidays << july_4
62
+ friday_afternoon = Time.parse("July 2nd, 2010, 4:50 pm")
63
+ monday_afternoon = 1.business_day.after(friday_afternoon)
64
+ expected = Time.parse("July 5th, 2010, 4:50 pm")
65
+ assert_equal expected, monday_afternoon
66
+ end
65
67
  end
66
68
 
67
- end
69
+ end
@@ -0,0 +1,75 @@
1
+ require 'helper'
2
+
3
+ class TestBusinessDays < Test::Unit::TestCase
4
+
5
+ context "with a TimeWithZone object set to the Eastern timezone" do
6
+ setup do
7
+ Time.zone = 'Eastern Time (US & Canada)'
8
+ end
9
+ teardown do
10
+ Time.zone = nil
11
+ end
12
+
13
+ should "move to tomorrow if we add a business day" do
14
+ first = Time.zone.parse("April 13th, 2010, 11:00 am")
15
+ later = 1.business_day.after(first)
16
+ expected = Time.zone.parse("April 14th, 2010, 11:00 am")
17
+ assert_equal expected, later
18
+ end
19
+
20
+ should "move to yesterday is we subtract a business day" do
21
+ first = Time.zone.parse("April 13th, 2010, 11:00 am")
22
+ before = 1.business_day.before(first)
23
+ expected = Time.zone.parse("April 12th, 2010, 11:00 am")
24
+ assert_equal expected, before
25
+ end
26
+
27
+ should "take into account the weekend when adding a day" do
28
+ first = Time.zone.parse("April 9th, 2010, 12:33 pm")
29
+ after = 1.business_day.after(first)
30
+ expected = Time.zone.parse("April 12th, 2010, 12:33 pm")
31
+ assert_equal expected, after
32
+ end
33
+
34
+ should "take into account the weekend when subtracting a day" do
35
+ first = Time.zone.parse("April 12th, 2010, 12:33 pm")
36
+ before = 1.business_day.before(first)
37
+ expected = Time.zone.parse("April 9th, 2010, 12:33 pm")
38
+ assert_equal expected, before
39
+ end
40
+
41
+ should "move forward one week when adding 5 business days" do
42
+ first = Time.zone.parse("April 9th, 2010, 12:33 pm")
43
+ after = 5.business_days.after(first)
44
+ expected = Time.zone.parse("April 16th, 2010, 12:33 pm")
45
+ assert_equal expected, after
46
+ end
47
+
48
+ should "move backward one week when subtracting 5 business days" do
49
+ first = Time.zone.parse("April 16th, 2010, 12:33 pm")
50
+ before = 5.business_days.before(first)
51
+ expected = Time.zone.parse("April 9th, 2010, 12:33 pm")
52
+ assert_equal expected, before
53
+ end
54
+
55
+ should "take into account a holiday when adding a day" do
56
+ three_day_weekend = Date.parse("July 5th, 2010")
57
+ BusinessTime::Config.holidays << three_day_weekend
58
+ friday_afternoon = Time.zone.parse("July 2nd, 2010, 4:50 pm")
59
+ tuesday_afternoon = 1.business_day.after(friday_afternoon)
60
+ expected = Time.zone.parse("July 6th, 2010, 4:50 pm")
61
+ assert_equal expected, tuesday_afternoon
62
+ end
63
+
64
+ should "take into account a holiday on a weekend" do
65
+ BusinessTime::Config.reset
66
+ july_4 = Date.parse("July 4th, 2010")
67
+ BusinessTime::Config.holidays << july_4
68
+ friday_afternoon = Time.zone.parse("July 2nd, 2010, 4:50 pm")
69
+ monday_afternoon = 1.business_day.after(friday_afternoon)
70
+ expected = Time.zone.parse("July 5th, 2010, 4:50 pm")
71
+ assert_equal expected, monday_afternoon
72
+ end
73
+ end
74
+
75
+ end
@@ -0,0 +1,75 @@
1
+ require 'helper'
2
+
3
+ class TestBusinessDays < Test::Unit::TestCase
4
+
5
+ context "with a TimeWithZone object set to UTC" do
6
+ setup do
7
+ Time.zone = 'UTC'
8
+ end
9
+ teardown do
10
+ Time.zone = nil
11
+ end
12
+
13
+ should "move to tomorrow if we add a business day" do
14
+ first = Time.zone.parse("April 13th, 2010, 11:00 am")
15
+ later = 1.business_day.after(first)
16
+ expected = Time.zone.parse("April 14th, 2010, 11:00 am")
17
+ assert_equal expected, later
18
+ end
19
+
20
+ should "move to yesterday is we subtract a business day" do
21
+ first = Time.zone.parse("April 13th, 2010, 11:00 am")
22
+ before = 1.business_day.before(first)
23
+ expected = Time.zone.parse("April 12th, 2010, 11:00 am")
24
+ assert_equal expected, before
25
+ end
26
+
27
+ should "take into account the weekend when adding a day" do
28
+ first = Time.zone.parse("April 9th, 2010, 12:33 pm")
29
+ after = 1.business_day.after(first)
30
+ expected = Time.zone.parse("April 12th, 2010, 12:33 pm")
31
+ assert_equal expected, after
32
+ end
33
+
34
+ should "take into account the weekend when subtracting a day" do
35
+ first = Time.zone.parse("April 12th, 2010, 12:33 pm")
36
+ before = 1.business_day.before(first)
37
+ expected = Time.zone.parse("April 9th, 2010, 12:33 pm")
38
+ assert_equal expected, before
39
+ end
40
+
41
+ should "move forward one week when adding 5 business days" do
42
+ first = Time.zone.parse("April 9th, 2010, 12:33 pm")
43
+ after = 5.business_days.after(first)
44
+ expected = Time.zone.parse("April 16th, 2010, 12:33 pm")
45
+ assert_equal expected, after
46
+ end
47
+
48
+ should "move backward one week when subtracting 5 business days" do
49
+ first = Time.zone.parse("April 16th, 2010, 12:33 pm")
50
+ before = 5.business_days.before(first)
51
+ expected = Time.zone.parse("April 9th, 2010, 12:33 pm")
52
+ assert_equal expected, before
53
+ end
54
+
55
+ should "take into account a holiday when adding a day" do
56
+ three_day_weekend = Date.parse("July 5th, 2010")
57
+ BusinessTime::Config.holidays << three_day_weekend
58
+ friday_afternoon = Time.zone.parse("July 2nd, 2010, 4:50 pm")
59
+ tuesday_afternoon = 1.business_day.after(friday_afternoon)
60
+ expected = Time.zone.parse("July 6th, 2010, 4:50 pm")
61
+ assert_equal expected, tuesday_afternoon
62
+ end
63
+
64
+ should "take into account a holiday on a weekend" do
65
+ BusinessTime::Config.reset
66
+ july_4 = Date.parse("July 4th, 2010")
67
+ BusinessTime::Config.holidays << july_4
68
+ friday_afternoon = Time.zone.parse("July 2nd, 2010, 4:50 pm")
69
+ monday_afternoon = 1.business_day.after(friday_afternoon)
70
+ expected = Time.zone.parse("July 5th, 2010, 4:50 pm")
71
+ assert_equal expected, monday_afternoon
72
+ end
73
+ end
74
+
75
+ end
@@ -1,64 +1,69 @@
1
1
  require 'helper'
2
2
 
3
3
  class TestBusinessHours < Test::Unit::TestCase
4
- should "move to tomorrow if we add 8 business hours" do
5
- first = Time.parse("Aug 4 2010, 9:35 am")
6
- later = 8.business_hours.after(first)
7
- expected = Time.parse("Aug 5 2010, 9:35 am")
8
- assert expected == later
9
- end
10
-
11
- should "move to yesterday if we subtract 8 business hours" do
12
- first = Time.parse("Aug 4 2010, 9:35 am")
13
- later = 8.business_hours.before(first)
14
- expected = Time.parse("Aug 3 2010, 9:35 am")
15
- assert expected == later
16
- end
17
-
18
- should "take into account a weekend when adding an hour" do
19
- friday_afternoon = Time.parse("April 9th, 4:50 pm")
20
- monday_morning = 1.business_hour.after(friday_afternoon)
21
- expected = Time.parse("April 12th 2010, 9:50 am")
22
- assert expected == monday_morning
23
- end
24
-
25
- should "take into account a weekend when subtracting an hour" do
26
- monday_morning = Time.parse("April 12th 2010, 9:50 am")
27
- friday_afternoon = 1.business_hour.before(monday_morning)
28
- expected = Time.parse("April 9th 2010, 4:50 pm")
29
- assert expected == friday_afternoon
30
- end
31
-
32
- should "take into account a holiday" do
33
- BusinessTime::Config.holidays << Date.parse("July 5th, 2010")
34
- friday_afternoon = Time.parse("July 2nd 2010, 4:50pm")
35
- tuesday_morning = 1.business_hour.after(friday_afternoon)
36
- expected = Time.parse("July 6th 2010, 9:50 am")
37
- assert expected == tuesday_morning
38
- end
39
-
40
- should "add hours in the middle of the workday" do
41
- monday_morning = Time.parse("April 12th 2010, 9:50 am")
42
- later = 3.business_hours.after(monday_morning)
43
- expected = Time.parse("April 12th 2010, 12:50 pm")
44
- assert expected == later
45
- end
46
-
47
- should "roll forward to 9 am if asked in the early morning" do
48
- crack_of_dawn_monday = Time.parse("Mon Apr 26, 04:30:00, 2010")
49
- monday_morning = Time.parse("Mon Apr 26, 09:00:00, 2010")
50
- assert_equal monday_morning, crack_of_dawn_monday.roll_forward
51
- end
52
-
53
- should "roll forward to the next morning if aftern business hours" do
54
- monday_evening = Time.parse("Mon Apr 26, 18:00:00, 2010")
55
- tuesday_morning = Time.parse("Tue Apr 27, 09:00:00, 2010")
56
- assert_equal tuesday_morning, monday_evening.roll_forward
57
- end
58
-
59
- should "consider any time on a weekend as equivalent to monday morning" do
60
- sunday = Time.parse("Sun Apr 25 12:06:56, 2010")
61
- monday = Time.parse("Mon Apr 26, 09:00:00, 2010")
62
- assert_equal 1.business_hour.before(monday), 1.business_hour.before(sunday)
4
+
5
+ context "with a standard Time object" do
6
+
7
+ should "move to tomorrow if we add 8 business hours" do
8
+ first = Time.parse("Aug 4 2010, 9:35 am")
9
+ later = 8.business_hours.after(first)
10
+ expected = Time.parse("Aug 5 2010, 9:35 am")
11
+ assert_equal expected, later
12
+ end
13
+
14
+ should "move to yesterday if we subtract 8 business hours" do
15
+ first = Time.parse("Aug 4 2010, 9:35 am")
16
+ later = 8.business_hours.before(first)
17
+ expected = Time.parse("Aug 3 2010, 9:35 am")
18
+ assert_equal expected, later
19
+ end
20
+
21
+ should "take into account a weekend when adding an hour" do
22
+ friday_afternoon = Time.parse("April 9th, 4:50 pm")
23
+ monday_morning = 1.business_hour.after(friday_afternoon)
24
+ expected = Time.parse("April 12th 2010, 9:50 am")
25
+ assert_equal expected, monday_morning
26
+ end
27
+
28
+ should "take into account a weekend when subtracting an hour" do
29
+ monday_morning = Time.parse("April 12th 2010, 9:50 am")
30
+ friday_afternoon = 1.business_hour.before(monday_morning)
31
+ expected = Time.parse("April 9th 2010, 4:50 pm")
32
+ assert_equal expected, friday_afternoon
33
+ end
34
+
35
+ should "take into account a holiday" do
36
+ BusinessTime::Config.holidays << Date.parse("July 5th, 2010")
37
+ friday_afternoon = Time.parse("July 2nd 2010, 4:50pm")
38
+ tuesday_morning = 1.business_hour.after(friday_afternoon)
39
+ expected = Time.parse("July 6th 2010, 9:50 am")
40
+ assert_equal expected, tuesday_morning
41
+ end
42
+
43
+ should "add hours in the middle of the workday" do
44
+ monday_morning = Time.parse("April 12th 2010, 9:50 am")
45
+ later = 3.business_hours.after(monday_morning)
46
+ expected = Time.parse("April 12th 2010, 12:50 pm")
47
+ assert_equal expected, later
48
+ end
49
+
50
+ should "roll forward to 9 am if asked in the early morning" do
51
+ crack_of_dawn_monday = Time.parse("Mon Apr 26, 04:30:00, 2010")
52
+ monday_morning = Time.parse("Mon Apr 26, 09:00:00, 2010")
53
+ assert_equal monday_morning, Time.roll_forward(crack_of_dawn_monday)
54
+ end
55
+
56
+ should "roll forward to the next morning if aftern business hours" do
57
+ monday_evening = Time.parse("Mon Apr 26, 18:00:00, 2010")
58
+ tuesday_morning = Time.parse("Tue Apr 27, 09:00:00, 2010")
59
+ assert_equal tuesday_morning, Time.roll_forward(monday_evening)
60
+ end
61
+
62
+ should "consider any time on a weekend as equivalent to monday morning" do
63
+ sunday = Time.parse("Sun Apr 25 12:06:56, 2010")
64
+ monday = Time.parse("Mon Apr 26, 09:00:00, 2010")
65
+ assert_equal 1.business_hour.before(monday), 1.business_hour.before(sunday)
66
+ end
63
67
  end
68
+
64
69
  end
@@ -0,0 +1,75 @@
1
+ require 'helper'
2
+
3
+ class TestBusinessHours < Test::Unit::TestCase
4
+
5
+ context "with a TimeWithZone object in US Eastern" do
6
+ setup do
7
+ Time.zone = 'Eastern Time (US & Canada)'
8
+ end
9
+ teardown do
10
+ Time.zone = nil
11
+ end
12
+
13
+ should "move to tomorrow if we add 8 business hours" do
14
+ first = Time.zone.parse("Aug 4 2010, 9:35 am")
15
+ later = 8.business_hours.after(first)
16
+ expected = Time.zone.parse("Aug 5 2010, 9:35 am")
17
+ assert_equal expected, later
18
+ end
19
+
20
+ should "move to yesterday if we subtract 8 business hours" do
21
+ first = Time.zone.parse("Aug 4 2010, 9:35 am")
22
+ later = 8.business_hours.before(first)
23
+ expected = Time.zone.parse("Aug 3 2010, 9:35 am")
24
+ assert_equal expected, later
25
+ end
26
+
27
+ should "take into account a weekend when adding an hour" do
28
+ friday_afternoon = Time.zone.parse("April 9th, 4:50 pm")
29
+ monday_morning = 1.business_hour.after(friday_afternoon)
30
+ expected = Time.zone.parse("April 12th 2010, 9:50 am")
31
+ assert_equal expected, monday_morning
32
+ end
33
+
34
+ should "take into account a weekend when subtracting an hour" do
35
+ monday_morning = Time.zone.parse("April 12th 2010, 9:50 am")
36
+ friday_afternoon = 1.business_hour.before(monday_morning)
37
+ expected = Time.zone.parse("April 9th 2010, 4:50 pm")
38
+ assert_equal expected, friday_afternoon
39
+ end
40
+
41
+ should "take into account a holiday" do
42
+ BusinessTime::Config.holidays << Date.parse("July 5th, 2010")
43
+ friday_afternoon = Time.zone.parse("July 2nd 2010, 4:50pm")
44
+ tuesday_morning = 1.business_hour.after(friday_afternoon)
45
+ expected = Time.zone.parse("July 6th 2010, 9:50 am")
46
+ assert_equal expected, tuesday_morning
47
+ end
48
+
49
+ should "add hours in the middle of the workday" do
50
+ monday_morning = Time.zone.parse("April 12th 2010, 9:50 am")
51
+ later = 3.business_hours.after(monday_morning)
52
+ expected = Time.zone.parse("April 12th 2010, 12:50 pm")
53
+ assert_equal expected, later
54
+ end
55
+
56
+ should "roll forward to 9 am if asked in the early morning" do
57
+ crack_of_dawn_monday = Time.zone.parse("Mon Apr 26, 04:30:00, 2010")
58
+ monday_morning = Time.zone.parse("Mon Apr 26, 09:00:00, 2010")
59
+ assert_equal monday_morning, Time.roll_forward(crack_of_dawn_monday)
60
+ end
61
+
62
+ should "roll forward to the next morning if aftern business hours" do
63
+ monday_evening = Time.zone.parse("Mon Apr 26, 18:00:00, 2010")
64
+ tuesday_morning = Time.zone.parse("Tue Apr 27, 09:00:00, 2010")
65
+ assert_equal tuesday_morning, Time.roll_forward(monday_evening)
66
+ end
67
+
68
+ should "consider any time on a weekend as equivalent to monday morning" do
69
+ sunday = Time.zone.parse("Sun Apr 25 12:06:56, 2010")
70
+ monday = Time.zone.parse("Mon Apr 26, 09:00:00, 2010")
71
+ assert_equal 1.business_hour.before(monday), 1.business_hour.before(sunday)
72
+ end
73
+
74
+ end
75
+ end
@@ -0,0 +1,75 @@
1
+ require 'helper'
2
+
3
+ class TestBusinessHours < Test::Unit::TestCase
4
+
5
+ context "with a TimeWithZone object in UTC" do
6
+ setup do
7
+ Time.zone = 'UTC'
8
+ end
9
+ teardown do
10
+ Time.zone = nil
11
+ end
12
+
13
+ should "move to tomorrow if we add 8 business hours" do
14
+ first = Time.zone.parse("Aug 4 2010, 9:35 am")
15
+ later = 8.business_hours.after(first)
16
+ expected = Time.zone.parse("Aug 5 2010, 9:35 am")
17
+ assert_equal expected, later
18
+ end
19
+
20
+ should "move to yesterday if we subtract 8 business hours" do
21
+ first = Time.zone.parse("Aug 4 2010, 9:35 am")
22
+ later = 8.business_hours.before(first)
23
+ expected = Time.zone.parse("Aug 3 2010, 9:35 am")
24
+ assert_equal expected, later
25
+ end
26
+
27
+ should "take into account a weekend when adding an hour" do
28
+ friday_afternoon = Time.zone.parse("April 9th, 4:50 pm")
29
+ monday_morning = 1.business_hour.after(friday_afternoon)
30
+ expected = Time.zone.parse("April 12th 2010, 9:50 am")
31
+ assert_equal expected, monday_morning
32
+ end
33
+
34
+ should "take into account a weekend when subtracting an hour" do
35
+ monday_morning = Time.zone.parse("April 12th 2010, 9:50 am")
36
+ friday_afternoon = 1.business_hour.before(monday_morning)
37
+ expected = Time.zone.parse("April 9th 2010, 4:50 pm")
38
+ assert_equal expected, friday_afternoon, "Expected #{expected} but received #{friday_afternoon}"
39
+ end
40
+
41
+ should "take into account a holiday" do
42
+ BusinessTime::Config.holidays << Date.parse("July 5th, 2010")
43
+ friday_afternoon = Time.zone.parse("July 2nd 2010, 4:50pm")
44
+ tuesday_morning = 1.business_hour.after(friday_afternoon)
45
+ expected = Time.zone.parse("July 6th 2010, 9:50 am")
46
+ assert_equal expected, tuesday_morning
47
+ end
48
+
49
+ should "add hours in the middle of the workday" do
50
+ monday_morning = Time.zone.parse("April 12th 2010, 9:50 am")
51
+ later = 3.business_hours.after(monday_morning)
52
+ expected = Time.zone.parse("April 12th 2010, 12:50 pm")
53
+ assert_equal expected, later
54
+ end
55
+
56
+ should "roll forward to 9 am if asked in the early morning" do
57
+ crack_of_dawn_monday = Time.zone.parse("Mon Apr 26, 04:30:00, 2010")
58
+ monday_morning = Time.zone.parse("Mon Apr 26, 09:00:00, 2010")
59
+ assert_equal monday_morning, Time.roll_forward(crack_of_dawn_monday)
60
+ end
61
+
62
+ should "roll forward to the next morning if aftern business hours" do
63
+ monday_evening = Time.zone.parse("Mon Apr 26, 18:00:00, 2010")
64
+ tuesday_morning = Time.zone.parse("Tue Apr 27, 09:00:00, 2010")
65
+ assert_equal tuesday_morning, Time.roll_forward(monday_evening)
66
+ end
67
+
68
+ should "consider any time on a weekend as equivalent to monday morning" do
69
+ sunday = Time.zone.parse("Sun Apr 25 12:06:56, 2010")
70
+ monday = Time.zone.parse("Mon Apr 26, 09:00:00, 2010")
71
+ assert_equal 1.business_hour.before(monday), 1.business_hour.before(sunday)
72
+ end
73
+ end
74
+
75
+ end
data/test/test_config.rb CHANGED
@@ -3,15 +3,15 @@ require 'helper'
3
3
  class TestConfig < Test::Unit::TestCase
4
4
 
5
5
  should "keep track of the start of the day" do
6
- assert BusinessTime::Config.beginning_of_workday == "9:00 am"
6
+ assert_equal BusinessTime::Config.beginning_of_workday, "9:00 am"
7
7
  BusinessTime::Config.beginning_of_workday = "8:30 am"
8
- assert BusinessTime::Config.beginning_of_workday == "8:30 am"
8
+ assert_equal BusinessTime::Config.beginning_of_workday, "8:30 am"
9
9
  end
10
10
 
11
11
  should "keep track of the end of the day" do
12
- assert BusinessTime::Config.end_of_workday == "5:00 pm"
12
+ assert_equal BusinessTime::Config.end_of_workday, "5:00 pm"
13
13
  BusinessTime::Config.end_of_workday = "5:30 pm"
14
- assert BusinessTime::Config.end_of_workday == "5:30 pm"
14
+ assert_equal BusinessTime::Config.end_of_workday, "5:30 pm"
15
15
  end
16
16
 
17
17
  should "keep track of holidays" do
@@ -22,4 +22,4 @@ class TestConfig < Test::Unit::TestCase
22
22
  assert BusinessTime::Config.holidays.include?(daves_birthday)
23
23
  end
24
24
 
25
- end
25
+ end
@@ -3,17 +3,17 @@ require 'helper'
3
3
  class TestTimeExtensions < Test::Unit::TestCase
4
4
 
5
5
  should "know what a weekend day is" do
6
- assert(Time.parse("April 9, 2010 10:30am").weekday?)
7
- assert(!Time.parse("April 10, 2010 10:30am").weekday?)
8
- assert(!Time.parse("April 11, 2010 10:30am").weekday?)
9
- assert(Time.parse("April 12, 2010 10:30am").weekday?)
6
+ assert( Time.weekday?(Time.parse("April 9, 2010 10:30am")))
7
+ assert(!Time.weekday?(Time.parse("April 10, 2010 10:30am")))
8
+ assert(!Time.weekday?(Time.parse("April 11, 2010 10:30am")))
9
+ assert( Time.weekday?(Time.parse("April 12, 2010 10:30am")))
10
10
  end
11
11
 
12
12
  should "know a weekend day is not a workday" do
13
- assert(Time.parse("April 9, 2010 10:45 am").workday?)
14
- assert(!Time.parse("April 10, 2010 10:45 am").workday?)
15
- assert(!Time.parse("April 11, 2010 10:45 am").workday?)
16
- assert(Time.parse("April 12, 2010 10:45 am").workday?)
13
+ assert( Time.workday?(Time.parse("April 9, 2010 10:45 am")))
14
+ assert(!Time.workday?(Time.parse("April 10, 2010 10:45 am")))
15
+ assert(!Time.workday?(Time.parse("April 11, 2010 10:45 am")))
16
+ assert( Time.workday?(Time.parse("April 12, 2010 10:45 am")))
17
17
  end
18
18
 
19
19
  should "know a holiday is not a workday" do
@@ -22,21 +22,21 @@ class TestTimeExtensions < Test::Unit::TestCase
22
22
  BusinessTime::Config.holidays << Date.parse("July 4, 2010")
23
23
  BusinessTime::Config.holidays << Date.parse("July 5, 2010")
24
24
 
25
- assert(!Time.parse("July 4th, 2010 1:15 pm").workday?)
26
- assert(!Time.parse("July 5th, 2010 2:37 pm").workday?)
25
+ assert(!Time.workday?(Time.parse("July 4th, 2010 1:15 pm")))
26
+ assert(!Time.workday?(Time.parse("July 5th, 2010 2:37 pm")))
27
27
  end
28
28
 
29
29
 
30
30
  should "know the beginning of the day for an instance" do
31
31
  first = Time.parse("August 17th, 2010, 11:50 am")
32
32
  expecting = Time.parse("August 17th, 2010, 9:00 am")
33
- assert expecting == first.beginning_of_workday
33
+ assert_equal expecting, Time.beginning_of_workday(first)
34
34
  end
35
35
 
36
36
  should "know the end of the day for an instance" do
37
37
  first = Time.parse("August 17th, 2010, 11:50 am")
38
38
  expecting = Time.parse("August 17th, 2010, 5:00 pm")
39
- assert expecting == first.end_of_workday
39
+ assert_equal expecting, Time.end_of_workday(first)
40
40
  end
41
41
 
42
- end
42
+ end
@@ -0,0 +1,92 @@
1
+ require 'helper'
2
+
3
+ class TestTimeWithZoneExtensions < Test::Unit::TestCase
4
+
5
+ context "With Eastern Standard Time" do
6
+ setup do
7
+ Time.zone = 'Eastern Time (US & Canada)'
8
+ end
9
+
10
+ should "know what a weekend day is" do
11
+ assert( Time.weekday?(Time.zone.parse("April 9, 2010 10:30am")))
12
+ assert(!Time.weekday?(Time.zone.parse("April 10, 2010 10:30am")))
13
+ assert(!Time.weekday?(Time.zone.parse("April 11, 2010 10:30am")))
14
+ assert( Time.weekday?(Time.zone.parse("April 12, 2010 10:30am")))
15
+ end
16
+
17
+ should "know a weekend day is not a workday" do
18
+ assert( Time.workday?(Time.zone.parse("April 9, 2010 10:45 am")))
19
+ assert(!Time.workday?(Time.zone.parse("April 10, 2010 10:45 am")))
20
+ assert(!Time.workday?(Time.zone.parse("April 11, 2010 10:45 am")))
21
+ assert( Time.workday?(Time.zone.parse("April 12, 2010 10:45 am")))
22
+ end
23
+
24
+ should "know a holiday is not a workday" do
25
+ BusinessTime::Config.reset
26
+
27
+ BusinessTime::Config.holidays << Date.parse("July 4, 2010")
28
+ BusinessTime::Config.holidays << Date.parse("July 5, 2010")
29
+
30
+ assert(!Time.workday?(Time.zone.parse("July 4th, 2010 1:15 pm")))
31
+ assert(!Time.workday?(Time.zone.parse("July 5th, 2010 2:37 pm")))
32
+ end
33
+
34
+
35
+ should "know the beginning of the day for an instance" do
36
+ first = Time.zone.parse("August 17th, 2010, 11:50 am")
37
+ expecting = Time.zone.parse("August 17th, 2010, 9:00 am")
38
+ assert_equal expecting, Time.beginning_of_workday(first)
39
+ end
40
+
41
+ should "know the end of the day for an instance" do
42
+ first = Time.zone.parse("August 17th, 2010, 11:50 am")
43
+ expecting = Time.zone.parse("August 17th, 2010, 5:00 pm")
44
+ assert_equal expecting, Time.end_of_workday(first)
45
+ end
46
+ end
47
+
48
+
49
+ context "With UTC Timezone" do
50
+ setup do
51
+ Time.zone = 'UTC'
52
+ end
53
+
54
+ should "know what a weekend day is" do
55
+ assert( Time.weekday?(Time.zone.parse("April 9, 2010 10:30am")))
56
+ assert(!Time.weekday?(Time.zone.parse("April 10, 2010 10:30am")))
57
+ assert(!Time.weekday?(Time.zone.parse("April 11, 2010 10:30am")))
58
+ assert( Time.weekday?(Time.zone.parse("April 12, 2010 10:30am")))
59
+ end
60
+
61
+ should "know a weekend day is not a workday" do
62
+ assert( Time.workday?(Time.zone.parse("April 9, 2010 10:45 am")))
63
+ assert(!Time.workday?(Time.zone.parse("April 10, 2010 10:45 am")))
64
+ assert(!Time.workday?(Time.zone.parse("April 11, 2010 10:45 am")))
65
+ assert( Time.workday?(Time.zone.parse("April 12, 2010 10:45 am")))
66
+ end
67
+
68
+ should "know a holiday is not a workday" do
69
+ BusinessTime::Config.reset
70
+
71
+ BusinessTime::Config.holidays << Date.parse("July 4, 2010")
72
+ BusinessTime::Config.holidays << Date.parse("July 5, 2010")
73
+
74
+ assert(!Time.workday?(Time.zone.parse("July 4th, 2010 1:15 pm")))
75
+ assert(!Time.workday?(Time.zone.parse("July 5th, 2010 2:37 pm")))
76
+ end
77
+
78
+
79
+ should "know the beginning of the day for an instance" do
80
+ first = Time.zone.parse("August 17th, 2010, 11:50 am")
81
+ expecting = Time.zone.parse("August 17th, 2010, 9:00 am")
82
+ assert_equal expecting, Time.beginning_of_workday(first)
83
+ end
84
+
85
+ should "know the end of the day for an instance" do
86
+ first = Time.zone.parse("August 17th, 2010, 11:50 am")
87
+ expecting = Time.zone.parse("August 17th, 2010, 5:00 pm")
88
+ assert_equal expecting, Time.end_of_workday(first)
89
+ end
90
+ end
91
+
92
+ end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 2
8
- - 2
9
- version: 0.2.2
7
+ - 3
8
+ - 0
9
+ version: 0.3.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - bokmann
@@ -14,11 +14,11 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-25 00:00:00 -04:00
17
+ date: 2010-05-30 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- name: thoughtbot-shoulda
21
+ name: shoulda
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
24
  requirements:
@@ -72,11 +72,16 @@ files:
72
72
  - rails_generators/business_time_config/templates/business_time.yml
73
73
  - test/helper.rb
74
74
  - test/test_business_days.rb
75
+ - test/test_business_days_eastern.rb
76
+ - test/test_business_days_utc.rb
75
77
  - test/test_business_hours.rb
78
+ - test/test_business_hours_eastern.rb
79
+ - test/test_business_hours_utc.rb
76
80
  - test/test_config.rb
77
81
  - test/test_date_extensions.rb
78
82
  - test/test_fixnum_extensions.rb
79
83
  - test/test_time_extensions.rb
84
+ - test/test_time_with_zone_extensions.rb
80
85
  has_rdoc: true
81
86
  homepage: http://github.com/bokmann/business_time
82
87
  licenses: []
@@ -110,8 +115,13 @@ summary: Support for doing time math in business hours and days
110
115
  test_files:
111
116
  - test/helper.rb
112
117
  - test/test_business_days.rb
118
+ - test/test_business_days_eastern.rb
119
+ - test/test_business_days_utc.rb
113
120
  - test/test_business_hours.rb
121
+ - test/test_business_hours_eastern.rb
122
+ - test/test_business_hours_utc.rb
114
123
  - test/test_config.rb
115
124
  - test/test_date_extensions.rb
116
125
  - test/test_fixnum_extensions.rb
117
126
  - test/test_time_extensions.rb
127
+ - test/test_time_with_zone_extensions.rb