time_calc 0.0.3 → 0.0.4

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: 3222784ca4e6f520d4402ce84f5ea6f8a9becccb66e3640071d0a29b332297b7
4
- data.tar.gz: 9746e03e5a3e560a5f63780e87ea75f87597faa44e594228f075ae5daca3a83b
3
+ metadata.gz: b611cfb8c2a45b600235a6a7b3c1c2ce0688205cf9b2be7130b2efa3a5f6b0bd
4
+ data.tar.gz: cd1ea75b65a186e5f444a4c1fbd20f146d36635857bbe901797a770d8249ec00
5
5
  SHA512:
6
- metadata.gz: a6f3315fe5e4bc9334cbee7f089f50aebf7dfa854a6580f7cc53488afa0c8cb9ef0601f0d47c691b8427cbeea4dcc2842c97022666009e3b01b8e4056883b67c
7
- data.tar.gz: d0ccd1540d9010f5c4cec6c3fb4708b75c3fc795cbe8913f7a7e43455caa6bf209f6d39ca828dd83bae8d73f4a7e8b7a0a7a432eaeaaec33442e6ef1afe5716d
6
+ metadata.gz: 91f750a32bf00c3bec57458cf89cabcaf0a307204b5a94d4bc5fb1210af88849b8c5e07feb63a75f6d05b242f5b390b2c64610df13156d7c19bd8db598227543
7
+ data.tar.gz: 89d16a28e6744ee4d7fd0c0cb18cbaf7dba2e8c8d1e459760b271c87e4927ca5e6a898af5220bb8e5bc9ce3148665fc7eb8d0a23a1bceef7ba356d2b3543355a
@@ -1,5 +1,10 @@
1
1
  # TimeCalc changelog
2
2
 
3
+ ## 0.0.4 / 2020-04-11
4
+
5
+ * Support `ActiveSupport::TimeWithZone` as a calculation target.
6
+
7
+
3
8
  ## 0.0.3 / 2019-12-14
4
9
 
5
10
  * Add `TimeCalc#iterate` to easily operate in "business date/time" contexts.
@@ -11,4 +16,4 @@
11
16
 
12
17
  ## 0.0.1 / 2019-07-05
13
18
 
