gb_work_day 0.0.6 → 0.1.0

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
  SHA256:
3
- metadata.gz: 06c47230ed0b62eaf183e73881b2e8f516435470a500b1ce703f96cbcf71f414
4
- data.tar.gz: 055b42d77c11caa155c821bc40662a39d2dca5b13e3e005750e69c0964b395a4
3
+ metadata.gz: 8697f8e4fc6efcec8b7cc8c32438fc50aa31b856fe44324db026aa1495183855
4
+ data.tar.gz: cf1e314b7734ac52c2e220f9f64f46ec63dddfb51d40a0b5452668f7595b6c52
5
5
  SHA512:
6
- metadata.gz: 9bd9bb5b0d0d22b4960a109772619edf1600c515d7ec22282664a1ae5292b675a4616d31d1da57c01d0407926b0fc5295217b833c0dae3cb2bf1974a5a00446e
7
- data.tar.gz: c08aed54bbd3c851a9ac0793a1faed0f242add8f61263e06c94e5817200cf1b1b8eb696da4983aa6cbb24e1aa0d163c5a88939631bb10569e478ccf2edcb88b5
6
+ metadata.gz: c8f789b355a2b07c5209adace10deab9166ce766bced2f27e7dd7462deb75db0b5cc570da46f3b0b3c84dc61104f78441ca35e5588e273935182d8115dac4f55
7
+ data.tar.gz: f151498882f8a5e4cd1e148d8ad50a2ac27e97ecab483e0ac070f067e744a242a43e5e94276aaf3c4bdb6bc93f747fb6d685910bb4b231ce27c3cf071d8ee3d5
@@ -25,48 +25,40 @@ class Date
25
25
 
26
26
  # Check if it is a work day.
27
27
  # @return [boolean]
28
- def work?
29
- default_week.work_day? self
28
+ def work?(week = default_week)
29
+ week.work_day? self
30
30
  end
31
31
 
32
32
  # Check if it is a work day.
33
33
  # @return [boolean]
34
- def free?
35
- default_week.free_day? self
34
+ def free?(week = default_week)
35
+ week.free_day? self
36
36
  end
37
37
 
38
38
  # Return next working day
39
39
  # @return [Time]
40
- def next_work_day
41
- if default_week.free_day? self
42
- next_day = self
43
- while default_week.free_day? next_day
44
- next_day += 1
45
- end
46
- next_day
40
+ def next_work_day(week = default_week)
41
+ if week.free_day? self
42
+ self.beginning_of_week + 7.days
47
43
  else
48
- self + GBWorkDay::Duration.new(1, default_week)
44
+ self + GBWorkDay::Duration.new(1, week)
49
45
  end
50
46
  end
51
47
 
52
48
  # Return previous working day
53
49
  # @return [Time]
54
- def previous_work_day
55
- if default_week.free_day? self
56
- previous_day = self
57
- while default_week.free_day? previous_day
58
- previous_day -= 1
59
- end
60
- previous_day
50
+ def previous_work_day(week = default_week)
51
+ if week.free_day? self
52
+ next_work_day(week) - (week.free_days_per_week + 1).days
61
53
  else
62
- self - GBWorkDay::Duration.new(1, default_week)
54
+ self - GBWorkDay::Duration.new(1, week)
63
55
  end
64
56
  end
65
57
 
66
58
  # Get date object for calculating working days
67
59
  #
68
60
  # @param week [GBWorkDay::WorkWeek] if not set, it will use week set globally. For more check {GBWorkingDay::WorkWeek#current}
69
- def work_date(week=nil)
61
+ def work_date(week = nil)
70
62
  GBWorkDay::Date.from_date self, week
71
63
  end
72
64
  alias_method :to_work, :work_date
@@ -26,34 +26,40 @@ class Time
26
26
 
27
27
  # Check if it is a work day.
28
28
  # @return [boolean]
29
- def work?
30
- default_week.work_day? self
29
+ def work?(week = default_week)
30
+ week.work_day? self
31
31
  end
