timeliness 0.4.4 → 0.5.0

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: 0b1224a95afa47942b2118db304f6b00f741748e129243fe277ccb45127b9804
4
- data.tar.gz: 320e9633f0769274f57bcca370e1a839abf62039df963af1d4cb35757b9f03fc
3
+ metadata.gz: 23fc962cb22262464b617a95fc8690f5b94400ee5de69fc110166975bf59fd40
4
+ data.tar.gz: fead9e440fb74611873e5ab1a89747514072602d961f01a3c1d96c9d1b052610
5
5
  SHA512:
6
- metadata.gz: 593b8a2649f97b485a94f205c2e500ca38c31d4db734d46962c4224f12df47fe6679a111d1a950e1794f46065a9e922eafbada8a8dc617ac68a250a1249fba1c
7
- data.tar.gz: 3b8705a405281a0d4bb2c56f436a6e016bae0f83ed8f61700fc6553d37ed53614b85b56d818063bc4aaa5dc96360426e762da038ed30374473448c621a18e07b
6
+ metadata.gz: ee38a67400fbe0b4bb9141eb359f3c8462a0a1d61b8c21b4bed1e7cc655bb4ac91246894abd8a4a25f279d1cfd94c0ef0d03cda034f76cea14adef01af5dba6d
7
+ data.tar.gz: 7310005faf480be6392f5c7838d2ea4e0ad9391a6cedd77a1f65709c6c93963b11131ccc5b2c9ceafa5a5dc3efde90b30fe0b06b61bbe183b8911ede2019f3bf
@@ -0,0 +1,23 @@
1
+ name: CI
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ test:
7
+
8
+ runs-on: ubuntu-latest
9
+
10
+ strategy:
11
+ fail-fast: false
12
+ matrix:
13
+ ruby: ["2.5", "2.6", "2.7", "3.0", "3.1", ruby-head, jruby-9.2, jruby-9.3, jruby-head]
14
+
15
+ steps:
16
+ - uses: actions/checkout@v2
17
+ - name: Set up Ruby
18
+ uses: ruby/setup-ruby@v1
19
+ with:
20
+ bundler-cache: true # 'bundle install' and cache gems
21
+ ruby-version: ${{ matrix.ruby }}
22
+ - name: Run tests
23
+ run: bundle exec rspec
data/.travis.yml CHANGED
@@ -1,16 +1,19 @@
1
+ dist: focal
2
+ os: linux
1
3
  language: ruby
2
- before_install:
3
- - gem install bundler
4
+ before_install: gem install bundler
4
5
  cache: bundler
5
6
 
6
7
  rvm:
7
- # - jruby
8
- # - truffleruby
9
- # - rbx-3
10
- - "2.3.8"
11
- - "2.4.5"
12
- - "2.5.3"
13
- - "2.6.1"
8
+ - "2.5.8"
9
+ - "2.6.6"
10
+ - "2.7.2"
11
+ - "3.0.0"
12
+ - ruby-head
13
+
14
+ jobs:
15
+ allow_failures:
16
+ - rvm: ruby-head
14
17
 
15
18
  script: 'bundle exec rspec'
16
19
 
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,12 @@
1
+ = 0.5.0 - 2024-12-02
2
+ * Reduce allocations through some internal parsing changes
3
+ * Changed parse method arg handling to simple using keyword args
4
+
5
+ = 0.4.5 - 2023-01-19
6
+ * Support case insensitive months
7
+ * Migrated to Github Actions (@petergoldstein)
8
+ * Various doc, spec, and gemspec fixes and updates (@tagliala)
9
+
1
10
  = 0.4.4 - 2019-08-06
2
11
  * Raise compilation error if token with capturing arg is used more than once in a format
3
12
  * Some small internal refactorings in format compilation
@@ -10,7 +19,7 @@
10
19
  = 0.4.2 - 2019-06-15
11
20
  * Fixed thread safe issue that forced you to use one of the date format methods e.g. `use_euro_formats`
12
21
  to initialize the format sets in each new thread. Now a new thread will default to the global default (main thread).
