timeliness 0.4.1 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 22c5b15397d7f945442d9768efb71ebbb243e7d44b8948d8ccf03e31c70858b3
4
- data.tar.gz: 96ac6e12fd20b0b5530e3ae99e60b2df81c9014bd7cedba26fa6e9395268d8b5
3
+ metadata.gz: 830b2a8f549031529ac5f153c60e80c4f6babae4edfd5e883fc954645f350322
4
+ data.tar.gz: 74ed311a9aa4a2da4d995a774e1ee438ee1454708cb25d991dfac30440d4cdcc
5
5
  SHA512:
6
- metadata.gz: d3c968646a9f6bc9d867d31c062724e162c8824fd4feb9f76a682f46cfd20cf817948b06bb1f14731eb2f3bb2be5d433edcb39d51ee8655e863898940f9ebf08
7
- data.tar.gz: 5eb2af292e5248ee58cfd539bad3491c668adf8c564579c1694ebffd0163e27d0353aec2bd0d478923d930d796d878ca8e99861ea15c9ea86d4bac9089ce16f8
6
+ metadata.gz: 66516e7c7cd33f1ef1c030f99a9e0ede74a39091c18d8c039310894a4e9ef7069c3630ac9bb6e2fe2f2b9be1acd68ca17e0036645842f56a489101776417264c
7
+ data.tar.gz: a1334464ba03f8c55245ab93ea8d26267900e5af3c2a6b6340d566e7cf59917758526ac2ab9165424568c84a8058932129fecc9a1caa844d2cb067bc0a679fdb
@@ -1,3 +1,8 @@
1
+ = 0.4.2 - 2019-06-15
2
+ * Fixed thread safe issue that forced you to use one of the date format methods e.g. `use_euro_formats`
3
+ to initialize the format sets in each new thread. Now a new thread will default to the global default (main thread).
4
+ * Add `Timeliness.ambiguous_date_format` config setting (:us or :euro) to control global default for date format sets.
5
+
1
6
  = 0.4.1 - 2019-06-11
2
7
  * Add format for ISO 8601 with usec and 'Z' UTC zone offset (jartek)
3
8
  * Fix ISO 8601 parsing bug where Z was not recognised as UTC