32
32
 
33
33
  # Check if it is a work day.
34
34
  # @return [boolean]
35
- def free?
36
- default_week.free_day? self
35
+ def free?(week = default_week)
36
+ week.free_day? self
37
37
  end
38
38
 
39
39
  # Return next working day
40
40
  # @return [Time]
41
- def next_work_day
42
- if default_week.free_day? self
43
- next_day = self
44
- while default_week.free_day? next_day
45
- next_day += GBWorkDay::Duration::SEC_IN_DAY
46
- end
47
- next_day
41
+ def next_work_day(week = default_week)
42
+ if week.free_day? self
43
+ self.beginning_of_week + 7.days
48
44
  else
49
- self + GBWorkDay::Duration.new(1, default_week)
45
+ self + GBWorkDay::Duration.new(1, week)
46
+ end
47
+ end
48
+
49
+ # Return previous working day
50
+ # @return [Time]
51
+ def previous_work_day(week = default_week)
52
+ if week.free_day? self
53
+ next_work_day(week) - (week.free_days_per_week + 1).days
54
+ else
55
+ self - GBWorkDay::Duration.new(1, week)
50
56
  end
51
57
  end
52
58
 
53
59
  # Get time object for calculating working days
54
60
  #
55
61
  # @param week [GBWorkDay::WorkWeek] if not set, it will use week set globally. For more check {GBWorkingDay::WorkWeek#current}
56
- def work_time(week=nil)
62
+ def work_time(week = nil)
57
63
  GBWorkDay::Time.from_time self, week
58
64
  end
59
65
  alias_method :to_work, :work_time
@@ -73,6 +73,7 @@ module GBWorkDay
73
73
 
74
74
  # Calculates a new Time or Date that is as far in the future
75
75
  # as this Duration represents.
76
+ # If time is a free day, it is calculated starting from the next work day
76
77
  def since(time = ::Time.current)
77
78
  self.work_days > 0 ? sum(time) : subtract(time)
78
79
  end
@@ -80,6 +81,7 @@ module GBWorkDay
80
81
 
81
82
  # Calculates a new Time or Date that is as far in the past
82
83
  # as this Duration represents.
84
+ # Time has to be a work day, it is calculated starting from the next work day
83
85
  def ago(time = ::Time.current)
84
86
  self.work_days > 0 ? subtract(time) : sum(time)
85
87
  end
@@ -92,6 +94,7 @@ module GBWorkDay
92
94
  private
93
95
 
94
96
  def sum(time)
97
+ time = next_work_day time
95
98
  distance_to_last_monday = (time.wday - 1) % 7
96
99
  weekends_count = (distance_to_last_monday + self.work_days.abs) / @week.work_days_per_week
97
100
  weekends_length = weekends_count * @week.free_days_per_week
@@ -100,6 +103,7 @@ module GBWorkDay
100
103
  end
101
104
 
102
105
  def subtract(time)
106
+ time = next_work_day time
103
107
  distance_to_eof = distance_to_end_of_week(time)
104
108
  weekends_count = (distance_to_eof + self.work_days.abs) / @week.work_days_per_week
105
109
  weekends_length = weekends_count * @week.free_days_per_week
@@ -107,21 +111,31 @@ module GBWorkDay
107
111
  sum_normal_days(sum_normal_days(time, -weekends_length), -self.work_days.abs)
108
112
  end
109
113
 
110
- # @param time [Date|Time]
114
+ # @param time [Date, Time]
111
115
  # @return distance_to_eof [Integer]
112
116
  def distance_to_end_of_week(time)
113
117
  (@week.work_days_per_week - time.wday) % (@week.work_days_per_week)
114
118
  end
115
119
 
116
- # @param time [Date|Time]
117
- # @param days [Integer]
118
- def sum_normal_days(time, days)
119
- if time.is_a? ::Date
120
- time += days * 1
120
+ # Return next working day, or today if today is a working day
121
+ # @param day [Date, Time]
122
+ # @return [Date, Time]
123
+ def next_work_day(day)
124
+ if @week.free_day? day
125
+ day.next_work_day(@week)
121
126
  else