14
- First release. Rip-off of [time_math2](https://github.com/zverok/time_math2) with full API redesign and dropping of some less-used features ("resamplers").
19
+ First release. Rip-off of [time_math2](https://github.com/zverok/time_math2) with full API redesign and dropping of some less-used features ("resamplers").
data/README.md CHANGED
@@ -16,7 +16,8 @@ _**NB:** TimeCalc is a continuation of [TimeMath](https://github.com/zverok/time
16
16
  * Tries its best to preserve timezone/offset information:
17
17
  * **on Ruby 2.6+**, for `Time` with real timezones, preserves them;
18
18
  * on Ruby < 2.6, preserves at least `utc_offset` of `Time`;
19
- * for `DateTime` preserves zone name.
19
+ * for `DateTime` preserves zone name;
20
+ * _Since 0.0.4,_ supports `ActiveSupport::TimeWithZone`, too. While in ActiveSupport-enabled context TimeCalc may seem redundant (you'll probably use `time - 1.day` anyways), some of the functionality is easier with TimeCalc (rounding to different units) or just not present in ActiveSupport (time sequences, iterate with skippking); also may be helpful for third-party libraries which want to use TimeCalc underneath but don't want to be broken in Rails context.
20
21
 
21
22
  ## Synopsis
22
23
 
@@ -7,11 +7,16 @@ class TimeCalc
7
7
  extend self
8
8
 
9
9
  ATTRS = {
10
- Time => %i[year month day hour min sec subsec utc_offset],
11
- Date => %i[year month day],
12
- DateTime => %i[year month day hour min sec sec_fraction zone]
10
+ 'Time' => %i[year month day hour min sec subsec utc_offset],
11
+ 'Date' => %i[year month day],
12
+ 'DateTime' => %i[year month day hour min sec sec_fraction zone],
13
+ 'ActiveSupport::TimeWithZone' => %i[year month day hour min sec sec_fraction time_zone]
13
14
  }.freeze
14
15
 
16
+ # @private
17
+ # Because AS::TimeWithZone so frigging smart that it returns "Time" from redefined class name.
18
+ CLASS_NAME = Class.instance_method(:name)
19
+
15
20
  def compatible?(v1, v2)
16
21
  [v1, v2].all?(Date) || [v1, v2].all?(Time)
17
22
  end
@@ -46,6 +51,22 @@ class TimeCalc
46
51
  .values.then { |components| DateTime.new(*components) }
47
52
  end
48
53
 
54
+ def merge_activesupport__timewithzone(value, **attrs)
55
+ # You'd imagine we should be able to use just value.change(...) ActiveSupport's API here...
56
+ # But it is not available if you don't require all the core_ext's of Time, so I decided to
57
+ # be on the safe side and use similar approach everywhere.
58
+
59
+ # When we truncate, we use :subsec key as a sign to zeroefy second fractions
60
+ attrs[:sec_fraction] ||= attrs.delete(:subsec) if attrs.key?(:subsec)
61
+
62
+ _merge(value, **attrs)
63
+ .then { |components|
64
+ zone = components.delete(:time_zone)
65
+ components.merge!(mday: components.delete(:day), mon: components.delete(:month))
66
+ zone.__send__(:parts_to_time, components, value)
67
+ }
68
+ end
69
+
49
70
  private
50
71
 
51
72
  REAL_TIMEZONE = ->(z) { z.respond_to?(:utc_to_local) } # Ruby 2.6 real timezones
@@ -63,7 +84,7 @@ class TimeCalc
63
84
  end
64
85
 
65
86
  def _merge(value, attrs)
66
- attr_names = ATTRS.fetch(value.class)
87
+ attr_names = ATTRS.fetch(CLASS_NAME.bind(value.class).call)
67
88
  attr_names.to_h { |u| [u, value.public_send(u)] }.merge(**attrs.slice(*attr_names))
68
89
  end
69
90
  end
@@ -6,27 +6,7 @@ require 'backports/2.6.0/hash/to_h'
6
6
  require 'backports/2.6.0/kernel/then'
7
7
  require 'backports/2.5.0/hash/slice'
8
8
  require 'backports/2.5.0/enumerable/all'
9
-
10
- if RUBY_VERSION < '2.7'
11
- # @private
12
- # TODO: Replace with backports after 2.7 release
13
- class Enumerator
14
- NOVALUE = Object.new.freeze
15
-
16
- def self.produce(initial = NOVALUE)
17
- fail ArgumentError, 'No block given' unless block_given?
18
-
19
- Enumerator.new do |y|
20
- val = initial == NOVALUE ? yield() : initial
21
-
22
- loop do
23
- y << val
24
- val = yield(val)
25
- end
26
- end
27
- end
28
- end
29
- end
9
+ require 'backports/2.7.0/enumerator/produce'
30
10
 
31
11
  class TimeCalc
32
12
  # Wrapper (one can say "monad") around date/time value, allowing to perform several TimeCalc
@@ -40,10 +20,17 @@ class TimeCalc
40
20
  # @private
41
21
  TIMEY = proc { |t| t.respond_to?(:to_time) }
42
22
 
23
+ # @private
24
+ # Because AS::TimeWithZone so frigging smart that it returns "Time" from redefined class name.
25
+ CLASS_NAME = Class.instance_method(:name)
26
+
43
27
  # @private
44
28
  def self.wrap(value)
45
29
  case value
46
30
  when Time, Date, DateTime
31
+ # NB: ActiveSupport::TimeWithZone will also pass to this branch if
32
+ # active_support/core_ext/time is required. But it is doubtfully it is not -- TWZ will be
33
+ # mostly unusable :)
47
34
  new(value)
48
35
  when Value
49
36
  value
@@ -100,7 +87,8 @@ class TimeCalc
100
87
  # @param attrs [Hash<Symbol => Integer>]
101
88
  # @return [Value]
102
89
  def merge(**attrs)
103
- Value.new(Types.public_send("merge_#{internal.class.name.downcase}", internal, **attrs))
90
+ class_name = CLASS_NAME.bind(internal.class).call.tr(':', '_')
91
+ Value.new(Types.public_send("merge_#{class_name.downcase}", internal, **attrs))
104
92
  end
105
93
 
106
94
  # Truncates all time components lower than `unit`. In other words, "floors" (rounds down)
@@ -2,5 +2,5 @@
2
2
 
3
3
  class TimeCalc
4
4
  # @private
5
- VERSION = '0.0.3'
5
+ VERSION = '0.0.4'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: time_calc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Shepelev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-12-14 00:00:00.000000000 Z
11
+ date: 2020-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backports
@@ -16,42 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 3.15.0
19
+ version: 3.17.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 3.15.0
26
+ version: 3.17.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rubocop
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.77.0
33
+ version: 0.81.0
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.77.0
40
+ version: 0.81.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rubocop-rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 1.37.0
47
+ version: 1.38.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 1.37.0
54
+ version: 1.38.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -86,14 +86,14 @@ dependencies:
86
86
  requirements:
87
87
  - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: 0.0.6
89
+ version: 0.0.7
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
- version: 0.0.6
96
+ version: 0.0.7
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: simplecov
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -110,18 +110,32 @@ dependencies:
110
110
  version: '0.9'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: tzinfo
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.1'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.1'
125
+ - !ruby/object:Gem::Dependency
126
+ name: activesupport
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
129
  - - ">="
116
130
  - !ruby/object:Gem::Version
117
- version: '0'
131
+ version: '5.0'
118
132
  type: :development
119
133
  prerelease: false
120
134
  version_requirements: !ruby/object:Gem::Requirement
121
135
  requirements:
122
136
  - - ">="
123
137
  - !ruby/object:Gem::Version
124
- version: '0'
138
+ version: '5.0'
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: rake
127
141
  requirement: !ruby/object:Gem::Requirement