active_period 7.1.2 → 7.1.4

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: e197dc4558fd215fc7090f5a14ad074e769457abfa7665b4b2393e5ba2a23d52
4
- data.tar.gz: 54c3de6172706d0f08e2885b6401b3f1c964526498193a63c13af4fbfab6eb99
3
+ metadata.gz: 29fd67cfde1ddca02696bf27400b13b0f1887d6bd64bf4e0749d3b2395f87730
4
+ data.tar.gz: fdba3eaf0997e0a4ad05948269b5a09f3ec18980caa2394d3fc41fb98aee7e99
5
5
  SHA512:
6
- metadata.gz: a228d61ffcb56d1f9206127e22775e2a3ec109822ce0b8242e6e778d8edb08531dd9b2834cc7def80cb42ec7cf148b2abc8776059228c5fb7b7d9cb90ec68562
7
- data.tar.gz: 25550cbd55706774bfd34e68690be5d39b2e01b6681f33b3134d3c7169949c9e1d017ac40cadd24d041eef2c85d3ce6c05dbb8fe76761d6a2fabebe501230e24
6
+ metadata.gz: 4107662e9c026dd3d2390534ab22800bf352b51f72747f2b018443d95a7d12982f5e2f6638ea1e78630c9a889551091af2bbf4d41e9504209f50fbd441b6872d
7
+ data.tar.gz: 5f06ee831b6199212561ef01352c7f02b6ba455f96381bda6ec3fe2b03af627a4223f924713e811848ad34098581eef876d863f09a9c65a8c80c6e45851730bc
data/README.md CHANGED
@@ -134,7 +134,7 @@ Period.week('10/02/2000') + 67.day
134
134
  **StandardPeriod** also respond to `.next` and `.prev`
135
135
  ```ruby
136
136
  Period.month('01/01/2000').next.next.next
137
- # Return the month of April 2020
137
+ # Return the month of April 2000
138
138
  ```
139
139
 
140
140
  You can quickly access convenient periods of time with `.(last|this|next)_(day|week|month|quarter|year)` and `.yesterday` `.today` `.tomorrow`
@@ -242,6 +242,27 @@ Period['01/01/2021'...'09/01/2021'] | Period['10/01/2021'..'20/01/2021']
242
242
  => nil