122
- time += (days * SEC_IN_DAY)
127
+ day
123
128
  end
124
- time
129
+ end
130
+
131
+ # @param time [Date, Time]
132
+ # @param days [Integer]
133
+ def sum_normal_days(time, days)
134
+ time + if time.is_a? ::Date
135
+ days * 1
136
+ else
137
+ (days * SEC_IN_DAY)
138
+ end
125
139
  end
126
140
  end
127
141
  end
@@ -1,5 +1,8 @@
1
1
  require 'gb_work_day/work_week'
2
2
  require 'gb_work_day/duration'
3
+ require 'gb_work_day/core_ext/date'
4
+ require 'gb_work_day/core_ext/integer'
5
+
3
6
  module GBWorkDay
4
7
  class Interval
5
8
  attr_reader :start_time, :end_time
@@ -8,31 +11,37 @@ module GBWorkDay
8
11
  # @param end_time [Time, Date]
9
12
  # @param params [Hash]
10
13
  # @option params [Fixnum] :work_days number of work days in a week, default is 7
11
- # @option params [Fixnum] :week_start first working day in a week as number. Default value is 1 corresponding to Monday.
12
- def initialize(start_time, end_time, params=Hash.new)
14
+ def initialize(start_time, end_time, params = Hash.new)
13
15
  @start_time = start_time
14
16
  @end_time = end_time
15
17
  @symbol = 1
16
18
  revert if @start_time > @end_time
17
19
  @working_week = params[:week]
18
20
  unless @working_week
19
- if params[:work_days] || params[:week_start]
21
+ if params[:work_days]
20
22
  work_days = params.fetch(:work_days, 7)
21
- week_start = params.fetch(:week_start, 1)
22
- @working_week = WorkWeek.new work_days, week_start
23
+ @working_week = WorkWeek.new work_days
23
24
  else
24
25
  @working_week = WorkWeek.current
25
26
  end
26
27
  end
28
+ @work_start_time = next_work_day @start_time
29
+ @work_end_time = next_work_day @end_time
27
30
  end
28
31
 
29
32
  # @return [Integer] Number of working days in a given period
30
33
  def work_days
31
- date = @start_time
32
- work_days = 0
33
- while date < end_time
34
- work_days += 1 if @working_week.work_day?(date)
35
- date += 1.day
34
+ if @working_week.work_days_per_week == 7
35
+ work_days = end_time.minus_without_work_duration(start_time).to_i
36
+ else
37
+ monday_before_start = @work_start_time.beginning_of_week
38
+ monday_before_end = @work_end_time.beginning_of_week
39
+
40
+ full_week_days = monday_before_end.minus_without_work_duration(monday_before_start).to_i
41
+ days_without_weekends = full_week_days - (full_week_days / 7) * @working_week.free_days_per_week
42
+ partial_week_days = @work_end_time.wday - @work_start_time.wday
43
+
44
+ work_days = days_without_weekends + partial_week_days
36
45
  end
37
46
  Duration.new(work_days * @symbol, @working_week)
38
47
  end
@@ -49,7 +58,18 @@ module GBWorkDay
49
58
  new_end_time = @start_time
50
59
  @start_time = @end_time
51
60
  @end_time = new_end_time
52
- @symbol= @symbol * -1
61
+ @symbol *= -1
62
+ end
63
+
64
+ # Return next working day, or today if today is a working day
65
+ # @param day [Date, Time]
66
+ # @return [Date, Time]
67
+ def next_work_day(day)
68
+ if @working_week.free_day? day
69
+ day.next_work_day(@working_week)
70
+ else
71
+ day
72
+ end
53
73
  end
54
74
  end
55
75
  end
@@ -1,3 +1,3 @@
1
1
  module GBWorkDay
2
- VERSION = '0.0.6'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -1,15 +1,14 @@
1
1
  module GBWorkDay
2
2
  class WorkWeek
