parse_date 0.4.2 → 0.4.4
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/.circleci/config.yml +11 -0
- data/.github/pull_request_template.md +9 -1
- data/.gitignore +0 -1
- data/.rubocop.yml +376 -7
- data/.rubocop_todo.yml +11 -28
- data/Gemfile.lock +123 -0
- data/README.md +2 -3
- data/lib/parse_date/int_from_string.rb +121 -67
- data/lib/parse_date/version.rb +1 -1
- data/lib/parse_date.rb +5 -18
- data/parse_date.gemspec +9 -4
- metadata +81 -12
- data/.travis.yml +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f613d991c15686a1b4ba6306fe8f0260a1b0e6159b868cba4f6894be3369df2c
|
4
|
+
data.tar.gz: 6c39918199136340604ab472ecc8c3898a13b88aea1f2d2bbd19ea7090a5bfec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1dece18d4386a1701e57097c016dc8910eee7d9c447ae365ccdd27bea973fed67d377d154e42f5cb4c91bdc6c187a19c63d491f2ee7b8eeb30ac6fe62963ca91
|
7
|
+
data.tar.gz: 7e4b96fce7029cf4c1918c6cd6614d26e170e160ba72e94ee8fc8f1402a780000469c965249f8c69be30882161f93125aa44e592c0dbec4f49c7040a2c4a8ed3
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,7 +1,26 @@
|
|
1
|
+
plugins:
|
2
|
+
- rubocop-capybara
|
3
|
+
- rubocop-factory_bot
|
4
|
+
- rubocop-rake
|
5
|
+
- rubocop-rspec
|
6
|
+
- rubocop-rspec_rails
|
7
|
+
|
1
8
|
inherit_from: .rubocop_todo.yml
|
2
9
|
|
3
10
|
AllCops:
|
4
|
-
TargetRubyVersion:
|
11
|
+
TargetRubyVersion: 3.1
|
12
|
+
SuggestExtensions: false
|
13
|
+
DisplayCopNames: true
|
14
|
+
Include:
|
15
|
+
- './Rakefile' # rake only
|
16
|
+
- '**/*.rb'
|
17
|
+
Exclude:
|
18
|
+
# autogenerated files (that we don't change) should go here
|
19
|
+
- 'bin/**/*'
|
20
|
+
- 'spec/spec_helper.rb'
|
21
|
+
|
22
|
+
Gemspec/RequiredRubyVersion:
|
23
|
+
Enabled: false
|
5
24
|
|
6
25
|
Layout/EmptyLinesAroundClassBody:
|
7
26
|
Enabled: false
|
@@ -9,23 +28,34 @@ Layout/EmptyLinesAroundClassBody:
|
|
9
28
|
Layout/EmptyLinesAroundModuleBody:
|
10
29
|
Enabled: false
|
11
30
|
|
31
|
+
Layout/LineLength:
|
32
|
+
Exclude:
|
33
|
+
- parse_date.gemspec
|
34
|
+
|
35
|
+
Lint/MixedRegexpCaptureTypes:
|
36
|
+
Enabled: false
|
37
|
+
|
12
38
|
Metrics/BlockLength:
|
13
39
|
Exclude:
|
14
40
|
- spec/**/*
|
15
41
|
|
16
|
-
Metrics/LineLength:
|
17
|
-
Max: 120
|
18
|
-
|
19
42
|
Metrics/MethodLength:
|
20
43
|
Max: 15
|
21
|
-
ExcludedMethods:
|
22
|
-
- earliest_year
|
23
|
-
- latest_year
|
24
44
|
|
25
45
|
Metrics/ModuleLength:
|
26
46
|
Exclude:
|
27
47
|
- lib/parse_date/int_from_string.rb
|
28
48
|
|
49
|
+
RSpec/MultipleMemoizedHelpers:
|
50
|
+
Enabled: false
|
51
|
+
|
52
|
+
RSpec/NestedGroups:
|
53
|
+
Max: 4 # default: 3
|
54
|
+
|
55
|
+
Style/Documentation:
|
56
|
+
Exclude:
|
57
|
+
- lib/parse_date.rb
|
58
|
+
|
29
59
|
Style/NumericLiterals:
|
30
60
|
Enabled: false
|
31
61
|
|
@@ -42,3 +72,342 @@ Style/WordArray:
|
|
42
72
|
|
43
73
|
Style/YodaCondition:
|
44
74
|
Enabled: false
|
75
|
+
|
76
|
+
Layout/SpaceBeforeBrackets: # (new in 1.7)
|
77
|
+
Enabled: true
|
78
|
+
Lint/AmbiguousAssignment: # (new in 1.7)
|
79
|
+
Enabled: true
|
80
|
+
Lint/DeprecatedConstants: # (new in 1.8)
|
81
|
+
Enabled: true
|
82
|
+
Lint/DuplicateBranch: # (new in 1.3)
|
83
|
+
Enabled: true
|
84
|
+
Lint/DuplicateRegexpCharacterClassElement: # (new in 1.1)
|
85
|
+
Enabled: true
|
86
|
+
Lint/EmptyBlock: # (new in 1.1)
|
87
|
+
Enabled: true
|
88
|
+
Lint/EmptyClass: # (new in 1.3)
|
89
|
+
Enabled: true
|
90
|
+
Lint/LambdaWithoutLiteralBlock: # (new in 1.8)
|
91
|
+
Enabled: true
|
92
|
+
Lint/NoReturnInBeginEndBlocks: # (new in 1.2)
|
93
|
+
Enabled: true
|
94
|
+
Lint/NumberedParameterAssignment: # (new in 1.9)
|
95
|
+
Enabled: true
|
96
|
+
Lint/OrAssignmentToConstant: # (new in 1.9)
|
97
|
+
Enabled: true
|
98
|
+
Lint/RedundantDirGlobSort: # (new in 1.8)
|
99
|
+
Enabled: true
|
100
|
+
Lint/SymbolConversion: # (new in 1.9)
|
101
|
+
Enabled: true
|
102
|
+
Lint/ToEnumArguments: # (new in 1.1)
|
103
|
+
Enabled: true
|
104
|
+
Lint/TripleQuotes: # (new in 1.9)
|
105
|
+
Enabled: true
|
106
|
+
Lint/UnexpectedBlockArity: # (new in 1.5)
|
107
|
+
Enabled: true
|
108
|
+
Lint/UnmodifiedReduceAccumulator: # (new in 1.1)
|
109
|
+
Enabled: true
|
110
|
+
Style/ArgumentsForwarding: # (new in 1.1)
|
111
|
+
Enabled: true
|
112
|
+
Style/CollectionCompact: # (new in 1.2)
|
113
|
+
Enabled: true
|
114
|
+
Style/DocumentDynamicEvalDefinition: # (new in 1.1)
|
115
|
+
Enabled: true
|
116
|
+
Style/EndlessMethod: # (new in 1.8)
|
117
|
+
Enabled: true
|
118
|
+
Style/HashConversion: # (new in 1.10)
|
119
|
+
Enabled: true
|
120
|
+
Style/HashExcept: # (new in 1.7)
|
121
|
+
Enabled: true
|
122
|
+
Style/IfWithBooleanLiteralBranches: # (new in 1.9)
|
123
|
+
Enabled: true
|
124
|
+
Style/NegatedIfElseCondition: # (new in 1.2)
|
125
|
+
Enabled: true
|
126
|
+
Style/NilLambda: # (new in 1.3)
|
127
|
+
Enabled: true
|
128
|
+
Style/RedundantArgument: # (new in 1.4)
|
129
|
+
Enabled: true
|
130
|
+
Style/StringChars: # (new in 1.12)
|
131
|
+
Enabled: true
|
132
|
+
Style/SwapValues: # (new in 1.1)
|
133
|
+
Enabled: true
|
134
|
+
Gemspec/DeprecatedAttributeAssignment: # new in 1.30
|
135
|
+
Enabled: true
|
136
|
+
Gemspec/RequireMFA: # new in 1.23
|
137
|
+
Enabled: true
|
138
|
+
Layout/LineContinuationLeadingSpace: # new in 1.31
|
139
|
+
Enabled: true
|
140
|
+
Layout/LineContinuationSpacing: # new in 1.31
|
141
|
+
Enabled: true
|
142
|
+
Layout/LineEndStringConcatenationIndentation: # new in 1.18
|
143
|
+
Enabled: true
|
144
|
+
Lint/AmbiguousOperatorPrecedence: # new in 1.21
|
145
|
+
Enabled: true
|
146
|
+
Lint/AmbiguousRange: # new in 1.19
|
147
|
+
Enabled: true
|
148
|
+
Lint/ConstantOverwrittenInRescue: # new in 1.31
|
149
|
+
Enabled: true
|
150
|
+
Lint/EmptyInPattern: # new in 1.16
|
151
|
+
Enabled: true
|
152
|
+
Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21
|
153
|
+
Enabled: true
|
154
|
+
Lint/NonAtomicFileOperation: # new in 1.31
|
155
|
+
Enabled: true
|
156
|
+
Lint/RefinementImportMethods: # new in 1.27
|
157
|
+
Enabled: true
|
158
|
+
Lint/RequireRelativeSelfPath: # new in 1.22
|
159
|
+
Enabled: true
|
160
|
+
Lint/UselessRuby2Keywords: # new in 1.23
|
161
|
+
Enabled: true
|
162
|
+
Naming/BlockForwarding: # new in 1.24
|
163
|
+
Enabled: true
|
164
|
+
Security/CompoundHash: # new in 1.28
|
165
|
+
Enabled: true
|
166
|
+
Security/IoMethods: # new in 1.22
|
167
|
+
Enabled: true
|
168
|
+
Style/EnvHome: # new in 1.29
|
169
|
+
Enabled: true
|
170
|
+
Style/FetchEnvVar: # new in 1.28
|
171
|
+
Enabled: true
|
172
|
+
Style/FileRead: # new in 1.24
|
173
|
+
Enabled: true
|
174
|
+
Style/FileWrite: # new in 1.24
|
175
|
+
Enabled: true
|
176
|
+
Style/InPatternThen: # new in 1.16
|
177
|
+
Enabled: true
|
178
|
+
Style/MapCompactWithConditionalBlock: # new in 1.30
|
179
|
+
Enabled: true
|
180
|
+
Style/MapToHash: # new in 1.24
|
181
|
+
Enabled: true
|
182
|
+
Style/MultilineInPatternThen: # new in 1.16
|
183
|
+
Enabled: true
|
184
|
+
Style/NestedFileDirname: # new in 1.26
|
185
|
+
Enabled: true
|
186
|
+
Style/NumberedParameters: # new in 1.22
|
187
|
+
Enabled: true
|
188
|
+
Style/NumberedParametersLimit: # new in 1.22
|
189
|
+
Enabled: true
|
190
|
+
Style/ObjectThen: # new in 1.28
|
191
|
+
Enabled: true
|
192
|
+
Style/OpenStructUse: # new in 1.23
|
193
|
+
Enabled: true
|
194
|
+
Style/QuotedSymbols: # new in 1.16
|
195
|
+
Enabled: true
|
196
|
+
Style/RedundantInitialize: # new in 1.27
|
197
|
+
Enabled: true
|
198
|
+
Style/RedundantSelfAssignmentBranch: # new in 1.19
|
199
|
+
Enabled: true
|
200
|
+
Style/SelectByRegexp: # new in 1.22
|
201
|
+
Enabled: true
|
202
|
+
|
203
|
+
Lint/RequireRangeParentheses: # new in 1.32
|
204
|
+
Enabled: true
|
205
|
+
Style/EmptyHeredoc: # new in 1.32
|
206
|
+
Enabled: true
|
207
|
+
Style/MagicCommentFormat: # new in 1.35
|
208
|
+
Enabled: true
|
209
|
+
RSpec/BeEq: # new in 2.9.0
|
210
|
+
Enabled: true
|
211
|
+
RSpec/BeNil: # new in 2.9.0
|
212
|
+
Enabled: true
|
213
|
+
RSpec/ChangeByZero: # new in 2.11
|
214
|
+
Enabled: true
|
215
|
+
RSpec/ClassCheck: # new in 2.13
|
216
|
+
Enabled: true
|
217
|
+
RSpec/ExcessiveDocstringSpacing: # new in 2.5
|
218
|
+
Enabled: true
|
219
|
+
RSpec/IdenticalEqualityAssertion: # new in 2.4
|
220
|
+
Enabled: true
|
221
|
+
RSpec/NoExpectationExample: # new in 2.13
|
222
|
+
Enabled: true
|
223
|
+
RSpec/SubjectDeclaration: # new in 2.5
|
224
|
+
Enabled: true
|
225
|
+
RSpec/VerifiedDoubleReference: # new in 2.10.0
|
226
|
+
Enabled: true
|
227
|
+
Capybara/SpecificFinders: # new in 2.13
|
228
|
+
Enabled: true
|
229
|
+
Capybara/SpecificMatcher: # new in 2.12
|
230
|
+
Enabled: true
|
231
|
+
FactoryBot/SyntaxMethods: # new in 2.7
|
232
|
+
Enabled: true
|
233
|
+
RSpecRails/AvoidSetupHook: # new in 2.4
|
234
|
+
Enabled: true
|
235
|
+
RSpecRails/HaveHttpStatus: # new in 2.12
|
236
|
+
Enabled: true
|
237
|
+
|
238
|
+
Gemspec/AddRuntimeDependency: # new in 1.65
|
239
|
+
Enabled: true
|
240
|
+
Gemspec/DevelopmentDependencies: # new in 1.44
|
241
|
+
Enabled: true
|
242
|
+
Lint/ArrayLiteralInRegexp: # new in 1.71
|
243
|
+
Enabled: true
|
244
|
+
Lint/ConstantReassignment: # new in 1.70
|
245
|
+
Enabled: true
|
246
|
+
Lint/CopDirectiveSyntax: # new in 1.72
|
247
|
+
Enabled: true
|
248
|
+
Lint/DuplicateMagicComment: # new in 1.37
|
249
|
+
Enabled: true
|
250
|
+
Lint/DuplicateMatchPattern: # new in 1.50
|
251
|
+
Enabled: true
|
252
|
+
Lint/DuplicateSetElement: # new in 1.67
|
253
|
+
Enabled: true
|
254
|
+
Lint/HashNewWithKeywordArgumentsAsDefault: # new in 1.69
|
255
|
+
Enabled: true
|
256
|
+
Lint/ItWithoutArgumentsInBlock: # new in 1.59
|
257
|
+
Enabled: true
|
258
|
+
Lint/LiteralAssignmentInCondition: # new in 1.58
|
259
|
+
Enabled: true
|
260
|
+
Lint/MixedCaseRange: # new in 1.53
|
261
|
+
Enabled: true
|
262
|
+
Lint/NumericOperationWithConstantResult: # new in 1.69
|
263
|
+
Enabled: true
|
264
|
+
Lint/RedundantRegexpQuantifiers: # new in 1.53
|
265
|
+
Enabled: true
|
266
|
+
Lint/RedundantTypeConversion: # new in 1.72
|
267
|
+
Enabled: true
|
268
|
+
Lint/SharedMutableDefault: # new in 1.70
|
269
|
+
Enabled: true
|
270
|
+
Lint/SuppressedExceptionInNumberConversion: # new in 1.72
|
271
|
+
Enabled: true
|
272
|
+
Lint/UnescapedBracketInRegexp: # new in 1.68
|
273
|
+
Enabled: true
|
274
|
+
Lint/UselessConstantScoping: # new in 1.72
|
275
|
+
Enabled: true
|
276
|
+
Exclude:
|
277
|
+
- lib/parse_date/int_from_string.rb
|
278
|
+
Lint/UselessDefined: # new in 1.69
|
279
|
+
Enabled: true
|
280
|
+
Lint/UselessNumericOperation: # new in 1.66
|
281
|
+
Enabled: true
|
282
|
+
Lint/UselessRescue: # new in 1.43
|
283
|
+
Enabled: true
|
284
|
+
Metrics/CollectionLiteralLength: # new in 1.47
|
285
|
+
Enabled: true
|
286
|
+
Style/AmbiguousEndlessMethodDefinition: # new in 1.68
|
287
|
+
Enabled: true
|
288
|
+
Style/ArrayIntersect: # new in 1.40
|
289
|
+
Enabled: true
|
290
|
+
Style/BitwisePredicate: # new in 1.68
|
291
|
+
Enabled: true
|
292
|
+
Style/CombinableDefined: # new in 1.68
|
293
|
+
Enabled: true
|
294
|
+
Style/ComparableBetween: # new in 1.74
|
295
|
+
Enabled: true
|
296
|
+
Style/ComparableClamp: # new in 1.44
|
297
|
+
Enabled: true
|
298
|
+
Style/ConcatArrayLiterals: # new in 1.41
|
299
|
+
Enabled: true
|
300
|
+
Style/DataInheritance: # new in 1.49
|
301
|
+
Enabled: true
|
302
|
+
Style/DigChain: # new in 1.69
|
303
|
+
Enabled: true
|
304
|
+
Style/DirEmpty: # new in 1.48
|
305
|
+
Enabled: true
|
306
|
+
Style/ExactRegexpMatch: # new in 1.51
|
307
|
+
Enabled: true
|
308
|
+
Style/FileEmpty: # new in 1.48
|
309
|
+
Enabled: true
|
310
|
+
Style/FileNull: # new in 1.69
|
311
|
+
Enabled: true
|
312
|
+
Style/FileTouch: # new in 1.69
|
313
|
+
Enabled: true
|
314
|
+
Style/HashFetchChain: # new in 1.75
|
315
|
+
Enabled: true
|
316
|
+
Style/HashSlice: # new in 1.71
|
317
|
+
Enabled: true
|
318
|
+
Style/ItAssignment: # new in 1.70
|
319
|
+
Enabled: true
|
320
|
+
Style/ItBlockParameter: # new in 1.75
|
321
|
+
Enabled: true
|
322
|
+
Style/KeywordArgumentsMerging: # new in 1.68
|
323
|
+
Enabled: true
|
324
|
+
Style/MapIntoArray: # new in 1.63
|
325
|
+
Enabled: true
|
326
|
+
Style/MapToSet: # new in 1.42
|
327
|
+
Enabled: true
|
328
|
+
Style/MinMaxComparison: # new in 1.42
|
329
|
+
Enabled: true
|
330
|
+
Style/OperatorMethodCall: # new in 1.37
|
331
|
+
Enabled: true
|
332
|
+
Style/RedundantArrayConstructor: # new in 1.52
|
333
|
+
Enabled: true
|
334
|
+
Style/RedundantConstantBase: # new in 1.40
|
335
|
+
Enabled: true
|
336
|
+
Style/RedundantCurrentDirectoryInPath: # new in 1.53
|
337
|
+
Enabled: true
|
338
|
+
Style/RedundantDoubleSplatHashBraces: # new in 1.41
|
339
|
+
Enabled: true
|
340
|
+
Style/RedundantEach: # new in 1.38
|
341
|
+
Enabled: true
|
342
|
+
Style/RedundantFilterChain: # new in 1.52
|
343
|
+
Enabled: true
|
344
|
+
Style/RedundantFormat: # new in 1.72
|
345
|
+
Enabled: true
|
346
|
+
Style/RedundantHeredocDelimiterQuotes: # new in 1.45
|
347
|
+
Enabled: true
|
348
|
+
Style/RedundantInterpolationUnfreeze: # new in 1.66
|
349
|
+
Enabled: true
|
350
|
+
Style/RedundantLineContinuation: # new in 1.49
|
351
|
+
Enabled: true
|
352
|
+
Style/RedundantRegexpArgument: # new in 1.53
|
353
|
+
Enabled: true
|
354
|
+
Style/RedundantRegexpConstructor: # new in 1.52
|
355
|
+
Enabled: true
|
356
|
+
Exclude:
|
357
|
+
- lib/parse_date/int_from_string.rb
|
358
|
+
Style/RedundantStringEscape: # new in 1.37
|
359
|
+
Enabled: true
|
360
|
+
Style/ReturnNilInPredicateMethodDefinition: # new in 1.53
|
361
|
+
Enabled: true
|
362
|
+
Style/SafeNavigationChainLength: # new in 1.68
|
363
|
+
Enabled: true
|
364
|
+
Style/SendWithLiteralMethodName: # new in 1.64
|
365
|
+
Enabled: true
|
366
|
+
Style/SingleLineDoEndBlock: # new in 1.57
|
367
|
+
Enabled: true
|
368
|
+
Style/SuperArguments: # new in 1.64
|
369
|
+
Enabled: true
|
370
|
+
Style/SuperWithArgsParentheses: # new in 1.58
|
371
|
+
Enabled: true
|
372
|
+
Style/YAMLFileRead: # new in 1.53
|
373
|
+
Enabled: true
|
374
|
+
Capybara/FindAllFirst: # new in 2.22
|
375
|
+
Enabled: true
|
376
|
+
Capybara/MatchStyle: # new in 2.17
|
377
|
+
Enabled: true
|
378
|
+
Capybara/NegationMatcher: # new in 2.14
|
379
|
+
Enabled: true
|
380
|
+
Capybara/NegationMatcherAfterVisit: # new in 2.22
|
381
|
+
Enabled: true
|
382
|
+
Capybara/RedundantWithinFind: # new in 2.20
|
383
|
+
Enabled: true
|
384
|
+
Capybara/SpecificActions: # new in 2.14
|
385
|
+
Enabled: true
|
386
|
+
Capybara/RSpec/HaveSelector: # new in 2.19
|
387
|
+
Enabled: true
|
388
|
+
Capybara/RSpec/PredicateMatcher: # new in 2.19
|
389
|
+
Enabled: true
|
390
|
+
FactoryBot/AssociationStyle: # new in 2.23
|
391
|
+
Enabled: true
|
392
|
+
FactoryBot/ConsistentParenthesesStyle: # new in 2.14
|
393
|
+
Enabled: true
|
394
|
+
FactoryBot/ExcessiveCreateList: # new in 2.25
|
395
|
+
Enabled: true
|
396
|
+
FactoryBot/FactoryAssociationWithStrategy: # new in 2.23
|
397
|
+
Enabled: true
|
398
|
+
FactoryBot/FactoryNameStyle: # new in 2.16
|
399
|
+
Enabled: true
|
400
|
+
FactoryBot/IdSequence: # new in 2.24
|
401
|
+
Enabled: true
|
402
|
+
FactoryBot/RedundantFactoryOption: # new in 2.23
|
403
|
+
Enabled: true
|
404
|
+
RSpec/IncludeExamples: # new in 3.6
|
405
|
+
Enabled: true
|
406
|
+
RSpecRails/InferredSpecType: # new in 2.14
|
407
|
+
Enabled: true
|
408
|
+
RSpecRails/MinitestAssertions: # new in 2.17
|
409
|
+
Enabled: true
|
410
|
+
RSpecRails/NegationBeValid: # new in 2.23
|
411
|
+
Enabled: true
|
412
|
+
RSpecRails/TravelAround: # new in 2.19
|
413
|
+
Enabled: true
|
data/.rubocop_todo.yml
CHANGED
@@ -1,42 +1,25 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config`
|
3
|
-
# on
|
3
|
+
# on 2022-10-07 22:01:55 UTC using RuboCop version 1.36.0.
|
4
4
|
# The point is for the user to remove these configuration records
|
5
5
|
# one by one as the offenses are removed from the code base.
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
8
8
|
|
9
9
|
# Offense count: 5
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
# Offense count: 4
|
14
|
-
Metrics/CyclomaticComplexity:
|
15
|
-
Max: 12
|
16
|
-
|
17
|
-
# Offense count: 4
|
18
|
-
Metrics/PerceivedComplexity:
|
19
|
-
Max: 12
|
20
|
-
|
21
|
-
# Offense count: 2
|
22
|
-
Style/Documentation:
|
10
|
+
# This cop supports safe autocorrection (--autocorrect).
|
11
|
+
Lint/AmbiguousOperatorPrecedence:
|
23
12
|
Exclude:
|
24
|
-
- '
|
25
|
-
- 'test/**/*'
|
26
|
-
- 'lib/parse_date.rb'
|
13
|
+
- 'lib/parse_date/int_from_string.rb'
|
27
14
|
|
28
|
-
# Offense count:
|
29
|
-
|
30
|
-
# Configuration parameters: EnforcedOctalStyle.
|
31
|
-
# SupportedOctalStyles: zero_with_o, zero_only
|
32
|
-
Style/NumericLiteralPrefix:
|
15
|
+
# Offense count: 11
|
16
|
+
RSpec/RepeatedDescription:
|
33
17
|
Exclude:
|
34
18
|
- 'spec/parse_date/int_from_string_spec.rb'
|
19
|
+
- 'spec/parse_date_spec.rb'
|
35
20
|
|
36
|
-
# Offense count:
|
37
|
-
|
38
|
-
# Configuration parameters: EnforcedStyle, AllowInnerSlashes.
|
39
|
-
# SupportedStyles: slashes, percent_r, mixed
|
40
|
-
Style/RegexpLiteral:
|
21
|
+
# Offense count: 14
|
22
|
+
RSpec/RepeatedExample:
|
41
23
|
Exclude:
|
42
|
-
- '
|
24
|
+
- 'spec/parse_date/int_from_string_spec.rb'
|
25
|
+
- 'spec/parse_date_spec.rb'
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
parse_date (0.4.4)
|
5
|
+
zeitwerk (~> 2.1)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
ast (2.4.3)
|
11
|
+
date (3.4.1)
|
12
|
+
debug (1.11.0)
|
13
|
+
irb (~> 1.10)
|
14
|
+
reline (>= 0.3.8)
|
15
|
+
diff-lcs (1.6.2)
|
16
|
+
docile (1.4.1)
|
17
|
+
erb (5.0.2)
|
18
|
+
io-console (0.8.1)
|
19
|
+
irb (1.15.2)
|
20
|
+
pp (>= 0.6.0)
|
21
|
+
rdoc (>= 4.0.0)
|
22
|
+
reline (>= 0.4.2)
|
23
|
+
json (2.13.2)
|
24
|
+
language_server-protocol (3.17.0.5)
|
25
|
+
lint_roller (1.1.0)
|
26
|
+
parallel (1.27.0)
|
27
|
+
parser (3.3.9.0)
|
28
|
+
ast (~> 2.4.1)
|
29
|
+
racc
|
30
|
+
pp (0.6.2)
|
31
|
+
prettyprint
|
32
|
+
prettyprint (0.2.0)
|
33
|
+
prism (1.5.1)
|
34
|
+
psych (5.2.6)
|
35
|
+
date
|
36
|
+
stringio
|
37
|
+
racc (1.8.1)
|
38
|
+
rainbow (3.1.1)
|
39
|
+
rake (13.0.6)
|
40
|
+
rdoc (6.14.2)
|
41
|
+
erb
|
42
|
+
psych (>= 4.0.0)
|
43
|
+
regexp_parser (2.11.3)
|
44
|
+
reline (0.6.2)
|
45
|
+
io-console (~> 0.5)
|
46
|
+
rspec (3.13.1)
|
47
|
+
rspec-core (~> 3.13.0)
|
48
|
+
rspec-expectations (~> 3.13.0)
|
49
|
+
rspec-mocks (~> 3.13.0)
|
50
|
+
rspec-core (3.13.5)
|
51
|
+
rspec-support (~> 3.13.0)
|
52
|
+
rspec-expectations (3.13.5)
|
53
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
54
|
+
rspec-support (~> 3.13.0)
|
55
|
+
rspec-mocks (3.13.5)
|
56
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
57
|
+
rspec-support (~> 3.13.0)
|
58
|
+
rspec-support (3.13.5)
|
59
|
+
rubocop (1.80.2)
|
60
|
+
json (~> 2.3)
|
61
|
+
language_server-protocol (~> 3.17.0.2)
|
62
|
+
lint_roller (~> 1.1.0)
|
63
|
+
parallel (~> 1.10)
|
64
|
+
parser (>= 3.3.0.2)
|
65
|
+
rainbow (>= 2.2.2, < 4.0)
|
66
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
67
|
+
rubocop-ast (>= 1.46.0, < 2.0)
|
68
|
+
ruby-progressbar (~> 1.7)
|
69
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
70
|
+
rubocop-ast (1.46.0)
|
71
|
+
parser (>= 3.3.7.2)
|
72
|
+
prism (~> 1.4)
|
73
|
+
rubocop-capybara (2.22.1)
|
74
|
+
lint_roller (~> 1.1)
|
75
|
+
rubocop (~> 1.72, >= 1.72.1)
|
76
|
+
rubocop-factory_bot (2.27.1)
|
77
|
+
lint_roller (~> 1.1)
|
78
|
+
rubocop (~> 1.72, >= 1.72.1)
|
79
|
+
rubocop-rake (0.7.1)
|
80
|
+
lint_roller (~> 1.1)
|
81
|
+
rubocop (>= 1.72.1)
|
82
|
+
rubocop-rspec (3.7.0)
|
83
|
+
lint_roller (~> 1.1)
|
84
|
+
rubocop (~> 1.72, >= 1.72.1)
|
85
|
+
rubocop-rspec_rails (2.31.0)
|
86
|
+
lint_roller (~> 1.1)
|
87
|
+
rubocop (~> 1.72, >= 1.72.1)
|
88
|
+
rubocop-rspec (~> 3.5)
|
89
|
+
ruby-progressbar (1.13.0)
|
90
|
+
simplecov (0.22.0)
|
91
|
+
docile (~> 1.1)
|
92
|
+
simplecov-html (~> 0.11)
|
93
|
+
simplecov_json_formatter (~> 0.1)
|
94
|
+
simplecov-html (0.13.2)
|
95
|
+
simplecov_json_formatter (0.1.4)
|
96
|
+
stringio (3.1.7)
|
97
|
+
unicode-display_width (3.2.0)
|
98
|
+
unicode-emoji (~> 4.1)
|
99
|
+
unicode-emoji (4.1.0)
|
100
|
+
zeitwerk (2.7.3)
|
101
|
+
|
102
|
+
PLATFORMS
|
103
|
+
arm64-darwin-24
|
104
|
+
x86_64-darwin-19
|
105
|
+
x86_64-darwin-22
|
106
|
+
x86_64-linux
|
107
|
+
|
108
|
+
DEPENDENCIES
|
109
|
+
bundler (~> 2.0)
|
110
|
+
debug
|
111
|
+
parse_date!
|
112
|
+
rake (~> 13.0.3)
|
113
|
+
rspec (~> 3.0)
|
114
|
+
rubocop (~> 1.12)
|
115
|
+
rubocop-capybara
|
116
|
+
rubocop-factory_bot
|
117
|
+
rubocop-rake
|
118
|
+
rubocop-rspec
|
119
|
+
rubocop-rspec_rails
|
120
|
+
simplecov
|
121
|
+
|
122
|
+
BUNDLED WITH
|
123
|
+
2.7.2
|
data/README.md
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
[](https://badge.fury.io/rb/parse_date)
|
2
|
-
[](https://codeclimate.com/github/sul-dlss/parse_date/test_coverage)
|
2
|
+
[](https://dl.circleci.com/status-badge/redirect/gh/sul-dlss/parse_date/tree/main)
|
3
|
+
[](https://codecov.io/github/sul-dlss/parse_date)
|
5
4
|
|
6
5
|
# ParseDate
|
7
6
|
|
@@ -1,12 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'date' # so upstream callers don't have to require it
|
4
|
-
|
5
3
|
class ParseDate
|
6
|
-
|
7
4
|
# Parse (Year) Integers from Date Strings
|
8
5
|
module IntFromString
|
9
|
-
|
10
6
|
# earliest year as Integer if we can parse one from date_str
|
11
7
|
# e.g. if 17uu, result is 1700
|
12
8
|
# NOTE: if we have a x/x/yy or x-x-yy pattern (the only 2 digit year patterns
|
@@ -15,29 +11,20 @@ class ParseDate
|
|
15
11
|
# 1/1/17 -> 2017
|
16
12
|
# 1/1/27 -> 1927
|
17
13
|
# @return [Integer, nil] Integer year if we could parse one, nil otherwise
|
18
|
-
def
|
14
|
+
def earliest_year(date_str)
|
19
15
|
return unless date_str && !date_str.empty?
|
20
16
|
return if date_str == '0000-00-00' # shpc collection has these useless dates
|
21
17
|
|
22
18
|
# B.C. first (match longest string first)
|
23
|
-
|
24
|
-
return
|
25
|
-
|
26
|
-
|
27
|
-
result
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
result ||= ParseDate.send(:first_year_for_decade, date_str) # 198x or 201x
|
33
|
-
result ||= ParseDate.send(:first_year_for_century, date_str) # includes BC
|
34
|
-
result ||= ParseDate.send(:year_for_early_numeric, date_str)
|
35
|
-
unless result
|
36
|
-
# try removing brackets between digits in case we have 169[5] or [18]91
|
37
|
-
no_brackets = ParseDate.send(:remove_brackets, date_str)
|
38
|
-
return earliest_year(no_brackets) if no_brackets
|
39
|
-
end
|
40
|
-
result.to_i if result && year_int_valid?(result.to_i)
|
19
|
+
bc_result = earliest_year_bc_parsing(date_str)
|
20
|
+
return bc_result if bc_result
|
21
|
+
|
22
|
+
result = earliest_year_parsing(date_str)
|
23
|
+
return result if result
|
24
|
+
|
25
|
+
# try removing brackets between digits in case we have 169[5] or [18]91
|
26
|
+
no_brackets = remove_brackets(date_str)
|
27
|
+
earliest_year(no_brackets) if no_brackets
|
41
28
|
end
|
42
29
|
|
43
30
|
# latest year as Integer if we can parse one from date_str
|
@@ -48,52 +35,100 @@ class ParseDate
|
|
48
35
|
# 1/1/17 -> 2017
|
49
36
|
# 1/1/27 -> 1927
|
50
37
|
# @return [Integer, nil] Integer year if we could parse one, nil otherwise
|
51
|
-
def
|
38
|
+
def latest_year(date_str)
|
52
39
|
return unless date_str && !date_str.empty?
|
53
40
|
return if date_str == '0000-00-00' # shpc collection has these useless dates
|
54
41
|
|
55
42
|
# B.C. first (match longest string first)
|
56
|
-
|
57
|
-
return
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
result ||= ParseDate.send(:yyuu_after_hyphen, date_str)
|
66
|
-
result ||= ParseDate.send(:year_after_or, date_str)
|
67
|
-
result ||= ParseDate.send(:negative_4digits_after_hyphen, date_str)
|
68
|
-
result ||= ParseDate.send(:negative_first_four_digits, date_str)
|
69
|
-
result ||= ParseDate.send(:last_year_for_0s_decade, date_str)
|
70
|
-
result ||= ParseDate.send(:first_four_digits, date_str)
|
71
|
-
result ||= ParseDate.send(:year_from_mm_dd_yy, date_str)
|
72
|
-
result ||= ParseDate.send(:last_year_for_decade, date_str) # 198x or 201x
|
73
|
-
result ||= ParseDate.send(:last_year_mult_centuries, date_str) # nth-nth century
|
74
|
-
result ||= ParseDate.send(:last_year_for_century, date_str)
|
75
|
-
result ||= ParseDate.send(:last_year_for_early_numeric, date_str)
|
76
|
-
unless result
|
77
|
-
# try removing brackets between digits in case we have 169[5] or [18]91
|
78
|
-
no_brackets = ParseDate.send(:remove_brackets, date_str)
|
79
|
-
return latest_year(no_brackets) if no_brackets
|
80
|
-
end
|
81
|
-
result.to_i if result && year_int_valid?(result.to_i)
|
43
|
+
bc_result = latest_year_bc_parsing(date_str)
|
44
|
+
return bc_result if bc_result
|
45
|
+
|
46
|
+
result = latest_year_parsing(date_str)
|
47
|
+
return result if result
|
48
|
+
|
49
|
+
# try removing brackets between digits in case we have 169[5] or [18]91
|
50
|
+
no_brackets = remove_brackets(date_str)
|
51
|
+
latest_year(no_brackets) if no_brackets
|
82
52
|
end
|
83
53
|
|
84
54
|
# true if the year is between -9999 and (current year + 1), inclusive
|
85
55
|
# @return [Boolean] true if the year is between -999 and (current year + 1); false otherwise
|
86
|
-
def
|
56
|
+
def year_int_valid?(year)
|
87
57
|
return false unless year.is_a? Integer
|
88
58
|
|
89
59
|
(-10000 < year.to_i) && (year < Date.today.year + 2)
|
90
60
|
end
|
91
61
|
|
92
|
-
|
62
|
+
private
|
63
|
+
|
64
|
+
def earliest_year_bc_parsing(date_str)
|
65
|
+
return earliest_century_bc(date_str) if date_str.match(YY_YY_CENTURY_BC_REGEX)
|
66
|
+
return between_bc_earliest_year(date_str) if date_str.match(BETWEEN_Yn_AND_Yn_BC_REGEX)
|
67
|
+
|
68
|
+
year_int_for_bc(date_str) if date_str.match(YEAR_BC_REGEX)
|
69
|
+
end
|
70
|
+
|
71
|
+
def earliest_year_parsing(date_str)
|
72
|
+
[
|
73
|
+
# DataWorks date ranges include slashes and hyphens that match date_str/date_str
|
74
|
+
:slash_earliest_year,
|
75
|
+
# longest string first, more or less
|
76
|
+
:between_earliest_year,
|
77
|
+
:hyphen_4digit_earliest_year,
|
78
|
+
:negative_first_four_digits,
|
79
|
+
:first_four_digits,
|
80
|
+
:year_from_mm_dd_yy,
|
81
|
+
:first_year_for_decade, # 198x or 201x
|
82
|
+
:first_year_for_century, # includes some BC
|
83
|
+
:year_for_early_numeric
|
84
|
+
].each do |method_name|
|
85
|
+
result = send(method_name, date_str)
|
86
|
+
return result.to_i if result && year_int_valid?(result.to_i)
|
87
|
+
end
|
88
|
+
nil
|
89
|
+
end
|
90
|
+
|
91
|
+
def latest_year_bc_parsing(date_str)
|
92
|
+
return last_year_mult_centuries_bc(date_str) if date_str.match(YY_YY_CENTURY_BC_REGEX)
|
93
|
+
return between_bc_latest_year(date_str) if date_str.match(BETWEEN_Yn_AND_Yn_BC_REGEX)
|
94
|
+
return last_year_for_bc_century(date_str) if date_str.match(BC_CENTURY_REGEX)
|
95
|
+
|
96
|
+
year_int_for_bc(date_str) if date_str.match(BC_REGEX)
|
97
|
+
end
|
98
|
+
|
99
|
+
# rubocop:disable Metrics/MethodLength
|
100
|
+
def latest_year_parsing(date_str)
|
101
|
+
result = nil
|
102
|
+
[
|
103
|
+
# DataWorks date ranges include slashes and hyphens that match date_str/date_str
|
104
|
+
:slash_latest_year,
|
105
|
+
# longest string first, more or less
|
106
|
+
:between_latest_year,
|
107
|
+
:hyphen_4digit_latest_year,
|
108
|
+
:hyphen_2digit_latest_year,
|
109
|
+
:hyphen_1digit_latest_year,
|
110
|
+
:yyuu_after_hyphen,
|
111
|
+
:year_after_or,
|
112
|
+
:negative_4digits_after_hyphen,
|
113
|
+
:negative_first_four_digits,
|
114
|
+
:last_year_for_0s_decade,
|
115
|
+
:first_four_digits,
|
116
|
+
:year_from_mm_dd_yy,
|
117
|
+
:last_year_for_decade, # 198x or 201x
|
118
|
+
:last_year_mult_centuries, # nth-nth century
|
119
|
+
:last_year_for_century,
|
120
|
+
:last_year_for_early_numeric
|
121
|
+
].each do |method|
|
122
|
+
result ||= send(method, date_str)
|
123
|
+
return result.to_i if result && year_int_valid?(result.to_i)
|
124
|
+
end
|
125
|
+
nil
|
126
|
+
end
|
127
|
+
# rubocop:enable Metrics/MethodLength
|
93
128
|
|
94
129
|
REGEX_OPTS = Regexp::IGNORECASE | Regexp::MULTILINE
|
95
130
|
BC_REGEX = Regexp.new(/\s*B\.?\s*C\.?/im)
|
96
|
-
BRACKETS_BETWEEN_DIGITS_REGEX = Regexp.new(
|
131
|
+
BRACKETS_BETWEEN_DIGITS_REGEX = Regexp.new("\\d[#{Regexp.escape('[]')}]\\d")
|
97
132
|
|
98
133
|
# removes brackets between digits such as 169[5] or [18]91
|
99
134
|
def remove_brackets(date_str)
|
@@ -112,8 +147,8 @@ class ParseDate
|
|
112
147
|
# @return [Integer, nil] yyyy if date_str matches pattern; nil otherwise
|
113
148
|
def hyphen_4digit_latest_year(date_str)
|
114
149
|
latest = Regexp.last_match(:last) if date_str.match(YYYY_HYPHEN_YYYY_REGEX)
|
115
|
-
if
|
116
|
-
|
150
|
+
if year_int_valid?(latest.to_i)
|
151
|
+
latest_year(latest) # accommodates '1980s - 1990s'
|
117
152
|
else
|
118
153
|
# return the bad value; parse_range might need to complain about it
|
119
154
|
latest
|
@@ -131,7 +166,7 @@ class ParseDate
|
|
131
166
|
first = Regexp.last_match(:first)
|
132
167
|
century = first[0..-3] # whatever is before the last 2 digits
|
133
168
|
last = "#{century}#{Regexp.last_match(:last)}"
|
134
|
-
last.to_i if
|
169
|
+
last.to_i if year_range_valid?(first.to_i, last.to_i)
|
135
170
|
end
|
136
171
|
|
137
172
|
YYYY_HYPHEN_Y_REGEX = Regexp.new(/(?<first>\d{3,4})\??\s*(-|—|–|to)\s*(?<last>\d{1})\??([^-0-9].*)?$/)
|
@@ -145,7 +180,7 @@ class ParseDate
|
|
145
180
|
first = Regexp.last_match(:first)
|
146
181
|
decade = first[0..-2] # whatever is before the last digit
|
147
182
|
last = "#{decade}#{Regexp.last_match(:last)}"
|
148
|
-
last.to_i if
|
183
|
+
last.to_i if year_range_valid?(first.to_i, last.to_i)
|
149
184
|
end
|
150
185
|
|
151
186
|
YYUU = '\\d{1,2}[u\\-]{2}'
|
@@ -206,13 +241,13 @@ class ParseDate
|
|
206
241
|
# looks for -yyyy at beginning of date_str and returns if found
|
207
242
|
# @return [String, nil] negative 4 digit year (e.g. -1865) if date_str has -yyyy, nil otherwise
|
208
243
|
def negative_first_four_digits(date_str)
|
209
|
-
Regexp.last_match(1) if date_str.match(/^(
|
244
|
+
Regexp.last_match(1) if date_str.match(/^(-\d{4})/)
|
210
245
|
end
|
211
246
|
|
212
247
|
# looks for -yyyy after hyphen and returns if found
|
213
248
|
# @return [String, nil] negative 4 digit year (e.g. -1865) if date_str has -yyyy - -yyyy, nil otherwise
|
214
249
|
def negative_4digits_after_hyphen(date_str)
|
215
|
-
Regexp.last_match(1) if date_str.match(
|
250
|
+
Regexp.last_match(1) if date_str.match(/-\d{4}\s*(?:-|–|–|or|to)\s*(-\d{4})/)
|
216
251
|
end
|
217
252
|
|
218
253
|
# looks for 4 consecutive digits in date_str and returns first occurrence if found
|
@@ -228,7 +263,7 @@ class ParseDate
|
|
228
263
|
# 1/1/27 -> 1927
|
229
264
|
# @return [String, nil] 4 digit year (e.g. 1865, 0950) if date_str matches pattern, nil otherwise
|
230
265
|
def year_from_mm_dd_yy(date_str)
|
231
|
-
slash_matches = date_str.match(
|
266
|
+
slash_matches = date_str.match(%r{\d{1,2}/\d{1,2}/\d{2}})
|
232
267
|
if slash_matches
|
233
268
|
date_obj = Date.strptime(date_str, '%m/%d/%y')
|
234
269
|
else
|
@@ -247,8 +282,8 @@ class ParseDate
|
|
247
282
|
# @return [String, nil] 4 digit year (e.g. 1869, 1959) if date_str matches pattern, nil otherwise
|
248
283
|
def last_year_for_0s_decade(date_str)
|
249
284
|
decade_matches = date_str.match(DECADE_0S_REGEX)
|
250
|
-
changed_to_nine = decade_matches.to_s.sub(/0
|
251
|
-
|
285
|
+
changed_to_nine = decade_matches.to_s.sub(/0'?s/, '9') if decade_matches
|
286
|
+
first_four_digits(changed_to_nine) if changed_to_nine
|
252
287
|
end
|
253
288
|
|
254
289
|
DECADE_4CHAR_REGEX = Regexp.new('(^|\D)\d{3}[u\-?x]($|\D)', REGEX_OPTS)
|
@@ -259,7 +294,7 @@ class ParseDate
|
|
259
294
|
def first_year_for_decade(date_str)
|
260
295
|
decade_matches = date_str.match(DECADE_4CHAR_REGEX)
|
261
296
|
changed_to_zero = decade_matches.to_s.tr('u\-?x', '0') if decade_matches
|
262
|
-
|
297
|
+
first_four_digits(changed_to_zero) if changed_to_zero
|
263
298
|
end
|
264
299
|
|
265
300
|
# last year of decade (as String) if we have: yyyu, yyy-, yyy? or yyyx pattern
|
@@ -268,7 +303,7 @@ class ParseDate
|
|
268
303
|
def last_year_for_decade(date_str)
|
269
304
|
decade_matches = date_str.match(DECADE_4CHAR_REGEX)
|
270
305
|
changed_to_nine = decade_matches.to_s.tr('u\-?x', '9') if decade_matches
|
271
|
-
|
306
|
+
first_four_digits(changed_to_nine) if changed_to_nine
|
272
307
|
end
|
273
308
|
|
274
309
|
CENTURY_WORD_REGEX = Regexp.new('(\d{1,2})[a-z]{2}?\s*century', REGEX_OPTS)
|
@@ -277,18 +312,22 @@ class ParseDate
|
|
277
312
|
|
278
313
|
# first year of century if we have: yyuu, yy--, yy--? or xxth century pattern; handles B.C.
|
279
314
|
# @return [Integer, nil] yy00 if date_str matches pattern, nil otherwise
|
315
|
+
# rubocop:disable Metrics/AbcSize
|
280
316
|
def first_year_for_century(date_str)
|
281
317
|
return Regexp.last_match(1).to_i * -100 - 99 if date_str.match(BC_CENTURY_REGEX)
|
282
318
|
return Regexp.last_match(1).to_i * 100 if date_str.match(CENTURY_4CHAR_REGEX)
|
283
319
|
return (Regexp.last_match(:first).to_i - 1) * 100 if date_str.match(YY_YY_CENTURY_REGEX)
|
284
|
-
|
320
|
+
|
321
|
+
(Regexp.last_match(1).to_i - 1) * 100 if date_str.match(CENTURY_WORD_REGEX)
|
285
322
|
end
|
323
|
+
# rubocop:enable Metrics/AbcSize
|
286
324
|
|
287
325
|
# last year of century if we have: yyuu, yy--, yy--? or xxth century pattern
|
288
326
|
# @return [Integer, nil] yy99 if date_str matches pattern, nil otherwise; also nil if B.C. in pattern
|
289
327
|
def last_year_for_century(date_str)
|
290
328
|
return Regexp.last_match(1).to_i * 100 + 99 if date_str.match(CENTURY_4CHAR_REGEX)
|
291
|
-
|
329
|
+
|
330
|
+
(Regexp.last_match(1).to_i - 1) * 100 + 99 if date_str.match(CENTURY_WORD_REGEX)
|
292
331
|
end
|
293
332
|
|
294
333
|
# last year of century (as String) if we have: nth century BC
|
@@ -297,6 +336,21 @@ class ParseDate
|
|
297
336
|
Regexp.last_match(1).to_i * -100 if date_str.match(BC_CENTURY_REGEX)
|
298
337
|
end
|
299
338
|
|
339
|
+
# Regex for a date range pattern with a slash: 2023-01-02T19:20:30+01:00/2025-01-01
|
340
|
+
DATESTR_REGEX = Regexp.new(/\b(\d{4})\b.*?\/.*?\b(\d{4})\b/im) # rubocop:disable Style/RegexpLiteral
|
341
|
+
|
342
|
+
# Integer value for earliest if we have "date_str/date_str" pattern
|
343
|
+
# @return [Integer, nil] year if date_str matches pattern; nil otherwise
|
344
|
+
def slash_earliest_year(date_str)
|
345
|
+
Regexp.last_match(1).to_i if date_str.match(DATESTR_REGEX)
|
346
|
+
end
|
347
|
+
|
348
|
+
# Integer value for latest if we have "date_str/date_str" pattern
|
349
|
+
# @return [Integer, nil] year if date_str matches pattern; nil otherwise
|
350
|
+
def slash_latest_year(date_str)
|
351
|
+
Regexp.last_match(2).to_i if date_str.match(DATESTR_REGEX)
|
352
|
+
end
|
353
|
+
|
300
354
|
BETWEEN_Yn_AND_Yn_REGEX = Regexp.new(/between\s+(?<first>\d{1,4})\??\s+and\s+(?<last>\d{1,4})\??/im)
|
301
355
|
|
302
356
|
# Integer value for earliest if we have "between y and y" pattern
|
@@ -344,7 +398,7 @@ class ParseDate
|
|
344
398
|
end
|
345
399
|
|
346
400
|
FIRST_LAST_EARLY_NUMERIC_REGEX =
|
347
|
-
Regexp.new(/^(?<first
|
401
|
+
Regexp.new(/^(?<first>-?\d{1,3})\??\s*(-|–|–|or|to)\s*(?<last>-?\d{1,4})\??([^\du\-\[]|$)/im)
|
348
402
|
|
349
403
|
# Integer value for latest year if we have early numeric year range or single early numeric year
|
350
404
|
# @return [Integer, nil] year if date_str matches pattern; nil otherwise
|
data/lib/parse_date/version.rb
CHANGED
data/lib/parse_date.rb
CHANGED
@@ -23,31 +23,18 @@ class ParseDate
|
|
23
23
|
class Error < StandardError; end
|
24
24
|
|
25
25
|
include Singleton
|
26
|
-
extend
|
27
|
-
|
28
|
-
# class method delegation
|
29
|
-
def self.earliest_year(date_str)
|
30
|
-
ParseDate::IntFromString.earliest_year(date_str)
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.latest_year(date_str)
|
34
|
-
ParseDate::IntFromString.latest_year(date_str)
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.year_int_valid?(date_str)
|
38
|
-
ParseDate::IntFromString.year_int_valid?(date_str)
|
39
|
-
end
|
26
|
+
extend IntFromString
|
40
27
|
|
41
28
|
# @return [Array] array of Integer year values from earliest year to latest year, inclusive
|
42
29
|
def self.parse_range(date_str)
|
43
30
|
first = earliest_year(date_str)
|
44
31
|
last = latest_year(date_str)
|
45
32
|
return nil unless first || last
|
46
|
-
raise
|
33
|
+
raise Error, "Unable to parse range from '#{date_str}'" unless year_range_valid?(first, last)
|
47
34
|
|
48
35
|
range_array(first, last)
|
49
36
|
rescue StandardError => e
|
50
|
-
raise
|
37
|
+
raise Error, "Unable to parse range from '#{date_str}': #{e.message}"
|
51
38
|
end
|
52
39
|
|
53
40
|
# true if:
|
@@ -65,14 +52,14 @@ class ParseDate
|
|
65
52
|
# @param [Integer, String] first_year, expecting integer or parseable string for .to_i
|
66
53
|
# @param [Integer, String] last_year, expecting integer or parseable string for .to_i
|
67
54
|
# @return [Array] array of Integer year values from first to last, inclusive
|
68
|
-
def self.range_array(first_year, last_year)
|
55
|
+
def self.range_array(first_year, last_year) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
69
56
|
first_year = first_year.to_i if first_year.is_a?(String) && first_year.match?(/^-?\d+$/)
|
70
57
|
last_year = last_year.to_i if last_year.is_a?(String) && last_year.match?(/^-?\d+$/)
|
71
58
|
|
72
59
|
return [] unless last_year || first_year
|
73
60
|
return [first_year] if last_year.nil? && first_year
|
74
61
|
return [last_year] if first_year.nil? && last_year
|
75
|
-
raise(
|
62
|
+
raise(Error, "unable to create year range array from #{first_year}, #{last_year}") unless
|
76
63
|
year_range_valid?(first_year, last_year)
|
77
64
|
|
78
65
|
Range.new(first_year, last_year).to_a
|
data/parse_date.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
|
|
15
15
|
spec.homepage = 'https://github.com/sul-dlss/parse_date'
|
16
16
|
|
17
17
|
spec.metadata['allowed_push_host'] = 'https://rubygems.org/'
|
18
|
-
|
18
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
19
19
|
spec.metadata['homepage_uri'] = spec.homepage
|
20
20
|
spec.metadata['source_code_uri'] = 'https://github.com/sul-dlss/parse_date'
|
21
21
|
|
@@ -31,9 +31,14 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_dependency 'zeitwerk', '~> 2.1'
|
32
32
|
|
33
33
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
34
|
-
spec.add_development_dependency '
|
35
|
-
spec.add_development_dependency 'rake', '~>
|
34
|
+
spec.add_development_dependency 'debug'
|
35
|
+
spec.add_development_dependency 'rake', '~> 13.0.3'
|
36
36
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
37
|
-
spec.add_development_dependency 'rubocop', '~>
|
37
|
+
spec.add_development_dependency 'rubocop', '~> 1.12'
|
38
|
+
spec.add_development_dependency 'rubocop-capybara'
|
39
|
+
spec.add_development_dependency 'rubocop-factory_bot'
|
40
|
+
spec.add_development_dependency 'rubocop-rake'
|
41
|
+
spec.add_development_dependency 'rubocop-rspec'
|
42
|
+
spec.add_development_dependency 'rubocop-rspec_rails'
|
38
43
|
spec.add_development_dependency 'simplecov'
|
39
44
|
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parse_date
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Naomi Dushay
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: zeitwerk
|
@@ -39,7 +38,7 @@ dependencies:
|
|
39
38
|
- !ruby/object:Gem::Version
|
40
39
|
version: '2.0'
|
41
40
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
41
|
+
name: debug
|
43
42
|
requirement: !ruby/object:Gem::Requirement
|
44
43
|
requirements:
|
45
44
|
- - ">="
|
@@ -58,14 +57,14 @@ dependencies:
|
|
58
57
|
requirements:
|
59
58
|
- - "~>"
|
60
59
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
60
|
+
version: 13.0.3
|
62
61
|
type: :development
|
63
62
|
prerelease: false
|
64
63
|
version_requirements: !ruby/object:Gem::Requirement
|
65
64
|
requirements:
|
66
65
|
- - "~>"
|
67
66
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
67
|
+
version: 13.0.3
|
69
68
|
- !ruby/object:Gem::Dependency
|
70
69
|
name: rspec
|
71
70
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,14 +85,84 @@ dependencies:
|
|
86
85
|
requirements:
|
87
86
|
- - "~>"
|
88
87
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
88
|
+
version: '1.12'
|
90
89
|
type: :development
|
91
90
|
prerelease: false
|
92
91
|
version_requirements: !ruby/object:Gem::Requirement
|
93
92
|
requirements:
|
94
93
|
- - "~>"
|
95
94
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
95
|
+
version: '1.12'
|
96
|
+
- !ruby/object:Gem::Dependency
|
97
|
+
name: rubocop-capybara
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
type: :development
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: rubocop-factory_bot
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
type: :development
|
118
|
+
prerelease: false
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
- !ruby/object:Gem::Dependency
|
125
|
+
name: rubocop-rake
|
126
|
+
requirement: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
type: :development
|
132
|
+
prerelease: false
|
133
|
+
version_requirements: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
- !ruby/object:Gem::Dependency
|
139
|
+
name: rubocop-rspec
|
140
|
+
requirement: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
type: :development
|
146
|
+
prerelease: false
|
147
|
+
version_requirements: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
- !ruby/object:Gem::Dependency
|
153
|
+
name: rubocop-rspec_rails
|
154
|
+
requirement: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
159
|
+
type: :development
|
160
|
+
prerelease: false
|
161
|
+
version_requirements: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - ">="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
97
166
|
- !ruby/object:Gem::Dependency
|
98
167
|
name: simplecov
|
99
168
|
requirement: !ruby/object:Gem::Requirement
|
@@ -116,13 +185,14 @@ executables: []
|
|
116
185
|
extensions: []
|
117
186
|
extra_rdoc_files: []
|
118
187
|
files:
|
188
|
+
- ".circleci/config.yml"
|
119
189
|
- ".github/pull_request_template.md"
|
120
190
|
- ".gitignore"
|
121
191
|
- ".rspec"
|
122
192
|
- ".rubocop.yml"
|
123
193
|
- ".rubocop_todo.yml"
|
124
|
-
- ".travis.yml"
|
125
194
|
- Gemfile
|
195
|
+
- Gemfile.lock
|
126
196
|
- LICENSE
|
127
197
|
- README.md
|
128
198
|
- Rakefile
|
@@ -136,9 +206,9 @@ homepage: https://github.com/sul-dlss/parse_date
|
|
136
206
|
licenses: []
|
137
207
|
metadata:
|
138
208
|
allowed_push_host: https://rubygems.org/
|
209
|
+
rubygems_mfa_required: 'true'
|
139
210
|
homepage_uri: https://github.com/sul-dlss/parse_date
|
140
211
|
source_code_uri: https://github.com/sul-dlss/parse_date
|
141
|
-
post_install_message:
|
142
212
|
rdoc_options: []
|
143
213
|
require_paths:
|
144
214
|
- lib
|
@@ -153,8 +223,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
153
223
|
- !ruby/object:Gem::Version
|
154
224
|
version: '0'
|
155
225
|
requirements: []
|
156
|
-
rubygems_version: 3.0
|
157
|
-
signing_key:
|
226
|
+
rubygems_version: 3.7.0
|
158
227
|
specification_version: 4
|
159
228
|
summary: parse date values out of strings and normalize them
|
160
229
|
test_files: []
|
data/.travis.yml
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
dist: bionic
|
2
|
-
sudo: false
|
3
|
-
language: ruby
|
4
|
-
cache: bundler
|
5
|
-
rvm:
|
6
|
-
- 2.5.3
|
7
|
-
- 2.6.4
|
8
|
-
|
9
|
-
env:
|
10
|
-
- 'RAILS_VERSION=5.2.3'
|
11
|
-
- 'RAILS_VERSION=6.0.0'
|
12
|
-
|
13
|
-
before_install: gem install bundler -v 2.0.2
|
14
|
-
|
15
|
-
before_script:
|
16
|
-
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
17
|
-
- chmod +x ./cc-test-reporter
|
18
|
-
- ./cc-test-reporter before-build
|
19
|
-
after_script:
|
20
|
-
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
21
|
-
|
22
|
-
notifications:
|
23
|
-
email: false
|