timeliness 0.4.4 → 0.5.0
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 +4 -4
- data/.github/workflows/ci.yml +23 -0
- data/.travis.yml +12 -9
- data/CHANGELOG.rdoc +11 -2
- data/LICENSE +1 -1
- data/README.rdoc +9 -9
- data/Rakefile +3 -2
- data/lib/timeliness/definitions.rb +3 -1
- data/lib/timeliness/format.rb +3 -2
- data/lib/timeliness/format_set.rb +7 -7
- data/lib/timeliness/helpers.rb +1 -1
- data/lib/timeliness/parser.rb +14 -7
- data/lib/timeliness/version.rb +1 -1
- data/spec/timeliness/format_spec.rb +20 -0
- data/spec/timeliness/parser_spec.rb +3 -3
- data/spec/timeliness_helper.rb +7 -7
- data/timeliness.gemspec +0 -2
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 23fc962cb22262464b617a95fc8690f5b94400ee5de69fc110166975bf59fd40
|
4
|
+
data.tar.gz: fead9e440fb74611873e5ab1a89747514072602d961f01a3c1d96c9d1b052610
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
- "
|
11
|
-
-
|
12
|
-
|
13
|
-
|
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
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:
|
4
|
-
* Bugs:
|
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}[
|
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}[
|
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,
|
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'
|
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
|
]
|
data/lib/timeliness/format.rb
CHANGED
@@ -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("^(
|
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
|
-
|
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
|
24
|
-
index + format.token_count
|
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
|
-
|
35
|
-
|
36
|
-
|
37
|
-
values =
|
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
|
-
|
44
|
+
@formats_hash.fetch(format_string) { Format.new(format_string).compile! }
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
data/lib/timeliness/helpers.rb
CHANGED
@@ -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
|
26
|
+
(month.length > 3 ? month_names : abbr_month_names).index { |str| month.casecmp?(str) }
|
27
27
|
end
|
28
28
|
|
29
29
|
def month_names
|
data/lib/timeliness/parser.rb
CHANGED
@@ -4,11 +4,14 @@ module Timeliness
|
|
4
4
|
|
5
5
|
class << self
|
6
6
|
|
7
|
-
def parse(value,
|
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
|
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).
|
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
|
99
|
-
Time.now.
|
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
|
111
|
-
time.
|
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
|
data/lib/timeliness/version.rb
CHANGED
@@ -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
|
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
|
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
|
113
|
+
expect(value.utc_offset).to eq(-7.hours)
|
114
114
|
end
|
115
115
|
end
|
116
116
|
end
|
data/spec/timeliness_helper.rb
CHANGED
@@ -12,20 +12,20 @@ module TimelinessHelpers
|
|
12
12
|
Timeliness::Definitions
|
13
13
|
end
|
14
14
|
|
15
|
-
def parse(
|
16
|
-
Timeliness::Parser.parse(
|
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(
|
24
|
-
expect(Timeliness::Parser.parse(
|
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(
|
28
|
-
expect(Timeliness::Parser.parse(
|
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
|
+
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:
|
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
|
-
|
135
|
-
|
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: []
|