3
- attr_reader :work_days_per_week, :free_days_per_week, :work_days, :free_days, :week_start
3
+ attr_reader :work_days_per_week, :free_days_per_week, :work_days, :free_days
4
4
 
5
5
  # @param work_days [#to_i] Amount of working days in a week. Default value is 7.
6
- # @param week_start [#to_i] Number of a week day, when work starts. Default value is 1 corresponding to Monday
7
- def initialize(work_days=7, week_start=1)
6
+ def initialize(work_days = 7)
8
7
  work_days = work_days.to_i
9
- week_start = week_start.to_i
8
+ week_start = 1
10
9
  raise ArgumentError, 'Work days have to be between 0 and 7!' unless work_days >= 0 && work_days <= 7
11
10
  @work_days_per_week = work_days
12
- @week_start = week_start % 7
11
+ @week_start = week_start
13
12
  @free_days_per_week = 7 - @work_days_per_week
14
13
  @work_days = []
15
14
  @work_days_per_week.times do
@@ -38,11 +37,11 @@ module GBWorkDay
38
37
  end
39
38
 
40
39
  def ==(other) # :nodoc:
41
- work_days_per_week == other.work_days_per_week && week_start == other.week_start
40
+ work_days_per_week == other.work_days_per_week
42
41
  end
43
42
 
44
43
  def eql?(other) # :nodoc:
45
- work_days_per_week.eql?(other.work_days_per_week) && week_start.eql?(other.week_start)
44
+ work_days_per_week.eql?(other.work_days_per_week)
46
45
  end
47
46
 
48
47
  class << self
@@ -34,10 +34,6 @@ describe GBWorkDay::Duration do
34
34
  expect(GBWorkDay::Duration.new(1) == 1).to be_truthy
35
35
  expect(GBWorkDay::Duration.new(1) == 2).to be_falsey
36
36
 
37
- week = GBWorkDay::WorkWeek.new(3, 3)
38
- expect(GBWorkDay::Duration.new(1, week) == GBWorkDay::Duration.new(1)).to be_falsey
39
- expect(GBWorkDay::Duration.new(1, week) == GBWorkDay::Duration.new(2)).to be_falsey
40
-
41
37
  expect(GBWorkDay::Duration.new(1).eql? GBWorkDay::Duration.new(1)).to be_truthy
42
38
  expect(GBWorkDay::Duration.new(1).eql? GBWorkDay::Duration.new(2)).to be_falsey
43
39
  end
@@ -57,7 +53,7 @@ describe GBWorkDay::Duration do
57
53
  end
58
54
 
59
55
  it 'should calculate proper time for future' do
60
- week = GBWorkDay::WorkWeek.new(5, 1)
56
+ week = GBWorkDay::WorkWeek.new(5)
61
57
  monday = Time.now.beginning_of_week
62
58
 
63
59
  expect(GBWorkDay::Duration.new(1, week).since(monday)).to eq monday + 1.day
@@ -69,7 +65,7 @@ describe GBWorkDay::Duration do
69
65
  end
70
66
 
71
67
  it 'should calculate proper date for future' do
72
- week = GBWorkDay::WorkWeek.new(5, 1)
68
+ week = GBWorkDay::WorkWeek.new(5)
73
69
  monday = Date.today.beginning_of_week
74
70
 
75
71
  expect(GBWorkDay::Duration.new(1, week).since(monday)).to eq monday + 1.day
@@ -81,7 +77,7 @@ describe GBWorkDay::Duration do
81
77
  end
82
78
 
83
79
  it 'should calculate proper time for past' do
84
- week = GBWorkDay::WorkWeek.new(5, 1)
80
+ week = GBWorkDay::WorkWeek.new(5)
85
81
  monday = Time.now.beginning_of_week
86
82
 
87
83
  expect(GBWorkDay::Duration.new(1, week).until(monday)).to eq monday - 3.days
@@ -92,7 +88,7 @@ describe GBWorkDay::Duration do
92
88
  end
93
89
 
