timeliness 0.4.2 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.rdoc +5 -0
- data/lib/timeliness.rb +11 -29
- data/lib/timeliness/configuration.rb +40 -0
- data/lib/timeliness/definitions.rb +3 -4
- data/lib/timeliness/helpers.rb +1 -1
- data/lib/timeliness/parser.rb +7 -5
- data/lib/timeliness/version.rb +1 -1
- data/spec/timeliness/definitions_spec.rb +12 -5
- data/spec/timeliness/parser_spec.rb +23 -30
- data/spec/timeliness_helper.rb +4 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '09a4713be8da3195a5d92e1cfbd2bfda98f35ff922674fd12339bcecc562e366'
|
4
|
+
data.tar.gz: d645f22bed3e99b5e2ebf971304e6f6acc6b657339f3d3d651ea67902258fb24
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 346644804949fc5398084ff04feecca71b6a415908433520932ff7f38985bcf6bb2c8db0dd048f3939286ebdf9d01fab4544ab9c45e5d2a6549984231f0ec329
|
7
|
+
data.tar.gz: 39b7862378f626fb7f361769deb81488cd7d5c3c86a61a81dff199ea4b6abc07d29422f64a16e8220085a49fc25c45216259c1e49d5a371533ac4255257fb25f
|
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
= 0.4.3 - 2019-06-16
|
2
|
+
* Fixed `Timeliness.ambiguous_date_format` being used in new threads if custom value set
|
3
|
+
* Moved all config from Timeliness to new Configuration class. Delegated all
|
4
|
+
old config methods to Timeliness.configuration instance.
|
5
|
+
|
1
6
|
= 0.4.2 - 2019-06-15
|
2
7
|
* Fixed thread safe issue that forced you to use one of the date format methods e.g. `use_euro_formats`
|
3
8
|
to initialize the format sets in each new thread. Now a new thread will default to the global default (main thread).
|
data/lib/timeliness.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'date'
|
2
2
|
require 'forwardable'
|
3
3
|
|
4
|
+
require 'timeliness/configuration'
|
4
5
|
require 'timeliness/helpers'
|
5
6
|
require 'timeliness/definitions'
|
6
7
|
require 'timeliness/format'
|
@@ -13,38 +14,19 @@ module Timeliness
|
|
13
14
|
extend Forwardable
|
14
15
|
def_delegators Parser, :parse, :_parse
|
15
16
|
def_delegators Definitions, :add_formats, :remove_formats, :use_us_formats, :use_euro_formats
|
16
|
-
attr_accessor :
|
17
|
-
end
|
18
|
-
|
19
|
-
# Default timezone. Options:
|
20
|
-
# - :local (default)
|
21
|
-
# - :utc
|
22
|
-
#
|
23
|
-
# If ActiveSupport loaded, also
|
24
|
-
# - :current
|
25
|
-
# - 'Zone name'
|
26
|
-
#
|
27
|
-
self.default_timezone = :local
|
17
|
+
attr_accessor :configuration
|
28
18
|
|
29
|
-
|
30
|
-
|
31
|
-
|
19
|
+
def_delegators :configuration, :default_timezone, :date_for_time_type, :ambiguous_date_format, :ambiguous_year_threshold
|
20
|
+
def_delegators :configuration, :default_timezone=, :date_for_time_type=, :ambiguous_date_format=, :ambiguous_year_threshold=
|
21
|
+
end
|
32
22
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
#
|
37
|
-
self.ambiguous_date_format = :us
|
23
|
+
def self.configuration
|
24
|
+
@configuration ||= Configuration.new
|
25
|
+
end
|
38
26
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
#
|
43
|
-
# Example:
|
44
|
-
# year = '29' is considered 2029
|
45
|
-
# year = '30' is considered 1930
|
46
|
-
#
|
47
|
-
self.ambiguous_year_threshold = 30
|
27
|
+
def self.configure
|
28
|
+
yield(configuration)
|
29
|
+
end
|
48
30
|
end
|
49
31
|
|
50
32
|
Timeliness::Definitions.compile_formats
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Timeliness
|
2
|
+
class Configuration
|
3
|
+
# Default timezone. Options:
|
4
|
+
# - :local (default)
|
5
|
+
# - :utc
|
6
|
+
#
|
7
|
+
# If ActiveSupport loaded, also
|
8
|
+
# - :current
|
9
|
+
# - 'Zone name'
|
10
|
+
#
|
11
|
+
attr_accessor :default_timezone
|
12
|
+
|
13
|
+
# Set the default date part for a time type values.
|
14
|
+
#
|
15
|
+
attr_accessor :date_for_time_type
|
16
|
+
|
17
|
+
# Default parsing of ambiguous date formats. Options:
|
18
|
+
# - :us (default, 01/02/2000 = 2nd of January 2000)
|
19
|
+
# - :euro (01/02/2000 = 1st of February 2000)
|
20
|
+
#
|
21
|
+
attr_accessor :ambiguous_date_format
|
22
|
+
|
23
|
+
# Set the threshold value for a two digit year to be considered last century
|
24
|
+
#
|
25
|
+
# Default: 30
|
26
|
+
#
|
27
|
+
# Example:
|
28
|
+
# year = '29' is considered 2029
|
29
|
+
# year = '30' is considered 1930
|
30
|
+
#
|
31
|
+
attr_accessor :ambiguous_year_threshold
|
32
|
+
|
33
|
+
def initialize
|
34
|
+
@default_timezone = :local
|
35
|
+
@date_for_time_type = lambda { Time.now }
|
36
|
+
@ambiguous_date_format = :us
|
37
|
+
@ambiguous_year_threshold = 30
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -195,15 +195,17 @@ module Timeliness
|
|
195
195
|
end
|
196
196
|
|
197
197
|
def current_date_format
|
198
|
-
Thread.current["Timeliness.current_date_format"] ||=
|
198
|
+
Thread.current["Timeliness.current_date_format"] ||= Timeliness.configuration.ambiguous_date_format
|
199
199
|
end
|
200
200
|
|
201
201
|
# Get date format set for using current thread format setting
|
202
|
+
#
|
202
203
|
def date_format_set
|
203
204
|
instance_variable_get(:"@#{current_date_format}_date_format_set")
|
204
205
|
end
|
205
206
|
|
206
207
|
# Get datetime format set for using current thread format setting
|
208
|
+
#
|
207
209
|
def datetime_format_set
|
208
210
|
instance_variable_get(:"@#{current_date_format}_datetime_format_set")
|
209
211
|
end
|
@@ -222,9 +224,6 @@ module Timeliness
|
|
222
224
|
|
223
225
|
def compile_formats
|
224
226
|
@sorted_token_keys = nil
|
225
|
-
@current_date_format = Timeliness.ambiguous_date_format
|
226
|
-
|
227
|
-
self.current_date_format = @current_date_format
|
228
227
|
|
229
228
|
@time_format_set = FormatSet.compile(time_formats)
|
230
229
|
@us_date_format_set = FormatSet.compile(date_formats)
|
data/lib/timeliness/helpers.rb
CHANGED
@@ -15,7 +15,7 @@ module Timeliness
|
|
15
15
|
def unambiguous_year(year)
|
16
16
|
if year.length <= 2
|
17
17
|
century = Time.now.year.to_s[0..1].to_i
|
18
|
-
century -= 1 if year.to_i >= Timeliness.ambiguous_year_threshold
|
18
|
+
century -= 1 if year.to_i >= Timeliness.configuration.ambiguous_year_threshold
|
19
19
|
year = "#{century}#{year.rjust(2,'0')}"
|
20
20
|
end
|
21
21
|
year.to_i
|
data/lib/timeliness/parser.rb
CHANGED
@@ -105,7 +105,7 @@ module Timeliness
|
|
105
105
|
end
|
106
106
|
|
107
107
|
def shift_time_to_zone(time, zone=nil)
|
108
|
-
zone ||= Timeliness.default_timezone
|
108
|
+
zone ||= Timeliness.configuration.default_timezone
|
109
109
|
case zone
|
110
110
|
when :utc, :local
|
111
111
|
time.send("get#{zone}")
|
@@ -117,7 +117,7 @@ module Timeliness
|
|
117
117
|
end
|
118
118
|
|
119
119
|
def create_time_in_zone(time_array, zone=nil)
|
120
|
-
zone ||= Timeliness.default_timezone
|
120
|
+
zone ||= Timeliness.configuration.default_timezone
|
121
121
|
case zone
|
122
122
|
when :utc, :local
|
123
123
|
time_with_datetime_fallback(zone, *time_array)
|
@@ -153,11 +153,13 @@ module Timeliness
|
|
153
153
|
end
|
154
154
|
|
155
155
|
def evaluate_date_for_time_type
|
156
|
-
|
156
|
+
date_for_time_type = Timeliness.configuration.date_for_time_type
|
157
|
+
|
158
|
+
case date_for_time_type
|
157
159
|
when Array
|
158
|
-
|
160
|
+
date_for_time_type
|
159
161
|
when Proc
|
160
|
-
v =
|
162
|
+
v = date_for_time_type.call
|
161
163
|
[v.year, v.month, v.day]
|
162
164
|
end
|
163
165
|
end
|
data/lib/timeliness/version.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
describe Timeliness::Definitions do
|
2
|
-
|
3
2
|
context "add_formats" do
|
4
3
|
before do
|
5
4
|
@default_formats = definitions.time_formats.dup
|
@@ -102,10 +101,16 @@ describe Timeliness::Definitions do
|
|
102
101
|
end
|
103
102
|
end
|
104
103
|
|
105
|
-
context "thread safe date format switching" do
|
104
|
+
context "thread safe ambiguous date format switching" do
|
106
105
|
let(:ambiguous_date) { "01/02/2000" }
|
107
106
|
|
108
|
-
|
107
|
+
around do |example|
|
108
|
+
Timeliness::Definitions.compile_formats
|
109
|
+
example.call
|
110
|
+
Timeliness::Definitions.compile_formats
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should allow independent control in current thread" do
|
109
114
|
threads = {
|
110
115
|
euro: Thread.new { Timeliness.use_euro_formats; sleep(0.005); Timeliness.parse(ambiguous_date) },
|
111
116
|
us: Thread.new { sleep(0.001); Timeliness.use_us_formats; Timeliness.parse(ambiguous_date) }
|
@@ -116,11 +121,13 @@ describe Timeliness::Definitions do
|
|
116
121
|
expect(threads[:us].value).to eql(Time.new(2000,1,2))
|
117
122
|
end
|
118
123
|
|
119
|
-
it 'should use default
|
124
|
+
it 'should use default format in new threads' do
|
125
|
+
Timeliness.configuration.ambiguous_date_format = :euro
|
126
|
+
|
120
127
|
thread = Thread.new { sleep(0.001); Timeliness.parse(ambiguous_date) }
|
121
128
|
thread.join
|
122
129
|
|
123
|
-
expect(thread.value).to eql(Time.new(2000,1
|
130
|
+
expect(thread.value).to eql(Time.new(2000,2,1))
|
124
131
|
end
|
125
132
|
end
|
126
133
|
end
|
@@ -1,19 +1,17 @@
|
|
1
1
|
describe Timeliness::Parser do
|
2
|
-
around(:all) do |example|
|
3
|
-
current_default = Timeliness.default_timezone
|
4
|
-
current_zone = Time.zone
|
5
|
-
example.call
|
6
|
-
Time.zone = current_zone
|
7
|
-
Timeliness.default_timezone = current_default
|
8
|
-
end
|
9
|
-
|
10
2
|
def self.timezone_settings(zone: nil, output: nil)
|
11
3
|
before do
|
12
4
|
Time.zone = zone if zone
|
13
|
-
Timeliness.default_timezone = output if output
|
5
|
+
Timeliness.configuration.default_timezone = output if output
|
14
6
|
end
|
15
7
|
end
|
16
8
|
|
9
|
+
around(:all) do |example|
|
10
|
+
current_zone = Time.zone
|
11
|
+
example.call
|
12
|
+
Time.zone = current_zone
|
13
|
+
end
|
14
|
+
|
17
15
|
before(:all) do
|
18
16
|
Timecop.freeze(2010,1,1,0,0,0)
|
19
17
|
end
|
@@ -121,22 +119,25 @@ describe Timeliness::Parser do
|
|
121
119
|
timezone_settings zone: 'Australia/Melbourne'
|
122
120
|
|
123
121
|
it 'should return value using string zone adjusted to default :local timezone' do
|
124
|
-
Timeliness.default_timezone = :local
|
122
|
+
Timeliness.configuration.default_timezone = :local
|
123
|
+
|
125
124
|
value = parse("Thu, 01 Jun 2000 03:00:00 MST")
|
126
125
|
expect(value).to eq Time.utc(2000,6,1,10,0,0).getlocal
|
127
126
|
expect(value.utc_offset).to eq Time.mktime(2000, 6, 1, 10, 0, 0).utc_offset
|
128
127
|
end
|
129
128
|
|
130
129
|
it 'should return value using string zone adjusted to default :current timezone' do
|
131
|
-
Timeliness.default_timezone = :current
|
130
|
+
Timeliness.configuration.default_timezone = :current
|
132
131
|
Time.zone = 'Adelaide'
|
132
|
+
|
133
133
|
value = parse("Thu, 01 Jun 2000 03:00:00 MST")
|
134
134
|
expect(value).to eq Time.zone.local(2000,6,1,19,30,0)
|
135
135
|
expect(value.utc_offset).to eq 9.5.hours
|
136
136
|
end
|
137
137
|
|
138
138
|
it 'should return value using string zone adjusted to :zone option string timezone' do
|
139
|
-
Timeliness.default_timezone = :local
|
139
|
+
Timeliness.configuration.default_timezone = :local
|
140
|
+
|
140
141
|
value = parse("Thu, 01 Jun 2000 03:00:00 MST", :zone => 'Perth')
|
141
142
|
expect(value).to eq Time.use_zone('Perth') { Time.zone.local(2000,6,1,18,0,0) }
|
142
143
|
expect(value.utc_offset).to eq 8.hours
|
@@ -147,7 +148,7 @@ describe Timeliness::Parser do
|
|
147
148
|
timezone_settings zone: 'Australia/Melbourne'
|
148
149
|
|
149
150
|
it 'should return value using string zone adjusted to default :current timezone' do
|
150
|
-
Timeliness.default_timezone = :current
|
151
|
+
Timeliness.configuration.default_timezone = :current
|
151
152
|
|
152
153
|
value = parse("2000-06-01T12:00:00Z")
|
153
154
|
expect(value).to eq Time.zone.local(2000,6,1,22,0,0)
|
@@ -276,22 +277,16 @@ describe Timeliness::Parser do
|
|
276
277
|
|
277
278
|
context "for time type" do
|
278
279
|
context "with date from date_for_time_type" do
|
279
|
-
before do
|
280
|
-
@original = Timeliness.date_for_time_type
|
281
|
-
end
|
282
|
-
|
283
280
|
it 'should return date array' do
|
284
|
-
Timeliness.date_for_time_type = [2010,1,1]
|
281
|
+
Timeliness.configuration.date_for_time_type = [2010,1,1]
|
282
|
+
|
285
283
|
expect(parse('12:13:14', :time)).to eq Time.local(2010,1,1,12,13,14)
|
286
284
|
end
|
287
285
|
|
288
286
|
it 'should return date array evaluated lambda' do
|
289
|
-
Timeliness.date_for_time_type = lambda { Time.local(2010,2,1) }
|
290
|
-
expect(parse('12:13:14', :time)).to eq Time.local(2010,2,1,12,13,14)
|
291
|
-
end
|
287
|
+
Timeliness.configuration.date_for_time_type = lambda { Time.local(2010,2,1) }
|
292
288
|
|
293
|
-
|
294
|
-
Timeliness.date_for_time_type = @original
|
289
|
+
expect(parse('12:13:14', :time)).to eq Time.local(2010,2,1,12,13,14)
|
295
290
|
end
|
296
291
|
end
|
297
292
|
|
@@ -303,7 +298,6 @@ describe Timeliness::Parser do
|
|
303
298
|
|
304
299
|
context "with :zone option" do
|
305
300
|
before(:all) do
|
306
|
-
Timecop.return
|
307
301
|
@current_tz = ENV['TZ']
|
308
302
|
ENV['TZ'] = 'Australia/Melbourne'
|
309
303
|
Timecop.freeze(2010,1,1,0,0,0)
|
@@ -317,7 +311,6 @@ describe Timeliness::Parser do
|
|
317
311
|
end
|
318
312
|
|
319
313
|
after(:all) do
|
320
|
-
Timecop.return
|
321
314
|
ENV['TZ'] = @current_tz
|
322
315
|
Timecop.freeze(2010,1,1,0,0,0)
|
323
316
|
end
|
@@ -442,13 +435,12 @@ describe Timeliness::Parser do
|
|
442
435
|
end
|
443
436
|
|
444
437
|
it "should allow custom threshold" do
|
445
|
-
|
446
|
-
|
438
|
+
Timeliness.configuration.ambiguous_year_threshold = 40
|
439
|
+
|
447
440
|
time_array = parser._parse('01-02-39', :date)
|
448
441
|
expect(time_array).to eq [2039,2,1,nil,nil,nil,nil,nil]
|
449
442
|
time_array = parser._parse('01-02-40', :date)
|
450
443
|
expect(time_array).to eq [1940,2,1,nil,nil,nil,nil,nil]
|
451
|
-
Timeliness.ambiguous_year_threshold = default
|
452
444
|
end
|
453
445
|
end
|
454
446
|
end
|
@@ -476,7 +468,8 @@ describe Timeliness::Parser do
|
|
476
468
|
|
477
469
|
context "default timezone" do
|
478
470
|
it "should be used if no zone value" do
|
479
|
-
Timeliness.default_timezone = :utc
|
471
|
+
Timeliness.configuration.default_timezone = :utc
|
472
|
+
|
480
473
|
time = parser.make_time([2000,6,1,12,0,0])
|
481
474
|
expect(time.utc_offset).to eq 0
|
482
475
|
end
|
@@ -518,7 +511,7 @@ describe Timeliness::Parser do
|
|
518
511
|
|
519
512
|
context "with no options" do
|
520
513
|
it 'should return date_for_time_type values with no options' do
|
521
|
-
dummy_date = Timeliness.date_for_time_type.call
|
514
|
+
dummy_date = Timeliness.configuration.date_for_time_type.call
|
522
515
|
expect(current_date).to eq [ dummy_date.year, dummy_date.month, dummy_date.day ]
|
523
516
|
end
|
524
517
|
end
|
data/spec/timeliness_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timeliness
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Meehan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-06-
|
11
|
+
date: 2019-06-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -95,6 +95,7 @@ files:
|
|
95
95
|
- Rakefile
|
96
96
|
- benchmark.rb
|
97
97
|
- lib/timeliness.rb
|
98
|
+
- lib/timeliness/configuration.rb
|
98
99
|
- lib/timeliness/core_ext.rb
|
99
100
|
- lib/timeliness/core_ext/string.rb
|
100
101
|
- lib/timeliness/definitions.rb
|