timetwister 0.2.7 → 0.2.8
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 +5 -13
- data/.github/workflows/ruby.yml +35 -0
- data/.travis.yml +3 -3
- data/README.md +2 -2
- data/lib/timetwister/parser.rb +15 -37
- data/lib/timetwister/utilities.rb +29 -11
- data/lib/timetwister/version.rb +1 -1
- data/spec/dates_spec.rb +87 -4
- data/timetwister.gemspec +2 -3
- metadata +19 -33
checksums.yaml
CHANGED
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
|
|
5
|
-
data.tar.gz: !binary |-
|
|
6
|
-
YjcyNDQ2MDg0MTM2YzdiMDNhMjkwNmY3OWI3YmVmMThkNTk5NGMzNw==
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: ca0d0c30070a1b30680aed8c91ab6950f8b3673395546605f1dc1c0bb72954ea
|
|
4
|
+
data.tar.gz: cee49664ffebe37b764217e1cfd212c12b6e364928425a913598e3dc44eb6903
|
|
7
5
|
SHA512:
|
|
8
|
-
metadata.gz:
|
|
9
|
-
|
|
10
|
-
NjdkNGI3YzU2ZTU1MzA5Y2YzYjFhYmJlZTI5NzFkYjQzZDY1MWFlOTU3MGY1
|
|
11
|
-
OWM0NjAzNjJkNDIyMDdmMjA0YjE0YzcwYjczMWI3MGNiMzNlNTg=
|
|
12
|
-
data.tar.gz: !binary |-
|
|
13
|
-
NmMyOWYzYWY2NWJmZmQyYmM4NjliMTc5YWQ3N2E2NzhkNmQ1MDdlZTQxYTQ5
|
|
14
|
-
ZjIxNWZhNTExODg0MDRkMDVkNDAyNGI3MjRkMWIyMjlhYzdjMzg5ZWE5OTcz
|
|
15
|
-
NjgzZmMwMTY4MDVlYzNlNzE0YzcyYTNmYTUzNDVhODczNGQ5ZWM=
|
|
6
|
+
metadata.gz: 897f1be9853d0c9ebe3800519b507f346bb0c78c265fe2b4d42a0d75e148faf9ccc919fe1d0e14bdc9b73676f39ecdd5ceb156dfaf25904f4d62c0e7fb89bd29
|
|
7
|
+
data.tar.gz: 867c87500e0011732f9c863fff5bb03ee78080f42ad63755d541ed07bc6d72ed83e41c8f490e3323498ff82dd5421cbd989360be66b96520d0dba21b2a0cc1ba
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
|
2
|
+
# They are provided by a third-party and are governed by
|
|
3
|
+
# separate terms of service, privacy policy, and support
|
|
4
|
+
# documentation.
|
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
|
7
|
+
|
|
8
|
+
name: Ruby
|
|
9
|
+
|
|
10
|
+
on:
|
|
11
|
+
push:
|
|
12
|
+
branches: [ master ]
|
|
13
|
+
pull_request:
|
|
14
|
+
branches: [ master ]
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
test:
|
|
18
|
+
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
strategy:
|
|
21
|
+
matrix:
|
|
22
|
+
ruby-version: ['2.6', '2.7', '3.0']
|
|
23
|
+
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v2
|
|
26
|
+
- name: Set up Ruby
|
|
27
|
+
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
|
28
|
+
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
|
29
|
+
# uses: ruby/setup-ruby@v1
|
|
30
|
+
uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
|
|
31
|
+
with:
|
|
32
|
+
ruby-version: ${{ matrix.ruby-version }}
|
|
33
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
|
34
|
+
- name: Run tests
|
|
35
|
+
run: bundle exec rspec
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
[](https://travis-ci.org/alexduryee/timetwister)
|
|
2
2
|
[](https://coveralls.io/github/alexduryee/timetwister?branch=master)
|
|
3
3
|
|
|
4
4
|
# Timetwister
|
|
5
5
|
|
|
6
|
-
A
|
|
6
|
+
A DateTime wrapper with improved date format parsing and fewer surprises.
|
|
7
7
|
|
|
8
8
|
Developed by the New York Public Library to transform freetext date metadata into machine-readable data.
|
|
9
9
|
|
data/lib/timetwister/parser.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
|
|
3
|
-
require '
|
|
3
|
+
require 'date'
|
|
4
4
|
require 'timetwister/utilities'
|
|
5
5
|
|
|
6
6
|
class Parser
|
|
@@ -574,18 +574,7 @@ class Parser
|
|
|
574
574
|
proc = Proc.new do |string|
|
|
575
575
|
string.gsub!(/\?/,'')
|
|
576
576
|
|
|
577
|
-
|
|
578
|
-
# so we need to change them to month-year before
|
|
579
|
-
# parsing them.
|
|
580
|
-
|
|
581
|
-
if string.match(/^[0-9]/)
|
|
582
|
-
tmpyear = string.split(' ')[0]
|
|
583
|
-
string.gsub!(/^.+? /,'')
|
|
584
|
-
string << " "
|
|
585
|
-
string << tmpyear
|
|
586
|
-
end
|
|
587
|
-
|
|
588
|
-
datetime = Chronic.parse(string)
|
|
577
|
+
datetime = DateTime.parse(string)
|
|
589
578
|
if datetime
|
|
590
579
|
@dates[:date_start] = datetime.strftime('%Y-%m')
|
|
591
580
|
@dates[:index_dates] << datetime.strftime('%Y').to_i
|
|
@@ -614,14 +603,14 @@ class Parser
|
|
|
614
603
|
# if month-specific, modify datetimes to include all days of each month
|
|
615
604
|
if specificity == 'month'
|
|
616
605
|
month_date_start = datetime_start.strftime('%Y-%m')
|
|
617
|
-
datetime_start =
|
|
606
|
+
datetime_start = DateTime.parse(month_date_start + '-01')
|
|
618
607
|
month_date_end = datetime_end.strftime('%Y-%m')
|
|
619
608
|
month_date_end_parts = month_date_end.split('-')
|
|
620
609
|
|
|
621
610
|
month_date_end_last = Utilities.days_in_month(month_date_end_parts[1],month_date_end_parts[0]).to_s
|
|
622
611
|
month_date_full = month_date_end + "-#{month_date_end_last}"
|
|
623
612
|
|
|
624
|
-
datetime_end =
|
|
613
|
+
datetime_end = DateTime.parse(month_date_full)
|
|
625
614
|
end
|
|
626
615
|
|
|
627
616
|
if datetime_start && datetime_end
|
|
@@ -699,14 +688,12 @@ class Parser
|
|
|
699
688
|
first_month = string.match(@regex_tokens[:named_month]).to_s
|
|
700
689
|
last_month = string.match(@regex_tokens[:named_month] + '$').to_s
|
|
701
690
|
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
date_string_first = first_month.delete('.') + ' 1,' + year
|
|
705
|
-
datetime_first = Chronic.parse(date_string_first)
|
|
691
|
+
date_string_first = first_month + ' 1,' + year
|
|
692
|
+
datetime_first = DateTime.parse(date_string_first)
|
|
706
693
|
if !last_month.empty?
|
|
707
694
|
@dates[:date_start] = datetime_first.strftime('%Y-%m')
|
|
708
695
|
date_string_last = last_month + ' ' + year
|
|
709
|
-
datetime_last =
|
|
696
|
+
datetime_last = DateTime.parse(date_string_last)
|
|
710
697
|
@dates[:date_end] = datetime_last.strftime('%Y-%m')
|
|
711
698
|
end
|
|
712
699
|
@dates[:inclusive_range] = true
|
|
@@ -729,7 +716,6 @@ class Parser
|
|
|
729
716
|
end
|
|
730
717
|
|
|
731
718
|
dates.each { |d| d.strip! }
|
|
732
|
-
|
|
733
719
|
if dates.length == 2
|
|
734
720
|
if dates[0].match(/[A-Za-z]/)
|
|
735
721
|
datetime_start = full_date_single_to_datetime(dates[0] + "-01")
|
|
@@ -773,20 +759,12 @@ class Parser
|
|
|
773
759
|
d << " "
|
|
774
760
|
d << year
|
|
775
761
|
end
|
|
776
|
-
|
|
777
|
-
# Chronic seemed to choke with YYYY-MM-DD dates
|
|
778
|
-
# so we'll flip it to MM-DD-YYYY
|
|
779
|
-
if d.match("^" + year)
|
|
780
|
-
d.gsub!(year + " ","")
|
|
781
|
-
d << " "
|
|
782
|
-
d << year
|
|
783
|
-
end
|
|
784
762
|
}
|
|
785
763
|
|
|
786
764
|
# change our strings to datetime objects
|
|
787
765
|
# and send them to be processed elsewhere
|
|
788
|
-
datetime_start =
|
|
789
|
-
datetime_end =
|
|
766
|
+
datetime_start = DateTime.parse(dates[0])
|
|
767
|
+
datetime_end = DateTime.parse(dates[1])
|
|
790
768
|
process_date_range(datetime_start, datetime_end)
|
|
791
769
|
@dates[:inclusive_range] = true
|
|
792
770
|
end
|
|
@@ -818,7 +796,7 @@ class Parser
|
|
|
818
796
|
month_date_end_last = Utilities.days_in_month(month_date_end_parts[1],month_date_end_parts[0]).to_s
|
|
819
797
|
month_date_full = month_date_end + "-#{month_date_end_last}"
|
|
820
798
|
|
|
821
|
-
datetime_end =
|
|
799
|
+
datetime_end = DateTime.parse(month_date_full)
|
|
822
800
|
else
|
|
823
801
|
datetime_start = full_date_single_to_datetime(dates[0] + "-01")
|
|
824
802
|
if datetime_start && datetime_end
|
|
@@ -870,13 +848,13 @@ class Parser
|
|
|
870
848
|
day = nil
|
|
871
849
|
end
|
|
872
850
|
|
|
873
|
-
new_string.gsub!(/[\.\,\s]+/,'')
|
|
851
|
+
new_string.gsub!(/[\.\,\s\-]+/,'')
|
|
874
852
|
|
|
875
853
|
month = new_string.clone
|
|
876
854
|
parse_string = month
|
|
877
855
|
parse_string += day ? " #{day}, #{year}" : " #{year}"
|
|
878
856
|
end
|
|
879
|
-
datetime =
|
|
857
|
+
datetime = DateTime.parse(parse_string)
|
|
880
858
|
end
|
|
881
859
|
|
|
882
860
|
|
|
@@ -926,11 +904,11 @@ class Parser
|
|
|
926
904
|
# generates datetime from ISO8601-formatted date
|
|
927
905
|
def self.iso8601_datetime(iso_8601_date)
|
|
928
906
|
if iso_8601_date.match(/^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$/)
|
|
929
|
-
|
|
907
|
+
DateTime.parse(iso_8601_date)
|
|
930
908
|
elsif iso_8601_date.match(/^[0-9]{4}\-[0-9]{2}$/)
|
|
931
|
-
|
|
909
|
+
DateTime.parse(iso_8601_date + '-01')
|
|
932
910
|
else
|
|
933
|
-
|
|
911
|
+
DateTime.parse(iso_8601_date + '-01-01')
|
|
934
912
|
end
|
|
935
913
|
end
|
|
936
914
|
|
|
@@ -4,10 +4,10 @@ class Utilities
|
|
|
4
4
|
|
|
5
5
|
# walk through a hash and transforms all ints to strings
|
|
6
6
|
# input: a hash
|
|
7
|
-
# output: same hash, but with all
|
|
7
|
+
# output: same hash, but with all Integers converted to strings
|
|
8
8
|
def self.stringify_values(hash)
|
|
9
9
|
hash.each do |k,v|
|
|
10
|
-
if v.is_a?(
|
|
10
|
+
if v.is_a?(Integer)
|
|
11
11
|
hash[k] = v.to_s
|
|
12
12
|
end
|
|
13
13
|
end
|
|
@@ -135,15 +135,15 @@ class Utilities
|
|
|
135
135
|
# italian
|
|
136
136
|
'gennaio' => 'January',
|
|
137
137
|
'febbraio' => 'February',
|
|
138
|
-
|
|
138
|
+
# redundant date removed
|
|
139
139
|
'aprile' => 'April',
|
|
140
140
|
'maggio' => 'May',
|
|
141
141
|
'giugno' => 'June',
|
|
142
142
|
'luglio' => 'July',
|
|
143
|
-
|
|
143
|
+
# redundant date removed
|
|
144
144
|
'settembre' => 'September',
|
|
145
145
|
'ottobre' => 'October',
|
|
146
|
-
|
|
146
|
+
# redundant date removed
|
|
147
147
|
'dicembre' => 'December',
|
|
148
148
|
|
|
149
149
|
# german
|
|
@@ -151,7 +151,7 @@ class Utilities
|
|
|
151
151
|
'februar[^y]' => 'February',
|
|
152
152
|
'märz' => 'March',
|
|
153
153
|
'april' => 'April',
|
|
154
|
-
|
|
154
|
+
# redundant date removed
|
|
155
155
|
'juni' => 'June',
|
|
156
156
|
'juli' => 'July',
|
|
157
157
|
'august' => 'August',
|
|
@@ -236,11 +236,7 @@ class Utilities
|
|
|
236
236
|
]
|
|
237
237
|
|
|
238
238
|
# transform seasons to months
|
|
239
|
-
string
|
|
240
|
-
string.gsub!(/[Ss]pring/, " March 20 - June 21 ")
|
|
241
|
-
string.gsub!(/[Ss]ummer/, " June 21 - September 23 ")
|
|
242
|
-
string.gsub!(/[Aa]utumn/, " September 23 - December 22 ")
|
|
243
|
-
string.gsub!(/[Ff]all/, " September 23 - December 22 ")
|
|
239
|
+
string = replace_seasons(string)
|
|
244
240
|
|
|
245
241
|
# remove days of the week
|
|
246
242
|
dow = [/[Ss]unday,?\s+/, /[Mm]onday,?\s+/, /[Tt]uesday,?\s+/, /[Ww]ednesday,?\s+/, /[Tt]hursday,?\s+/, /[Ff]riday,?\s+/, /[Ss]aturday,?\s+/]
|
|
@@ -258,6 +254,28 @@ class Utilities
|
|
|
258
254
|
return string
|
|
259
255
|
end
|
|
260
256
|
|
|
257
|
+
def self.replace_seasons(string)
|
|
258
|
+
seasons = { 'win[^\s]*' => ['January 1', 'March 20'],
|
|
259
|
+
'spr[^\s]*' => ['March 20', 'June 21'],
|
|
260
|
+
'sum[^\s]*' => ['June 21', 'September 23'],
|
|
261
|
+
'aut[^\s]*' => ['September 23', 'December 31'],
|
|
262
|
+
'fal[^\s]*' => ['September 23', 'December 31']}
|
|
263
|
+
|
|
264
|
+
# if we're working with a range, we need to be a little careful, so that we don't create sub-ranges in a string
|
|
265
|
+
is_range = string.match(/[^-]+?-[^-]+?/)
|
|
266
|
+
|
|
267
|
+
seasons.each do |season, dates|
|
|
268
|
+
regex = Regexp.new(season, Regexp::IGNORECASE)
|
|
269
|
+
|
|
270
|
+
# is the season the beginning or the end of a range?
|
|
271
|
+
new_date = (is_range ? (string.match(Regexp.new(season + '.+?-', Regexp::IGNORECASE)) ? dates[0] : dates[1]) : dates.join(' - '))
|
|
272
|
+
|
|
273
|
+
string = string.gsub(regex, new_date)
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
return string
|
|
277
|
+
end
|
|
278
|
+
|
|
261
279
|
# Removes the first 4-digit number found in the string and returns it
|
|
262
280
|
def self.extract_year(string)
|
|
263
281
|
year = string.match(/\d{4}/).to_s
|
data/lib/timetwister/version.rb
CHANGED
data/spec/dates_spec.rb
CHANGED
|
@@ -195,7 +195,7 @@ describe Timetwister do
|
|
|
195
195
|
end
|
|
196
196
|
|
|
197
197
|
it "parses month ranges within one year" do
|
|
198
|
-
forms = ["July-September 1776", "1776 July-September"]
|
|
198
|
+
forms = ["July-September 1776", "1776 July-September", "1776 Jul.-Sept."]
|
|
199
199
|
forms.each do |f|
|
|
200
200
|
date = Timetwister.parse(f)
|
|
201
201
|
expect(date[0][:date_start]).to eq("1776-07")
|
|
@@ -344,7 +344,7 @@ describe Timetwister do
|
|
|
344
344
|
end
|
|
345
345
|
end
|
|
346
346
|
|
|
347
|
-
it "parses seasons" do
|
|
347
|
+
it "parses single seasons" do
|
|
348
348
|
date = Timetwister.parse("Winter 1776")
|
|
349
349
|
expect(date[0][:date_start]).to eq("1776-01-01")
|
|
350
350
|
expect(date[0][:date_start_full]).to eq("1776-01-01")
|
|
@@ -354,6 +354,15 @@ describe Timetwister do
|
|
|
354
354
|
expect(date[0][:index_dates]).to eq([1776])
|
|
355
355
|
expect(date[0][:test_data]).to eq("310")
|
|
356
356
|
|
|
357
|
+
date = Timetwister.parse("win. 1776")
|
|
358
|
+
expect(date[0][:date_start]).to eq("1776-01-01")
|
|
359
|
+
expect(date[0][:date_start_full]).to eq("1776-01-01")
|
|
360
|
+
expect(date[0][:date_end]).to eq("1776-03-20")
|
|
361
|
+
expect(date[0][:date_end_full]).to eq("1776-03-20")
|
|
362
|
+
expect(date[0][:inclusive_range]).to eq(true)
|
|
363
|
+
expect(date[0][:index_dates]).to eq([1776])
|
|
364
|
+
expect(date[0][:test_data]).to eq("310")
|
|
365
|
+
|
|
357
366
|
date = Timetwister.parse("1776 Spring")
|
|
358
367
|
expect(date[0][:date_start]).to eq("1776-03-20")
|
|
359
368
|
expect(date[0][:date_start_full]).to eq("1776-03-20")
|
|
@@ -363,6 +372,15 @@ describe Timetwister do
|
|
|
363
372
|
expect(date[0][:index_dates]).to eq([1776])
|
|
364
373
|
expect(date[0][:test_data]).to eq("310")
|
|
365
374
|
|
|
375
|
+
date = Timetwister.parse("1776 Spr")
|
|
376
|
+
expect(date[0][:date_start]).to eq("1776-03-20")
|
|
377
|
+
expect(date[0][:date_start_full]).to eq("1776-03-20")
|
|
378
|
+
expect(date[0][:date_end]).to eq("1776-06-21")
|
|
379
|
+
expect(date[0][:date_end_full]).to eq("1776-06-21")
|
|
380
|
+
expect(date[0][:inclusive_range]).to eq(true)
|
|
381
|
+
expect(date[0][:index_dates]).to eq([1776])
|
|
382
|
+
expect(date[0][:test_data]).to eq("310")
|
|
383
|
+
|
|
366
384
|
date = Timetwister.parse("1776 Summer")
|
|
367
385
|
expect(date[0][:date_start]).to eq("1776-06-21")
|
|
368
386
|
expect(date[0][:date_start_full]).to eq("1776-06-21")
|
|
@@ -372,14 +390,61 @@ describe Timetwister do
|
|
|
372
390
|
expect(date[0][:index_dates]).to eq([1776])
|
|
373
391
|
expect(date[0][:test_data]).to eq("310")
|
|
374
392
|
|
|
393
|
+
date = Timetwister.parse("1776 Summ")
|
|
394
|
+
expect(date[0][:date_start]).to eq("1776-06-21")
|
|
395
|
+
expect(date[0][:date_start_full]).to eq("1776-06-21")
|
|
396
|
+
expect(date[0][:date_end]).to eq("1776-09-23")
|
|
397
|
+
expect(date[0][:date_end_full]).to eq("1776-09-23")
|
|
398
|
+
expect(date[0][:inclusive_range]).to eq(true)
|
|
399
|
+
expect(date[0][:index_dates]).to eq([1776])
|
|
400
|
+
expect(date[0][:test_data]).to eq("310")
|
|
401
|
+
|
|
375
402
|
date = Timetwister.parse("Fall 1776")
|
|
376
403
|
expect(date[0][:date_start]).to eq("1776-09-23")
|
|
377
404
|
expect(date[0][:date_start_full]).to eq("1776-09-23")
|
|
378
|
-
expect(date[0][:date_end]).to eq("1776-12-
|
|
379
|
-
expect(date[0][:date_end_full]).to eq("1776-12-
|
|
405
|
+
expect(date[0][:date_end]).to eq("1776-12-31")
|
|
406
|
+
expect(date[0][:date_end_full]).to eq("1776-12-31")
|
|
407
|
+
expect(date[0][:inclusive_range]).to eq(true)
|
|
408
|
+
expect(date[0][:index_dates]).to eq([1776])
|
|
409
|
+
expect(date[0][:test_data]).to eq("310")
|
|
410
|
+
|
|
411
|
+
date = Timetwister.parse("Autumn 1776")
|
|
412
|
+
expect(date[0][:date_start]).to eq("1776-09-23")
|
|
413
|
+
expect(date[0][:date_start_full]).to eq("1776-09-23")
|
|
414
|
+
expect(date[0][:date_end]).to eq("1776-12-31")
|
|
415
|
+
expect(date[0][:date_end_full]).to eq("1776-12-31")
|
|
380
416
|
expect(date[0][:inclusive_range]).to eq(true)
|
|
381
417
|
expect(date[0][:index_dates]).to eq([1776])
|
|
382
418
|
expect(date[0][:test_data]).to eq("310")
|
|
419
|
+
|
|
420
|
+
date = Timetwister.parse("Aut. 1776")
|
|
421
|
+
expect(date[0][:date_start]).to eq("1776-09-23")
|
|
422
|
+
expect(date[0][:date_start_full]).to eq("1776-09-23")
|
|
423
|
+
expect(date[0][:date_end]).to eq("1776-12-31")
|
|
424
|
+
expect(date[0][:date_end_full]).to eq("1776-12-31")
|
|
425
|
+
expect(date[0][:inclusive_range]).to eq(true)
|
|
426
|
+
expect(date[0][:index_dates]).to eq([1776])
|
|
427
|
+
expect(date[0][:test_data]).to eq("310")
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
it "parses ranges of seasons" do
|
|
431
|
+
date = Timetwister.parse("Winter 1776 - Spring 1777")
|
|
432
|
+
expect(date[0][:date_start]).to eq("1776-01-01")
|
|
433
|
+
expect(date[0][:date_start_full]).to eq("1776-01-01")
|
|
434
|
+
expect(date[0][:date_end]).to eq("1777-06-21")
|
|
435
|
+
expect(date[0][:date_end_full]).to eq("1777-06-21")
|
|
436
|
+
expect(date[0][:inclusive_range]).to eq(true)
|
|
437
|
+
expect(date[0][:index_dates]).to eq([1776, 1777])
|
|
438
|
+
expect(date[0][:test_data]).to eq("80")
|
|
439
|
+
|
|
440
|
+
date = Timetwister.parse("1777 Spring - 1778 Summer")
|
|
441
|
+
expect(date[0][:date_start]).to eq("1777-03-20")
|
|
442
|
+
expect(date[0][:date_start_full]).to eq("1777-03-20")
|
|
443
|
+
expect(date[0][:date_end]).to eq("1778-09-23")
|
|
444
|
+
expect(date[0][:date_end_full]).to eq("1778-09-23")
|
|
445
|
+
expect(date[0][:inclusive_range]).to eq(true)
|
|
446
|
+
expect(date[0][:index_dates]).to eq([1777, 1778])
|
|
447
|
+
expect(date[0][:test_data]).to eq("80")
|
|
383
448
|
end
|
|
384
449
|
|
|
385
450
|
it "parses dates with punctuation" do
|
|
@@ -528,6 +593,24 @@ describe Timetwister do
|
|
|
528
593
|
expect(date[2][:test_data]).to eq("70")
|
|
529
594
|
end
|
|
530
595
|
|
|
596
|
+
it "parses lists of ISO 8601 dates" do
|
|
597
|
+
date = Timetwister.parse("1777 April 30, 1777 June 4")
|
|
598
|
+
expect(date[0][:date_start]).to eq("1777-04-30")
|
|
599
|
+
expect(date[0][:date_start_full]).to eq("1777-04-30")
|
|
600
|
+
expect(date[0][:date_end]).to eq("1777-04-30")
|
|
601
|
+
expect(date[0][:date_end_full]).to eq("1777-04-30")
|
|
602
|
+
expect(date[0][:index_dates]).to eq([1777])
|
|
603
|
+
expect(date[0][:test_data]).to eq("200")
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
expect(date[1][:date_start]).to eq("1777-06-04")
|
|
607
|
+
expect(date[1][:date_start_full]).to eq("1777-06-04")
|
|
608
|
+
expect(date[1][:date_end]).to eq("1777-06-04")
|
|
609
|
+
expect(date[1][:date_end_full]).to eq("1777-06-04")
|
|
610
|
+
expect(date[1][:index_dates]).to eq([1777])
|
|
611
|
+
expect(date[1][:test_data]).to eq("200")
|
|
612
|
+
end
|
|
613
|
+
|
|
531
614
|
it "parses lists of mixed date types" do
|
|
532
615
|
date = Timetwister.parse("July 1776 - August 1789, 1812 - 1820, 1900")
|
|
533
616
|
expect(date[0][:date_start]).to eq("1776-07")
|
data/timetwister.gemspec
CHANGED
|
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
|
|
|
8
8
|
spec.version = Timetwister::VERSION
|
|
9
9
|
spec.authors = ["Alex Duryee"]
|
|
10
10
|
spec.email = ["alexanderduryee@nypl.org"]
|
|
11
|
-
spec.summary = "
|
|
11
|
+
spec.summary = "DateTime wrapper to handle common date formats"
|
|
12
12
|
spec.homepage = "http://github.com/alexduryee/timetwister"
|
|
13
13
|
spec.license = "MIT"
|
|
14
14
|
|
|
@@ -18,7 +18,6 @@ Gem::Specification.new do |spec|
|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
19
|
spec.require_paths = ["lib"]
|
|
20
20
|
|
|
21
|
-
spec.add_development_dependency "bundler"
|
|
21
|
+
spec.add_development_dependency "bundler"
|
|
22
22
|
spec.add_development_dependency "rake", "~> 10.0"
|
|
23
|
-
spec.add_runtime_dependency "chronic", "~> 0.10.2"
|
|
24
23
|
end
|
metadata
CHANGED
|
@@ -1,58 +1,44 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: timetwister
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alex Duryee
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-06-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- -
|
|
17
|
+
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
19
|
+
version: '0'
|
|
20
20
|
type: :development
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- -
|
|
24
|
+
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
26
|
+
version: '0'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: rake
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- - ~>
|
|
31
|
+
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
33
|
version: '10.0'
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
|
-
- - ~>
|
|
38
|
+
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '10.0'
|
|
41
|
-
|
|
42
|
-
name: chronic
|
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
|
44
|
-
requirements:
|
|
45
|
-
- - ~>
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: 0.10.2
|
|
48
|
-
type: :runtime
|
|
49
|
-
prerelease: false
|
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
-
requirements:
|
|
52
|
-
- - ~>
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
version: 0.10.2
|
|
55
|
-
description:
|
|
41
|
+
description:
|
|
56
42
|
email:
|
|
57
43
|
- alexanderduryee@nypl.org
|
|
58
44
|
executables:
|
|
@@ -60,8 +46,9 @@ executables:
|
|
|
60
46
|
extensions: []
|
|
61
47
|
extra_rdoc_files: []
|
|
62
48
|
files:
|
|
63
|
-
- .
|
|
64
|
-
- .
|
|
49
|
+
- ".github/workflows/ruby.yml"
|
|
50
|
+
- ".gitignore"
|
|
51
|
+
- ".travis.yml"
|
|
65
52
|
- Gemfile
|
|
66
53
|
- LICENSE.txt
|
|
67
54
|
- README.md
|
|
@@ -78,26 +65,25 @@ homepage: http://github.com/alexduryee/timetwister
|
|
|
78
65
|
licenses:
|
|
79
66
|
- MIT
|
|
80
67
|
metadata: {}
|
|
81
|
-
post_install_message:
|
|
68
|
+
post_install_message:
|
|
82
69
|
rdoc_options: []
|
|
83
70
|
require_paths:
|
|
84
71
|
- lib
|
|
85
72
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
86
73
|
requirements:
|
|
87
|
-
- -
|
|
74
|
+
- - ">="
|
|
88
75
|
- !ruby/object:Gem::Version
|
|
89
76
|
version: '0'
|
|
90
77
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
78
|
requirements:
|
|
92
|
-
- -
|
|
79
|
+
- - ">="
|
|
93
80
|
- !ruby/object:Gem::Version
|
|
94
81
|
version: '0'
|
|
95
82
|
requirements: []
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
signing_key:
|
|
83
|
+
rubygems_version: 3.2.22
|
|
84
|
+
signing_key:
|
|
99
85
|
specification_version: 4
|
|
100
|
-
summary:
|
|
86
|
+
summary: DateTime wrapper to handle common date formats
|
|
101
87
|
test_files:
|
|
102
88
|
- spec/dates_spec.rb
|
|
103
89
|
- spec/spec_helper.rb
|