94
90
  it 'should calculate proper date for past' do
95
- week = GBWorkDay::WorkWeek.new(5, 1)
91
+ week = GBWorkDay::WorkWeek.new(5)
96
92
  monday = Date.today.beginning_of_week
97
93
 
98
94
  expect(GBWorkDay::Duration.new(1, week).until(monday)).to eq monday - 3.days
@@ -4,7 +4,7 @@ require 'active_support/time'
4
4
 
5
5
 
6
6
  describe GBWorkDay::Interval do
7
- it 'properly calculate work days for interval' do
7
+ it 'properly calculates work days for interval for a 5 days week' do
8
8
  week = GBWorkDay::WorkWeek.new(5)
9
9
  monday = Date.today.beginning_of_week
10
10
  expect(GBWorkDay::Interval.new(monday - 1.day, monday, week: week).duration.work_days).to eq 0
@@ -16,4 +16,26 @@ describe GBWorkDay::Interval do
16
16
  expect(GBWorkDay::Interval.new(monday, monday + 12.day, week: week).duration.work_days).to eq 10
17
17
  expect(GBWorkDay::Interval.new(monday, monday + 14.day, week: week).duration.work_days).to eq 10
18
18
  end
19
+
20
+ it 'properly calculates work days for interval for a 6 days week' do
21
+ week = GBWorkDay::WorkWeek.new(6)
22
+ monday = Date.today.beginning_of_week
23
+ expect(GBWorkDay::Interval.new(monday - 1.day, monday, week: week).duration.work_days).to eq 0
24
+ expect(GBWorkDay::Interval.new(monday - 2.day, monday, week: week).duration.work_days).to eq 1
25
+ expect(GBWorkDay::Interval.new(monday, monday + 1.day, week: week).duration.work_days).to eq 1
26
+ expect(GBWorkDay::Interval.new(monday, monday + 6.day, week: week).duration.work_days).to eq 6
27
+ expect(GBWorkDay::Interval.new(monday, monday + 7.day, week: week).duration.work_days).to eq 6
28
+ expect(GBWorkDay::Interval.new(monday, monday + 12.day, week: week).duration.work_days).to eq 11
29
+ end
30
+
31
+ it 'properly calculates work days for interval for a 7 days week' do
32
+ week = GBWorkDay::WorkWeek.new(7)
33
+ monday = Date.today.beginning_of_week
34
+ expect(GBWorkDay::Interval.new(monday - 1.day, monday, week: week).duration.work_days).to eq 1
35
+ expect(GBWorkDay::Interval.new(monday - 2.day, monday, week: week).duration.work_days).to eq 2
36
+ expect(GBWorkDay::Interval.new(monday, monday + 1.day, week: week).duration.work_days).to eq 1
37
+ expect(GBWorkDay::Interval.new(monday, monday + 6.day, week: week).duration.work_days).to eq 6
38
+ expect(GBWorkDay::Interval.new(monday, monday + 7.day, week: week).duration.work_days).to eq 7
39
+ expect(GBWorkDay::Interval.new(monday, monday + 12.day, week: week).duration.work_days).to eq 12
40
+ end
19
41
  end
@@ -6,65 +6,29 @@ describe GBWorkDay::WorkWeek do
6
6
 
7
7
  context 'work days' do
8
8
  it 'should calculates work days for 7 days work and start on monday' do
9
- week = GBWorkDay::WorkWeek.new(7, 1)
9
+ week = GBWorkDay::WorkWeek.new(7)
10
10
  expect(week.work_days).to eq [1,2,3,4,5,6,7]
11
11
  end
12
-
13
- it 'should calculates work days for 7 days work and start on tuesday' do
14
- week = GBWorkDay::WorkWeek.new(7, 2)
15
- expect(week.work_days).to eq [1,2,3,4,5,6,7]
16
- end
17
-
18
12
  it 'should calculates work days for 5 days work week and start on monday' do
19
- week = GBWorkDay::WorkWeek.new(5, 1)
13
+ week = GBWorkDay::WorkWeek.new(5)
20
14
  expect(week.work_days).to eq [1,2,3,4,5]