@@ -236,7 +236,7 @@ To see all defined formats look at the {source code}[http://github.com/adzap/tim
236
236
  === US/Euro Formats
237
237
 
238
238
  The perennial problem for non-US developers or applications not primarily for the US, is the US date
239
- format of m/d/yy. This is ambiguous with the European format of d/m/yy. By default the gem uses the
239
+ format of m/d/yy. This is can be ambiguous with the European format of d/m/yy. By default the gem uses the
240
240
  US formats as this is the Ruby default
241
241
  when it does date interpretation.
242
242
 
@@ -250,6 +250,13 @@ You can switch back to US formats with
250
250
 
251
251
  Timeliness.use_us_formats
252
252
 
253
+ ==== Thread Safety
254
+
255
+ The switching of formats is threadsafe (since v0.4.0), however for each new thread the format default will be
256
+ the gem default, being the US format. To control default for your app and each new thread, use the config
257
+
258
+ Timeliness.ambiguous_date_format = :euro
259
+
253
260
 
254
261
  === Customising Formats
255
262
 
@@ -2,7 +2,6 @@ require 'date'
2
2
  require 'forwardable'
3
3
 
4
4
  require 'timeliness/helpers'
5
- require 'timeliness/threadsafe_attr'
6
5
  require 'timeliness/definitions'
7
6
  require 'timeliness/format'
8
7
  require 'timeliness/format_set'
@@ -14,7 +13,7 @@ module Timeliness
14
13
  extend Forwardable
15
14
  def_delegators Parser, :parse, :_parse
16
15
  def_delegators Definitions, :add_formats, :remove_formats, :use_us_formats, :use_euro_formats
17
- attr_accessor :default_timezone, :date_for_time_type, :ambiguous_year_threshold
16
+ attr_accessor :default_timezone, :date_for_time_type, :ambiguous_date_format, :ambiguous_year_threshold
18
17
  end
19
18
 
20
19
  # Default timezone. Options:
@@ -31,6 +30,12 @@ module Timeliness
31
30
  #
32
31
  self.date_for_time_type = lambda { Time.now }
33
32
 
33
+ # Default parsing of ambiguous date formats. Options:
34
+ # - :us (default, 01/02/2000 = 2nd of January 2000)
35
+ # - :euro (01/02/2000 = 1st of February 2000)
36
+ #
37
+ self.ambiguous_date_format = :us
38
+
34
39
  # Set the threshold value for a two digit year to be considered last century
35
40
  #
36
41
  # Default: 30
@@ -155,9 +155,8 @@ module Timeliness
155
155
  DuplicateFormat = Class.new(StandardError)
156
156
 
157
157
  class << self
158
- extend ThreadsafeAttr
159
158
  attr_accessor :time_formats, :date_formats, :datetime_formats, :format_tokens, :format_components, :timezone_mapping
160
- threadsafe_attr_accessor :date_format_set, :time_format_set, :datetime_format_set
159
+ attr_reader :time_format_set, :date_format_set, :datetime_format_set
161
160
 
162
161
  # Adds new formats. Must specify format type and can specify a :before
163
162
  # option to nominate which format the new formats should be inserted in
@@ -191,35 +190,51 @@ module Timeliness
191
190
  compile_formats
192
191
  end
193
192
 
194
- # Removes US date formats so that ambiguous dates are parsed as European format
193
+ def current_date_format=(value)
194
+ Thread.current["Timeliness.current_date_format"] = value
195
+ end
196
+
197
+ def current_date_format
198
+ Thread.current["Timeliness.current_date_format"] ||= @current_date_format
199
+ end
200
+
201
+ # Get date format set for using current thread format setting
202
+ def date_format_set
203
+ instance_variable_get(:"@#{current_date_format}_date_format_set")
204
+ end
205
+
206
+ # Get datetime format set for using current thread format setting
207
+ def datetime_format_set
208
+ instance_variable_get(:"@#{current_date_format}_datetime_format_set")
209
+ end
210
+
211
+ # Use date formats that return ambiguous dates parsed in European format
195
212
  #
196
213
  def use_euro_formats
197
- self.date_format_set = @euro_date_format_set
198
- self.datetime_format_set = @euro_datetime_format_set
214
+ self.current_date_format = :euro
199
215
  end
200
216
 
201
- # Restores default to parse ambiguous dates as US format
217
+ # Use date formats that return ambiguous dates parsed as US format
202
218
  #
203
219
  def use_us_formats
204
- self.date_format_set = @us_date_format_set
205
- self.datetime_format_set = @us_datetime_format_set
220
+ self.current_date_format = :us
206
221
  end
207
222
 
208
223
  def compile_formats
209
- @sorted_token_keys = nil
210
- self.time_format_set = FormatSet.compile(time_formats)
224
+ @sorted_token_keys = nil
225
+ @current_date_format = Timeliness.ambiguous_date_format
211
226
 
227
+ self.current_date_format = @current_date_format
228
+
229
+ @time_format_set = FormatSet.compile(time_formats)
212
230
  @us_date_format_set = FormatSet.compile(date_formats)
213
231
  @us_datetime_format_set = FormatSet.compile(datetime_formats)
214
232
  @euro_date_format_set = FormatSet.compile(date_formats.select { |format| US_FORMAT_REGEXP !~ format })
215
233
  @euro_datetime_format_set = FormatSet.compile(datetime_formats.select { |format| US_FORMAT_REGEXP !~ format })
216
-
217
- self.date_format_set = @us_date_format_set
218
- self.datetime_format_set = @us_datetime_format_set
219
234
  end
220
235
 
221
236
  def sorted_token_keys
222
- @sorted_token_keys ||= format_tokens.keys.sort {|a,b| a.size <=> b.size }.reverse
237
+ @sorted_token_keys ||= format_tokens.keys.sort_by(&:size).reverse
223
238
  end
224
239
 
225
240
  # Returns format for type and other possible matching format set based on type
@@ -1,3 +1,3 @@
1
1
  module Timeliness
2
- VERSION = '0.4.1'
2
+ VERSION = '0.4.2'
3
3
  end
@@ -102,15 +102,25 @@ describe Timeliness::Definitions do
102
102
  end
103
103
  end
104
104
 
105
- context "threadsafety" do
106
- it "should allow threadsafe use of regional formats" do
107
- eu_date = "30/06/2016"
108
- us_date = "06/30/2016"
109
- threads = []
110
- threads << Thread.new { Timeliness.use_euro_formats; sleep(0.005); Timeliness.parse(eu_date) }
111
- threads << Thread.new { sleep(0.001); Timeliness.use_us_formats; Timeliness.parse(us_date) }
112
- threads.each { |t| t.join }
113
- threads.each { |t| expect(t.value).to eql(Time.new(2016,06,30)) }
105
+ context "thread safe date format switching" do
106
+ let(:ambiguous_date) { "01/02/2000" }
107
+
108
+ it "should allow indepdent regional format control in current thread" do
109
+ threads = {
110
+ euro: Thread.new { Timeliness.use_euro_formats; sleep(0.005); Timeliness.parse(ambiguous_date) },
111
+ us: Thread.new { sleep(0.001); Timeliness.use_us_formats; Timeliness.parse(ambiguous_date) }
112
+ }
113
+ threads.values.each { |t| t.join }
114
+
115
+ expect(threads[:euro].value).to eql(Time.new(2000,2,1))
116
+ expect(threads[:us].value).to eql(Time.new(2000,1,2))
117
+ end
118
+
119
+ it 'should use default regional format in new threads' do
120
+ thread = Thread.new { sleep(0.001); Timeliness.parse(ambiguous_date) }
121
+ thread.join
122
+
123
+ expect(thread.value).to eql(Time.new(2000,1,2))
114
124
  end
115
125
  end
116
126
  end
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.1
4
+ version: 0.4.2
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 00:00:00.000000000 Z
11
+ date: 2019-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -102,7 +102,6 @@ files:
102
102
  - lib/timeliness/format_set.rb
103
103
  - lib/timeliness/helpers.rb
104
104
  - lib/timeliness/parser.rb
105
- - lib/timeliness/threadsafe_attr.rb
106
105
  - lib/timeliness/version.rb
107
106
  - spec/spec_helper.rb
108
107
  - spec/timeliness/core_ext/string_spec.rb
@@ -1,24 +0,0 @@
1
- module Timeliness
2
- module ThreadsafeAttr
3
- def threadsafe_attr_accessor(*attrs)
4
- attrs.each do |attr|
5
- storage_name = "#{name}.#{attr}".freeze
6
- reader attr, storage_name
7
- writer attr, storage_name
8
- end
9
- end
10
-
11
- private
12
- def reader(attr, storage_name)
13
- define_method(attr) do
14
- Thread.current[storage_name]
15
- end
16
- end
17
-
18
- def writer(attr, storage_name)
19
- define_method("#{attr}=") do |value|
20
- Thread.current[storage_name] = value
21
- end
22
- end
23
- end
24
- end