easy_time 0.1.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4495654dbc3739198ac730b17b43fd61d66edf258f3a1506e7608414b6e16328
4
+ data.tar.gz: f3cb77f9f6a71a2d0c48811f3f69153f93678eda2e7510db58fc26657cfe4764
5
+ SHA512:
6
+ metadata.gz: 1bff901b47f340553598a7e1f618faaf011ead4e86c3a32abf84a9edd64afecd043a932811d83a63d6820e319a89fb4c0df2f451733f1c22a5b1465585f83415
7
+ data.tar.gz: c87ede1b52cd24227c3734c41230af038ee3710ee46dffd9c11776dab8dfe73f8553999e5d04da9ba15f45a4f52a0ebc9133c2a8da228e9c5c2af48240b0bdcc
@@ -0,0 +1,132 @@
1
+ version: 2.1
2
+ orbs:
3
+ ruby: circleci/ruby@0.1.2
4
+
5
+ defaults: &DEFAULTS
6
+ resource_class: small
7
+ docker:
8
+ - image: circleci/ruby:2.5
9
+
10
+ environment:
11
+ BUNDLE_JOBS: 3
12
+ BUNDLE_RETRY: 3
13
+ BUNDLE_PATH: vendor/bundle
14
+
15
+ working_directory: ~/repo
16
+
17
+ jobs:
18
+ build:
19
+ docker:
20
+ - image: circleci/ruby:2.6.3-stretch-node
21
+ executor: ruby/default
22
+ steps:
23
+ - checkout
24
+ - attach_workspace:
25
+ at: ~/repo
26
+
27
+ - restore_cache:
28
+ keys:
29
+ - gem-cache-{{ checksum "easy_time.gemspec" }}
30
+ - gem-cache-
31
+
32
+ - run:
33
+ name: Install bundler
34
+ command: gem install bundler
35
+
36
+ - run:
37
+ name: Check bundle version
38
+ command: bundle --version
39
+
40
+ - run:
41
+ name: set the bundle path
42
+ command: bundle config set path 'vendor/bundle'
43
+
44
+ - run:
45
+ name: install dependencies
46
+ command: bundle install --jobs=4 --retry=3
47
+
48
+ - save_cache:
49
+ paths:
50
+ - ./vendor/bundle
51
+ key: gem-cache-{{ checksum "easy_time.gemspec" }}
52
+
53
+ - run:
54
+ name: run tests
55
+ command: |
56
+ mkdir /tmp/test-results
57
+ TEST_FILES="$(circleci tests glob 'spec/**/*_spec.rb' | circleci tests split --split-by=timings)"
58
+
59
+ bundle exec rspec --format RspecJunitFormatter \
60
+ --out /tmp/test-results/rspec.xml \
61
+ --format progress \
62
+ $TEST_FILES
63
+
64
+ - store_test_results:
65
+ path: /tmp/test-results
66
+
67
+ - store_artifacts:
68
+ path: /tmp/test-results
69
+ destination: test-results
70
+
71
+ - run:
72
+ name: build package
73
+ command: |
74
+ bundle exec rake clean
75
+ bundle exec rake build
76
+
77
+ release:
78
+ <<: *DEFAULTS
79
+ steps:
80
+ - checkout
81
+
82
+ - attach_workspace:
83
+ at: ~/repo
84
+
85
+ - restore_cache:
86
+ keys:
87
+ - gem-cache-{{ checksum "easy_time.gemspec" }}
88
+ - gem-cache-
89
+
90
+ - run:
91
+ name: Check bundle version
92
+ command: bundle --version
93
+
94
+ - run:
95
+ name: Install bundler
96
+ command: gem install bundler
97
+
98
+ - run:
99
+ name: set the bundle path
100
+ command: bundle config set path 'vendor/bundle'
101
+
102
+ - run:
103
+ name: install dependencies
104
+ command: bundle install --jobs=4 --retry=3
105
+
106
+ - save_cache:
107
+ paths:
108
+ - ./vendor/bundle
109
+ key: gem-cache-{{ checksum "easy_time.gemspec" }}
110
+
111
+ - run:
112
+ name: build package
113
+ command: |
114
+ bundle exec rake clean
115
+ bundle exec rake build
116
+
117
+ #- deploy:
118
+ # name: Release and push
119
+ # command: bundle exec gem push
120
+
121
+ workflows:
122
+ version: 2
123
+ bundle_build_test_release:
124
+ jobs:
125
+ - build
126
+ - release:
127
+ requires:
128
+ - build
129
+ filters:
130
+ branches:
131
+ only: master
132
+
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --backtrace
3
+ --fail-fast
4
+ --format Fuubar
data/.rubocop.yml ADDED
@@ -0,0 +1,38 @@
1
+ # Metrics
2
+ Metrics/AbcSize:
3
+ Enabled: false
4
+
5
+ Metrics/CyclomaticComplexity:
6
+ Enabled: false
7
+
8
+ Metrics/MethodLength:
9
+ Enabled: false
10
+
11
+ Metrics/PerceivedComplexity:
12
+ Enabled: false
13
+
14
+ Metrics/ClassLength:
15
+ Enabled: false
16
+
17
+ # Layouts
18
+ Layout/ExtraSpacing:
19
+ Enabled: false
20
+
21
+ Layout/LineLength:
22
+ Enabled: false
23
+
24
+ Layout/SpacingAroundOperators:
25
+ Enabled: false
26
+
27
+ # Styles
28
+ Style/AsciiComments:
29
+ Enabled: false
30
+
31
+ Style/Documentation:
32
+ Enabled: false
33
+
34
+ Style/StringLiterals:
35
+ Enabled: false
36
+
37
+ Style/RescueModifier:
38
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.7.1
6
+ before_install: gem install bundler -v 2.1.4
data/.yardopts ADDED
@@ -0,0 +1,4 @@
1
+ -r README.md
2
+ --markup-provider=redcarpet
3
+ --markup=markdown
4
+ --no-private --protected lib/**/*.rb -
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in easy_time.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,137 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ easy_time (0.1.2)
5
+ activesupport
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activesupport (6.0.2.2)
11
+ concurrent-ruby (~> 1.0, >= 1.0.2)
12
+ i18n (>= 0.7, < 2)
13
+ minitest (~> 5.1)
14
+ tzinfo (~> 1.1)
15
+ zeitwerk (~> 2.2)
16
+ ast (2.4.0)
17
+ builder (3.2.4)
18
+ byebug (11.1.3)
19
+ coderay (1.1.2)
20
+ concurrent-ruby (1.1.6)
21
+ diff-lcs (1.3)
22
+ docile (1.3.2)
23
+ ffi (1.12.2)
24
+ formatador (0.2.5)
25
+ fuubar (2.5.0)
26
+ rspec-core (~> 3.0)
27
+ ruby-progressbar (~> 1.4)
28
+ guard (2.16.2)
29
+ formatador (>= 0.2.4)
30
+ listen (>= 2.7, < 4.0)
31
+ lumberjack (>= 1.0.12, < 2.0)
32
+ nenv (~> 0.1)
33
+ notiffany (~> 0.0)
34
+ pry (>= 0.9.12)
35
+ shellany (~> 0.0)
36
+ thor (>= 0.18.1)
37
+ guard-compat (1.2.1)
38
+ guard-rspec (4.7.3)
39
+ guard (~> 2.1)
40
+ guard-compat (~> 1.1)
41
+ rspec (>= 2.99.0, < 4.0)
42
+ guard-yard (2.2.1)
43
+ guard (>= 1.1.0)
44
+ yard (>= 0.7.0)
45
+ i18n (1.8.2)
46
+ concurrent-ruby (~> 1.0)
47
+ jaro_winkler (1.5.4)
48
+ listen (3.2.1)
49
+ rb-fsevent (~> 0.10, >= 0.10.3)
50
+ rb-inotify (~> 0.9, >= 0.9.10)
51
+ lumberjack (1.2.4)
52
+ method_source (1.0.0)
53
+ minitest (5.14.0)
54
+ nenv (0.3.0)
55
+ notiffany (0.1.3)
56
+ nenv (~> 0.1)
57
+ shellany (~> 0.0)
58
+ parallel (1.19.1)
59
+ parser (2.7.1.1)
60
+ ast (~> 2.4.0)
61
+ pry (0.13.1)
62
+ coderay (~> 1.1)
63
+ method_source (~> 1.0)
64
+ pry-byebug (3.9.0)
65
+ byebug (~> 11.0)
66
+ pry (~> 0.13.0)
67
+ rainbow (3.0.0)
68
+ rake (13.0.1)
69
+ rb-fsevent (0.10.3)
70
+ rb-inotify (0.10.1)
71
+ ffi (~> 1.0)
72
+ redcarpet (3.5.0)
73
+ rexml (3.2.4)
74
+ rspec (3.9.0)
75
+ rspec-core (~> 3.9.0)
76
+ rspec-expectations (~> 3.9.0)
77
+ rspec-mocks (~> 3.9.0)
78
+ rspec-core (3.9.1)
79
+ rspec-support (~> 3.9.1)
80
+ rspec-expectations (3.9.1)
81
+ diff-lcs (>= 1.2.0, < 2.0)
82
+ rspec-support (~> 3.9.0)
83
+ rspec-mocks (3.9.1)
84
+ diff-lcs (>= 1.2.0, < 2.0)
85
+ rspec-support (~> 3.9.0)
86
+ rspec-support (3.9.2)
87
+ rspec_junit (4.0.4)
88
+ builder (>= 3.2.2)
89
+ rspec (>= 3.3.0)
90
+ rspec_junit_formatter (0.4.1)
91
+ rspec-core (>= 2, < 4, != 2.12.0)
92
+ rubocop (0.82.0)
93
+ jaro_winkler (~> 1.5.1)
94
+ parallel (~> 1.10)
95
+ parser (>= 2.7.0.1)
96
+ rainbow (>= 2.2.2, < 4.0)
97
+ rexml
98
+ ruby-progressbar (~> 1.7)
99
+ unicode-display_width (>= 1.4.0, < 2.0)
100
+ ruby-progressbar (1.10.1)
101
+ shellany (0.0.1)
102
+ simplecov (0.18.5)
103
+ docile (~> 1.1)
104
+ simplecov-html (~> 0.11)
105
+ simplecov-html (0.12.2)
106
+ terminal-notifier-guard (1.7.0)
107
+ thor (1.0.1)
108
+ thread_safe (0.3.6)
109
+ tzinfo (1.2.7)
110
+ thread_safe (~> 0.1)
111
+ unicode-display_width (1.7.0)
112
+ yard (0.9.24)
113
+ zeitwerk (2.3.0)
114
+
115
+ PLATFORMS
116
+ ruby
117
+
118
+ DEPENDENCIES
119
+ bundler (~> 2.1.4)
120
+ easy_time!
121
+ fuubar (>= 2.5.0)
122
+ guard
123
+ guard-rspec
124
+ guard-yard
125
+ pry-byebug
126
+ rake
127
+ redcarpet
128
+ rspec
129
+ rspec_junit
130
+ rspec_junit_formatter
131
+ rubocop (>= 0.82.0)
132
+ simplecov
133
+ terminal-notifier-guard
134
+ yard (>= 0.9.24)
135
+
136
+ BUNDLED WITH
137
+ 2.1.4
data/Guardfile ADDED
@@ -0,0 +1,35 @@
1
+ # Guardfile for easy_time gem
2
+
3
+ begin
4
+ require 'terminal-notifier-guard'
5
+ notification :terminal_notifier, app_name: 'easy_time'
6
+ rescue LoadError
7
+ warn "Failed to load notifier"
8
+ end
9
+
10
+ guard :rspec,
11
+ all_on_start: false,
12
+ all_after_pass: false,
13
+ failed_mode: :focus,
14
+ cmd: "CODE_COVERAGE=1 bundle exec rspec" do
15
+ directories(%w[lib spec])
16
+ .select { |d| Dir.exist?(d) ? d : UI.warning("Directory #{d} does not exist") }
17
+
18
+ require "guard/rspec/dsl"
19
+ dsl = Guard::RSpec::Dsl.new(self)
20
+
21
+ # RSpec files
22
+ rspec = dsl.rspec
23
+ watch(rspec.spec_helper) { rspec.spec_dir }
24
+ watch(rspec.spec_support) { rspec.spec_dir }
25
+ watch(rspec.spec_files)
26
+
27
+ # Ruby files
28
+ ruby = dsl.ruby
29
+ dsl.watch_spec_files_for(ruby.lib_files)
30
+ end
31
+
32
+ guard 'yard' do
33
+ watch(%r{lib\/.+\.rb})
34
+ watch('README.md')
35
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Alan Stebbens
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,300 @@
1
+ # EasyTime
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/easy_time.svg)](https://badge.fury.io/rb/easy_time)
4
+
5
+ [![CircleCI](https://circleci.com/gh/aks/easy_time.svg?style=shield)](https://app.circleci.com/pipelines/github/aks/easy_time)
6
+
7
+ Are you tired of having to deal with many kinds of date and time objects?
8
+
9
+ Are you frustrated that comparing timestamps from different systems yields
10
+ incorrect results? _(Were you surprised to learn that, despite really good
11
+ time sync sources, many systems aren't actually synced all that closely in
12
+ time?)_
13
+
14
+ Well, then, give EasyTime a try!
15
+
16
+ `EasyTime` accepts most of the well-known date and time objects, including
17
+ `RFC2822`, `HTTPDate`, `XMLSchema`, `ISO8601`, as well as
18
+ ActiveSupport::TimeWithZone strings and provides comparisons that have an
19
+ adjustable tolerance. With `EasyTime` methods, you can reliably compare two
20
+ timestamps and determine which one is "newer", "older" or the "same" withing
21
+ a configurable tolerance. The default comparison tolerance is 1.minute.
22
+
23
+ In other words, if you have a time-stamp from an `ActiveRecord` object that is
24
+ a few seconds different from a related object obtained from a 3rd-party system,
25
+ (eg: AWS S3), then logically, from an application perspective, these two
26
+ objects could be considered having the "same" time-stamp.
27
+
28
+ This is quite useful when one is trying to keep state synchronized between
29
+ different systems. How does one know if an object is "newer" or "older" than
30
+ that from another system? If the system time from the connected systems varies
31
+ by a few or more seconds, then comparisons needs to have some tolerance.
32
+
33
+ Having a tolerant comparison makes "newness" and "oldness" checks easier to
34
+ manage across systems with possibly varying time sources.
35
+
36
+ `EasyTime` objects are just like Time objects, except:
37
+
38
+ - they auto-convert most date and time objects to Time objects
39
+ - they provide configurable tolerant comparisons between two time objects
40
+
41
+ Even if you decide to set the configurable comparison tolerance to zero
42
+ _(disabling it)_, the auto-type conversion of most date and time objects is
43
+ very useful all by itself.
44
+
45
+ Finally, this module adds a new instance method to the familiar date and time
46
+ classes, to easily convert from the object to the corresponding `EasyTime`
47
+ object:
48
+
49
+ obj.easy_time
50
+
51
+ For example, this is pretty cool:
52
+
53
+ '2010-09-08 07:06:05 +04:00'.easy_time # => EasyTime instance
54
+
55
+ So it is just as easy to convert an ISO8601 time string as it is to convert
56
+ a `created_at` value from an ActiveRecord object:
57
+
58
+ rec.created_at.easy_time # => EasyTime instance
59
+
60
+ resp = RestClient.get service_uri + '/get_time'
61
+ time = JSON.parse(resp.body)["date_time"].easy_time
62
+
63
+
64
+ These are the currently known date and time classes the values of which will be
65
+ automatically converted, enabling tolerant ("easy") comparisons:
66
+
67
+ Date
68
+ Time
69
+ DateTime
70
+ ActiveSupport::Duration
71
+ ActiveSupport::TimeWithZone
72
+
73
+ ## Installation
74
+
75
+ Add this line to your application's `Gemfile`:
76
+
77
+ ```ruby
78
+ gem 'easy_time'
79
+ ```
80
+
81
+ or, add this to your application's `*-gemspec.rb` file:
82
+
83
+ add.dependency 'easy_time'
84
+
85
+ And then execute:
86
+
87
+ $ bundle install
88
+
89
+ Or install it yourself as:
90
+
91
+ $ gem install easy_time
92
+
93
+ ## Usage
94
+
95
+ require 'easy_time'
96
+
97
+ ### Class Methods
98
+
99
+ There are class methods and instance methods.
100
+
101
+ ### Creating a `EasyTime` Value
102
+
103
+ EasyTime.new(time)
104
+
105
+ This creates a new `EasyTime` value, which is essentially a wrapped `Time` value.
106
+
107
+ The `new` method uses the `convert` method to convert several known date and
108
+ time value types into a `Time` value.
109
+
110
+ EasyTime.convert(timestr)
111
+
112
+ ### Auto-Conversion Date and Time Classes
113
+
114
+ These are the currently known class values that can be converted:
115
+
116
+ String # => Time.parse(string)
117
+ EasyTime # => EasyTime.time
118
+ Time # => Time
119
+ Date # => Time.iso8601(Date.iso8601)
120
+ DateTime # => Time.iso8601(DateTime.iso8601)
121
+ [yyyy,mm,dd,...] # => Time.new(yyyy,mm,dd,...)
122
+ ActiveSupport::TimeWithZone # => value.to_time (eg: 3.weeks.ago)
123
+ ActiveSupport::Duration # => Time.now + duration (eg: 2.months)
124
+
125
+ Most of the date and time classes have built-in ISO8601 formatters, which
126
+ allows easy conversion using the `Time.iso8601` parser.
127
+
128
+ The `EasyTime` and `Time` values are passed through unchanged.
129
+
130
+ The `ActiveSupport::TimeWithZone` value is converted to a `Time`.
131
+
132
+ The `ActiveSupport::Duration` value is converted to a `Time` by adding it to `Time.now`.
133
+
134
+ A `String` value is parsed with the `convert` method.
135
+
136
+ #### Time Strings
137
+
138
+ Most modern time format strings are recognized: ISO8601, RFD2822, HTTPDate,
139
+ XMLSchema, and even some natural date and time formats. Many systems use an
140
+ [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) string, which has date, time,
141
+ and timezone components, with each variant having some variations.
142
+
143
+ With `EasyTime`, you don't have to know which time string format to use,
144
+ you can just ask `EasyTime` to convert it. If it can't, you'll get an
145
+ `ArgumentError` exception.
146
+
147
+ ### `EasyTime` Comparison Class Methods
148
+
149
+ One advantage of `EasyTime` values over the other time objects is that `EasyTime`
150
+ can perform tolerant-comparisons, where the tolerance can be specified by
151
+ you _(the developer)_.
152
+
153
+ These are the `EasyTime` class methods for comparison:
154
+
155
+ EasyTime.newer?(t1, t2) # => true if t1 > t2
156
+ EasyTime.older?(t1, t2) # => true if t1 < t2
157
+ EasyTime.same?(t1, t2) # => true if t1 == t2 with tolerance
158
+ EasyTime.compare(t1, t2) # => t1 <=> t2 => -1, 0, 1, or nil with tolerance
159
+
160
+ Each comparison method auto-converts both time arguments into a `Time` value,
161
+ and then compares them with tolerance. This means that if the absolute
162
+ difference between `t1` and `t2` is less than the configured tolerance value,
163
+ then the two values will be considered equal _(the same)_.
164
+
165
+ If the two values are not tolerantly-equal, then the two values are compared
166
+ with `<=>`, which normally returns one of three values: [-1, 0, 1]. However,
167
+ since a tolerant-equality _(or sameness)_ was already tested and ruled out, the
168
+ comparison using `<=>` will only ever return -1 or 1.
169
+
170
+ Finally, if either time value is nil, or cannot be converted to a Time value,
171
+ the result of any comparison method is also nil.
172
+
173
+ There are other methods that make use of the tolerant comparison:
174
+
175
+ EasyTime.between?(t1, t_min, t_max) # => true if t1 >= t_min and t1 <= t_max
176
+
177
+ or
178
+
179
+ EasyTime.between?(t1, time_range) # => true if t1 is within the time_range
180
+
181
+
182
+ ### Configuring the Comparison Tolerance
183
+
184
+ As described above, the comparison tolerance value can be configured to
185
+ something other than the default of `DEFAULT_TIME_COMPARISON_TOLERANCE`, which
186
+ is currently set to `1.minute`.
187
+
188
+ EasyTime.tolerance = 15.seconds # set an appropriate tolerance for our app
189
+
190
+ The above will set the tolerance value to 15 seconds. This configuration is
191
+ applied across all instances of the class.
192
+
193
+ ### EasyTime Instance Methods
194
+
195
+ Once a `EasyTime` value has been created, it is basically a wrapped `Time` value
196
+ where the comparison methods are overridden in order to apply the comparison
197
+ tolerance value.
198
+
199
+ These are the instance methods:
200
+
201
+ t1 < t2 # => true if t1 is older than t2
202
+ t1 > t2 # => true if t1 is newer than t2
203
+ t1 <= t2 # => true if t1 is the same or older as t2
204
+ t1 >= t2 # => true if t1 is the same or newer as t2
205
+ t1 != t2 # => true if t1 is not the same as t2 (with tolerance)
206
+ t1 == t2 # => true if t1 is the same as t2 (with tolerance)
207
+
208
+ On each of the above, the `t2` value will be automatically converted to
209
+ a `Time` value, and tolerantly compared against `t1`.
210
+
211
+ In addition to the infix operators, there are the comparison instance methods:
212
+
213
+ t1.newer?(t2) # => true if t1 is newer (>) than t2
214
+ t1.older?(t2) # => true if t1 is older (<) then t2
215
+ t1.same?(t2) # => true if t1 is equal (==) to t2
216
+ t1.compare(t2) # => [-1, 0, 1] from t1 <=> t2
217
+
218
+ and
219
+
220
+ t1.between?(t_min, t_max) #=> true if t_min >= t1 <= t_max
221
+ t1.between?([t_min..t_max]) # => true if t1 is in the range
222
+
223
+ In all the above instance methods, `t2`, `t_min`, or `t_max` may be any known
224
+ date or time value, which is automatically converted into a Time value for the
225
+ tolerant comparison.
226
+
227
+ Arithmetic operators with auto-conversion are also supported:
228
+
229
+ t1 + duration
230
+ t1 - t2
231
+ t1 - duration
232
+
233
+ The `t2` can be a date, time or even a time string. In which case, the are
234
+ converted to a `Time` value, and the subtraction is performed between two
235
+ dates, with a duration result.
236
+
237
+ When arithmetic is performed with a `duration` value, then the result is a new
238
+ updated `EasyTime` value
239
+
240
+ ### Auto-Conversion Of Comparison Values
241
+
242
+ `EasyTime` values can be compared with tolerance against any other time value,
243
+ including time strings, using instance methods. The receiver object must be an
244
+ `EasyTime` object in order to enable the auto-conversion of the other time
245
+ object.
246
+
247
+ The values provided on any comparison operator or method are converted to
248
+ a `Time` value using the same `convert` routine. See the description of the
249
+ acceptable date and time types above.
250
+
251
+ ### Comparison Tolerance Instance Methods
252
+
253
+ As given above, the comparison tolerance value used on the instance methods is
254
+ that previously configured either on the instance, or at the class level.
255
+
256
+ It is possible, however, to dynamically provide comparison tolerance when
257
+ creating a new `EasyTime` value, or with the `with_tolerance` method.
258
+
259
+ In addition to the class methods for comparison tolerance, it is possible to
260
+ configure the comparison tolerance for each instance.
261
+
262
+ The `new` method accepts an optional `tolerance:` keyword value:
263
+
264
+ t1 = EasyTime.new(record.created_at, tolerance: 20.seconds)
265
+ t1.newer?(another_time) # => compared with a tolerance of 20 seconds
266
+
267
+ The comparison tolerance can also be set dynamically using `.with_tolerance`:
268
+
269
+ t1 = EasyTime.new(record.updated_at)
270
+ t1.with_tolerance(1.second) > another_time
271
+ t1.with_tolerance(2.seconds).newer?(another_time)
272
+
273
+ The `.with_tolerance` method creates a _new_ `EasyTime` value with the
274
+ specified tolerance, leaving the original value and configured tolerance
275
+ intact.
276
+
277
+ ## Development
278
+
279
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
280
+ `rake spec` to run the tests. You can also run `bin/console` for an interactive
281
+ prompt that will allow you to experiment.
282
+
283
+ To install this gem onto your local machine, run `bundle exec rake install`. To
284
+ release a new version, update the version number in `version.rb`, and then run
285
+ `bundle exec rake release`, which will create a git tag for the version, push
286
+ git commits and tags, and push the `.gem` file to
287
+ [rubygems.org](https://rubygems.org).
288
+
289
+ ## Contributing
290
+
291
+ Bug reports and pull requests are welcome on GitHub at https://github.com/aks/easy_time.
292
+
293
+
294
+ ## License
295
+
296
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
297
+
298
+ ## Author
299
+
300
+ Alan K. Stebbens `<aks@stebbens.org>`