gb_work_day 0.0.6 → 0.1.0

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