13
- * Add `Timeliness.ambiguous_date_format` config setting (:us or :euro) to control global default for date format sets.
22
+ * Add `Timeliness.ambiguous_date_format` config setting (:us or :euro) to control global default for date format sets.
14
23
 
15
24
  = 0.4.1 - 2019-06-11
16
25
  * Add format for ISO 8601 with usec and 'Z' UTC zone offset (jartek)
@@ -19,7 +28,7 @@
19
28
 
20
29
  = 0.4.0 - 2019-02-09
21
30
  * Add threadsafety for use_euro_formats & use_us_formats to allow runtime
22
- switching (andruby, timdiggins)
31
+ switching (andruby, timdiggins)
23
32
 
24
33
  = 0.3.10 - 2019-02-06
25
34
  * Fixed file permissions in gem build
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010 Adam Meehan
1
+ Copyright (c) 2010-2021 Adam Meehan
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.rdoc CHANGED
@@ -1,7 +1,7 @@
1
1
  = Timeliness {<img src="https://travis-ci.org/adzap/timeliness.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/adzap/timeliness]
2
2
 
3
- * Source: http://github.com/adzap/timeliness
4
- * Bugs: http://github.com/adzap/timeliness/issues
3
+ * Source: https://github.com/adzap/timeliness
4
+ * Bugs: https://github.com/adzap/timeliness/issues
5
5
 
6
6
  == Description
7
7
 
@@ -16,7 +16,7 @@ Date/time parser for Ruby with the following features:
16
16
  * Has no dependencies.
17
17
  * Works with Ruby MRI >= 2.2
18
18
 
19
- Extracted from the {validates_timeliness gem}[http://github.com/adzap/validates_timeliness], it has been rewritten cleaner and much faster. It's most suitable for when
19
+ Extracted from the {validates_timeliness gem}[https://github.com/adzap/validates_timeliness], it has been rewritten cleaner and much faster. It's most suitable for when
20
20
  you need to control the parsing behaviour. It's faster than the Time/Date class parse methods, so it
21
21
  has general appeal.
22
22
 
@@ -51,14 +51,14 @@ ignored.
51
51
 
52
52
  === Specify the Current Date
53
53
 
54
- Notice a time only string will return with a date value. The date value can be configured globally
54
+ Notice a time only string will return with a date value. The date value can be configured globally
55
55
  with this setting:
56
56
 
57
57
  Timeliness.date_for_time_type = [2010, 1, 1]
58
58
 
59
59
  or using a lambda thats evaluated when parsed
60
60
 
61
- Timeliness.date_for_time_type = lambda { Time.now }
61
+ Timeliness.date_for_time_type = lambda { Time.now }
62
62
 
63
63
  It can also be specified with :now option:
64
64
 
@@ -143,7 +143,7 @@ You just need to add this line to an initializer or other application file:
143
143
 
144
144
  == Formats
145
145
 
146
- The gem has default formats included which can be easily added to using the format syntax. Also
146
+ The gem has default formats included which can be easily added to using the format syntax. Also
147
147
  formats can be easily removed so that they are no longer considered valid.
148
148
 
149
149
  Below are the default formats. If you think they are easy to read then you will be happy to know
@@ -228,7 +228,7 @@ Here is what each format token means:
228
228
  All other characters are considered literal. For the technically minded, these formats are compiled
229
229
  into a single regular expression
230
230
 
231
- To see all defined formats look at the {source code}[http://github.com/adzap/timeliness/tree/master/lib/timeliness/formats.rb].
231
+ To see all defined formats look at the {source code}[https://github.com/adzap/timeliness/tree/master/lib/timeliness/formats.rb].
232
232
 
233
233
 
234
234
  == Settings
@@ -252,7 +252,7 @@ You can switch back to US formats with
252
252
 
253
253
  ==== Thread Safety
254
254
 
255
- The switching of formats is threadsafe (since v0.4.0), however for each new thread the format default will be
255
+ The switching of formats is threadsafe (since v0.4.0), however for each new thread the format default will be
256
256
  the gem default, being the US format. To control default for your app and each new thread, use the config
257
257
 
258
258
  Timeliness.ambiguous_date_format = :euro
@@ -301,7 +301,7 @@ Now you get:
301
301
 
302
302
  == Credits
303
303
 
304
- * Adam Meehan (adam.meehan@gmail.com, http://github.com/adzap)
304
+ * Adam Meehan (adam.meehan@gmail.com, https://github.com/adzap)
305
305
 
306
306
 
307
307
  == License
data/Rakefile CHANGED
@@ -15,10 +15,11 @@ end
15
15
 
16
16
  desc 'Generate documentation for plugin.'
17
17
  Rake::RDocTask.new(:rdoc) do |rdoc|
18
+ rdoc.main = 'README.rdoc'
18
19
  rdoc.rdoc_dir = 'rdoc'
19
20
  rdoc.title = 'Timeliness'
20
- rdoc.options << '--line-numbers' << '--inline-source'
21
- rdoc.rdoc_files.include('README')
21
+ rdoc.options << '--line-numbers'
22
+ rdoc.rdoc_files.include('README.rdoc')
22
23
  rdoc.rdoc_files.include('lib/**/*.rb')
23
24
  end
24
25
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Timeliness
2
4
  module Definitions
3
5
 
@@ -80,7 +82,7 @@ module Timeliness
80
82
  'yyyy-mm-ddThh:nn:sszt', # ISO 8601 with 'Zulu time' (i.e. Z) UTC zone designator
81
83
  'yyyy-mm-ddThh:nn:ss.u', # ISO 8601 with usec
82
84
  'yyyy-mm-ddThh:nn:ss.uzo', # ISO 8601 with usec and offset
83
- 'yyyy-mm-ddThh:nn:ss.uzt', # ISO 8601 with usec and 'Zulu time' (i.e. Z) UTC zone designator
85
+ 'yyyy-mm-ddThh:nn:ss.uzt', # ISO 8601 with usec and 'Zulu time' (i.e. Z) UTC zone designator
84
86
  'yyyy-mm-dd hh:nn:ss zo', # Ruby time string in later versions
85
87
  'yyyy-mm-dd hh:nn:ss tz', # Ruby time string for UTC in later versions
86
88
  ]
@@ -46,7 +46,7 @@ module Timeliness
46
46
 
47
47
  define_process_method(token_order.compact)
48
48
  @regexp_string = format
49
- @regexp = Regexp.new("^(#{format})$")
49
+ @regexp = Regexp.new("^(?>#{format})$")
50
50
  self
51
51
  rescue => ex
52
52
  raise CompilationFailed, "The format '#{format_string}' failed to compile using regexp string #{format}. Error message: #{ex.inspect}"
@@ -63,7 +63,8 @@ module Timeliness
63
63
  position, code = Definitions.format_components[component]
64
64
  values[position] = code || "#{component}.to_i" if position
65
65
  end
66
- instance_eval <<~DEF
66
+ components << '*_' # absorb any excess arguments not used by format
67
+ instance_eval <<-DEF
67
68
  def process(#{components.join(',')})
68
69
  [#{values.map { |i| i || 'nil' }.join(',')}]
69
70
  end
@@ -20,8 +20,8 @@ module Timeliness
20
20
  format = Format.new(format_string).compile!
21
21
  @formats_hash[format_string] = format
22
22
  @match_indexes[index] = format
23
- regexp_string = "#{regexp_string}(#{format.regexp_string})|"
24
- index + format.token_count + 1 # add one for wrapper capture
23
+ regexp_string.concat("(?>#{format.regexp_string})|")
24
+ index + format.token_count
25
25
  }
26
26
  @regexp = %r[\A(?:#{regexp_string.chop})\z]
27
27
  self
@@ -31,17 +31,17 @@ module Timeliness
31
31
  format = single_format(format_string) if format_string
32
32
  match_regexp = format && format.regexp || @regexp
33
33
 
34
- if match_data = match_regexp.match(string)
35
- index = match_data.captures.index(string)
36
- start = index + 1
37
- values = match_data.captures[start..(start+7)].compact
34
+ match_regexp.match(string) do |match_data|
35
+ captures = match_data.captures # For a multi-format regexp there are lots of nils
36
+ index = captures.find_index { |e| !e.nil? } # Find the start of captures for matched format
37
+ values = captures.values_at(index..(index+7))
38
38
  format ||= @match_indexes[index]
39
39
  format.process(*values)
40
40
  end
41
41
  end
42
42
 
43
43
  def single_format(format_string)
44
- @formats_hash.fetch(format_string) { Format.new(format_string).compile! }
44
+ @formats_hash.fetch(format_string) { Format.new(format_string).compile! }
45
45
  end
46
46
  end
47
47
  end
@@ -23,7 +23,7 @@ module Timeliness
23
23
 
24
24
  def month_index(month)
25
25
  return month.to_i if month.to_i > 0 || /0+/ =~ month
26
- month.length > 3 ? month_names.index(month.capitalize) : abbr_month_names.index(month.capitalize)
26
+ (month.length > 3 ? month_names : abbr_month_names).index { |str| month.casecmp?(str) }
27
27
  end
28
28
 
29
29
  def month_names
@@ -4,11 +4,14 @@ module Timeliness
4
4
 
5
5
  class << self
6
6
 
7
- def parse(value, *args)
7
+ def parse(value, type=nil, **options)
8
8
  return value if acts_like_temporal?(value)
9
9
  return nil unless parseable?(value)
10
10
 
11
- type, options = type_and_options_from_args(args)
11
+ if type && !type.is_a?(Symbol)
12
+ options[:now] = type if type
13
+ type = nil
14
+ end
12
15
 
13
16
  time_array = _parse(value, type, options)
14
17
  return nil if time_array.nil?
@@ -40,7 +43,7 @@ module Timeliness
40
43
  Definitions.send("#{type}_format_set").match(string, options[:format])
41
44
  else
42
45
  values = nil
43
- Definitions.format_sets(type, string).find {|set| values = set.match(string, options[:format]) }
46
+ Definitions.format_sets(type, string).any? { |set| values = set.match(string, options[:format]) }
44
47
  values
45
48
  end
46
49
  rescue
@@ -95,8 +98,10 @@ module Timeliness
95
98
 
96
99
  def current_time_in_zone(zone)
97
100
  case zone
98
- when :utc, :local
99
- Time.now.send("get#{zone}")
101
+ when :utc
102
+ Time.now.getutc
103
+ when :local
104
+ Time.now.getlocal
100
105
  when :current
101
106
  Time.current
102
107
  else
@@ -107,8 +112,10 @@ module Timeliness
107
112
  def shift_time_to_zone(time, zone=nil)
108
113
  zone ||= Timeliness.configuration.default_timezone
109
114
  case zone
110
- when :utc, :local
111
- time.send("get#{zone}")
115
+ when :utc
116
+ time.getutc
117
+ when :local
118
+ time.getlocal
112
119
  when :current
113
120
  time.in_time_zone
114
121
  else
@@ -1,3 +1,3 @@
1
1
  module Timeliness
2
- VERSION = '0.4.4'
2
+ VERSION = '0.5.0'.freeze
3
3
  end
@@ -91,6 +91,26 @@ describe Timeliness::Format do
91
91
  expect(format.process('2', 'Enero', '2000')).to eq [2000,1,2,nil,nil,nil,nil,nil]
92
92
  end
93
93
 
94
+ context "with upper case month abbreviations" do
95
+ before(:all) do
96
+ I18n.backend.store_translations :es, date: { abbr_month_names: %w{ ~ ENE FEB MAR } }
97
+ end
98
+
99
+ it 'should parse abbreviated month for current locale case insensitively' do
100
+ expect(format_for('d-mmm-yyyy').process('01', 'mar', '2023')).to eq [2023,3,1,nil,nil,nil,nil,nil]
101
+ end
102
+ end
103
+
104
+ context "with upper case month names" do
105
+ before(:all) do
106
+ I18n.backend.store_translations :es, date: { month_names: %w{ ~ ENERO FEBRERO MARZO } }
107
+ end
108
+
109
+ it 'should parse full month for current locale case insensitively' do
110
+ expect(format_for('d-mmm-yyyy').process('01', 'mArZo', '2023')).to eq [2023,3,1,nil,nil,nil,nil,nil]
111
+ end
112
+ end
113
+
94
114
  after(:all) do
95
115
  I18n.locale = :en
96
116
  end
@@ -6,7 +6,7 @@ describe Timeliness::Parser do
6
6
  end
7
7
  end
8
8
 
9
- around(:all) do |example|
9
+ around do |example|
10
10
  current_zone = Time.zone
11
11
  example.call
12
12
  Time.zone = current_zone
@@ -104,13 +104,13 @@ describe Timeliness::Parser do
104
104
  it 'should return value shifted by positive offset in default timezone' do
105
105
  value = parse("2000-06-01T12:00:00+02:00")
106
106
  expect(value).to eq Time.zone.local(2000,6,1,3,0,0)
107
- expect(value.utc_offset).to eq -7.hours
107
+ expect(value.utc_offset).to eq(-7.hours)
108
108
  end
109
109
 
110
110
  it 'should return value shifted by negative offset in default timezone' do
111
111
  value = parse("2000-06-01T12:00:00-01:00")
112
112
  expect(value).to eq Time.zone.local(2000,6,1,6,0,0)
113
- expect(value.utc_offset).to eq -7.hours
113
+ expect(value.utc_offset).to eq(-7.hours)
114
114
  end
115
115
  end
116
116
  end
@@ -12,20 +12,20 @@ module TimelinessHelpers
12
12
  Timeliness::Definitions
13
13
  end
14
14
 
15
- def parse(*args)
16
- Timeliness::Parser.parse(*args)
15
+ def parse(value, type=nil, **args)
16
+ Timeliness::Parser.parse(value, type, **args)
17
17
  end
18
18
 
19
19
  def current_date(options={})
20
20
  Timeliness::Parser.send(:current_date, options)
21
21
  end
22
22
 
23
- def should_parse(*args)
24
- expect(Timeliness::Parser.parse(*args)).not_to be_nil
23
+ def should_parse(value, type=nil, **args)
24
+ expect(Timeliness::Parser.parse(value, type, **args)).not_to be_nil
25
25
  end
26
26
 
27
- def should_not_parse(*args)
28
- expect(Timeliness::Parser.parse(*args)).to be_nil
27
+ def should_not_parse(value, type=nil, **args)
28
+ expect(Timeliness::Parser.parse(value, type, **args)).to be_nil
29
29
  end
30
30
  end
31
31
 
@@ -38,4 +38,4 @@ RSpec.configure do |c|
38
38
  c.after do
39
39
  Timeliness.configuration = Timeliness::Configuration.new
40
40
  end
41
- end
41
+ end
data/timeliness.gemspec CHANGED
@@ -13,8 +13,6 @@ Gem::Specification.new do |s|
13
13
  s.description = %q{Fast date/time parser with customisable formats, timezone and I18n support.}
14
14
  s.license = "MIT"
15
15
 
16
- s.rubyforge_project = %q{timeliness}
17
-
18
16
  s.add_development_dependency 'activesupport', '>= 3.2'
19
17
  s.add_development_dependency 'tzinfo', '>= 0.3.31'
20
18
  s.add_development_dependency 'rspec', '~> 3.4'
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
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Meehan
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-23 00:00:00.000000000 Z
11
+ date: 2024-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -88,6 +88,7 @@ extra_rdoc_files:
88
88
  - README.rdoc
89
89
  - CHANGELOG.rdoc
90
90
  files:
91
+ - ".github/workflows/ci.yml"
91
92
  - ".travis.yml"
92
93
  - CHANGELOG.rdoc
93
94
  - LICENSE
@@ -116,7 +117,7 @@ homepage: http://github.com/adzap/timeliness
116
117
  licenses:
117
118
  - MIT
118
119
  metadata: {}
119
- post_install_message:
120
+ post_install_message:
120
121
  rdoc_options: []
121
122
  require_paths:
122
123
  - lib
@@ -131,9 +132,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
131
132
  - !ruby/object:Gem::Version
132
133
  version: '0'
133
134
  requirements: []
134
- rubyforge_project: timeliness
135
- rubygems_version: 2.7.6.2
136
- signing_key:
135
+ rubygems_version: 3.3.27
136
+ signing_key:
137
137
  specification_version: 4
138
138
  summary: Date/time parsing for the control freak.
139
139
  test_files: []