243
243
  ```
244
244
 
245
+ ## Period clamping with `clamp_on`
246
+
247
+ You can use `clamp_on` to clamp a `Period`, a date or a range of dates, within a `Period`.
248
+ If you user `clamp_on` on a range of dates, the return value will also be a range of dates, this is to preserve hours/minutes/second precision
249
+ :warning: The classic `clamp` apply the param to the caller. It's `42.clamp(1..10) -> 10` **and this don't exist** `(1..10).clamp(42)`
250
+ `clamp_on` reverse this logic, and apply the caller to the params.
251
+ This choice has been made to avoid a monkey patch on `clamp`
252
+ :warning: If you `clamp_on` a `range` that don't overlap with the caller, the return value is `nil`
253
+
254
+ ```ruby
255
+ Period.today.clamp_on(Period.this_week)
256
+ => Period.today
257
+
258
+ Period.today.clamp_on(Period.last_week)
259
+ => nil
260
+
261
+ Period.today.clamp_on(3.from_now)
262
+ => # 3.from_now or today ending's time
263
+
264
+ ```
265
+
245
266
  ## Boundless Period
246
267
 
247
268
  Boundless period are fully supported and work as you expect them to do
@@ -10,21 +10,75 @@ module ActivePeriod
10
10
  include_period?(ActivePeriod::Day.new(other))
11
11
  when ActivePeriod::Period
12
12
  include_period?(other)
13
+ when Range
14
+ include?(other.first) && include?(other.last)
13
15
  else
14
16
  raise ArgumentError, I18n.t(:incomparable_error, scope: %i[active_period comparable])
15
17
  end
16
18
  end
17
19
 
18
20
  def <=>(other)
19
- raise ArgumentError, I18n.t(:incomparable_error, scope: %i[active_period comparable]) unless other.is_a?(ActiveSupport::Duration)
20
-
21
- if other.is_a?(ActiveSupport::Duration) || other.is_a?(Numeric)
21
+ case other
22
+ when DateTime, Time, ActiveSupport::TimeWithZone
23
+ if first < other && last < other
24
+ -1
25
+ elsif first > other && last > other
26
+ 1
27
+ else
28
+ 0
29
+ end
30
+ when ActiveSupport::Duration, Numeric
22
31
  to_i <=> other.to_i
23
- elsif self.class != other.class
24
- raise ArgumentError, I18n.t(:incomparable_error, scope: %i[active_period comparable])
25
32
  else
26
- (self.begin <=> other)
33
+ if self.class != other.class
34
+ raise ArgumentError, I18n.t(:incomparable_error, scope: %i[active_period comparable])
35
+ else
36
+ (self.begin <=> other)
37
+ end
38
+ end
39
+ end
40
+
41
+ # Reverse clamp where the `other` is clamped by `self`
42
+ # If other is an ActivePeriod::Period then `clamp_on` will return an ActivePeriod::Period
43
+ # If other is not an ActivePeriod::Period then `clamp_on` will return a range
44
+ def clamp_on(other)
45
+ case other
46
+ when DateTime, Time, ActiveSupport::TimeWithZone
47
+ case self <=> other
48
+ when -1
49
+ last
50
+ when 0
51
+ other
52
+ when 1
53
+ first
54
+ end
55
+ when ActivePeriod::Period
56
+ self & other
57
+ when Range
58
+ if (other.first > last && other.last > last) ||
59
+ (other.first < first && other.last < first)
60
+ return nil
61
+ end
62
+
63
+ clamped = clamp_on(other.first) .. clamp_on(other.last)
64
+
65
+ if other.is_a? ActivePeriod::Period
66
+ clamped.to_period
67
+ else
68
+ clamped
69
+ end
70
+ else
71
+ raise ArgumentError, I18n.t(:incomparable_error, scope: %i[active_period comparable])
27
72
  end
73
+ #
74
+ # new_first = other.first < first ? first : other.first
75
+ # new_last = other.last > last ? last : other.last
76
+ #
77
+ # if other.is_a? ActivePeriod::Period
78
+ # Period.new(new_first .. new_last)
79
+ # else
80
+ # new_first .. new_last
81
+ # end
28
82
  end
29
83
 
30
84
  private
@@ -32,8 +86,6 @@ module ActivePeriod
32
86
  def include_period?(other)
33
87
  if self.class.in?([Month, Quarter, Year]) && other.is_a?(Week)
34
88
  self.include_time?(other.include_date)
35
- # elsif (other.class.in?([Month, Quarter, Year]) && self.is_a?(Week)
36
- # other.include_time?(self.include_date)
37
89
  else
38
90
  self.include_time?(other.begin) && self.include_time?(other.calculated_end)
39
91
  end
@@ -107,11 +107,11 @@ class ActivePeriod::Period < Range
107
107
  # self 5-----8
108
108
  # other 1-----------10
109
109
  elsif other.include?(self)
110
- other
110
+ self
111
111
  # self 1-----------10
112
112
  # other 5-----8
113
113
  elsif self.include?(other)
114
- self
114
+ other
115
115
  else
116
116
  nil
117
117
  end
@@ -1,5 +1,5 @@
1
1
  module ActivePeriod
2
2
 
3
- VERSION = '7.1.2'.freeze
3
+ VERSION = '7.1.4'.freeze
4
4
 
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_period
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.1.2
4
+ version: 7.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - billau_l
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-16 00:00:00.000000000 Z
11
+ date: 2024-07-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -159,7 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
159
159
  - !ruby/object:Gem::Version
160
160
  version: '0'
161
161
  requirements: []
162
- rubygems_version: 3.3.22
162
+ rubygems_version: 3.5.9
163
163
  signing_key:
164
164
  specification_version: 4
165
165
  summary: Manage time ranges without brain damage.