21
15
  end
22
-
23
- it 'should calculates work days for 5 days work week and start on tuesday' do
24
- week = GBWorkDay::WorkWeek.new(5, 2)
25
- expect(week.work_days).to eq [2,3,4,5,6]
26
- end
27
-
28
- it 'should calculates work days for 5 days work week and start on thursday' do
29
- week = GBWorkDay::WorkWeek.new(5, 4)
30
- expect(week.work_days).to eq [1,4,5,6,7]
31
- end
32
-
33
- it 'should calculates work days for 3 days work week and start on wednesday' do
34
- week = GBWorkDay::WorkWeek.new(3, 3)
35
- expect(week.work_days).to eq [3,4,5]
36
- end
37
16
  end
38
17
 
39
18
  context 'free days' do
40
- it 'should calculates free days for 7 days work and start on any day' do
41
- week = GBWorkDay::WorkWeek.new(7, rand(6)+1)
19
+ it 'should calculates free days for 7 days work' do
20
+ week = GBWorkDay::WorkWeek.new(7)
42
21
  expect(week.free_days).to eq []
43
22
  end
44
23
 
45
24
  it 'should calculates free days for 5 days work week and start on monday' do
46
- week = GBWorkDay::WorkWeek.new(5, 1)
25
+ week = GBWorkDay::WorkWeek.new(5)
47
26
  expect(week.free_days).to eq [6,7]
48
27
  end
49
-
50
- it 'should calculates work days for 5 days work week and start on tuesday' do
51
- week = GBWorkDay::WorkWeek.new(5, 2)
52
- expect(week.free_days).to eq [1,7]
53
- end
54
-
55
- it 'should calculates work days for 5 days work week and start on thursday' do
56
- week = GBWorkDay::WorkWeek.new(5, 4)
57
- expect(week.free_days).to eq [2,3]
58
- end
59
-
60
- it 'should calculates work days for 3 days work week and start on wednesday' do
61
- week = GBWorkDay::WorkWeek.new(3, 3)
62
- expect(week.free_days).to eq [1,2,6,7]
63
- end
64
28
  end
65
29
 
66
30
  it 'should respond to work_day? if day is a Time' do
67
- week = GBWorkDay::WorkWeek.new(5, 1)
31
+ week = GBWorkDay::WorkWeek.new(5)
68
32
  expect(week.work_days).to eq [1,2,3,4,5]
69
33
  monday = Time.now.beginning_of_week
70
34
 
@@ -79,7 +43,7 @@ describe GBWorkDay::WorkWeek do
79
43
  end
80
44
 
81
45
  it 'should respond to work_day? if day is a Date' do
82
- week = GBWorkDay::WorkWeek.new(5, 1)
46
+ week = GBWorkDay::WorkWeek.new(5)
83
47
  expect(week.work_days).to eq [1,2,3,4,5]
84
48
  monday = Date.today.beginning_of_week
85
49
 
@@ -93,7 +57,7 @@ describe GBWorkDay::WorkWeek do
93
57
  end
94
58
 
95
59
  it 'should respond to free_day? if day is a Time' do
96
- week = GBWorkDay::WorkWeek.new(5, 1)
60
+ week = GBWorkDay::WorkWeek.new(5)
97
61
  expect(week.free_days).to eq [6,7]
98
62
  monday = Time.now.beginning_of_week
99
63
 
@@ -107,7 +71,7 @@ describe GBWorkDay::WorkWeek do
107
71
  end
108
72
 
109
73
  it 'should respond to free_day? if day is a Date' do
110
- week = GBWorkDay::WorkWeek.new(5, 1)
74
+ week = GBWorkDay::WorkWeek.new(5)
111
75
  expect(week.free_days).to eq [6,7]
112
76
  monday = Date.today.beginning_of_week
113
77
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gb_work_day
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kacper Kawecki
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-19 00:00:00.000000000 Z
11
+ date: 2019-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler