edtf 0.0.7 → 0.0.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.
- data/README.md +10 -3
- data/features/parser/uncertain_or_approximate.feature +129 -0
- data/features/print/uncertain_or_approximate.feature +0 -3
- data/lib/edtf/date.rb +2 -1
- data/lib/edtf/parser.y +114 -108
- data/lib/edtf/version.rb +1 -1
- data/spec/edtf/parser_spec.rb +55 -0
- metadata +22 -14
data/README.md
CHANGED
@@ -8,13 +8,18 @@ Specification](http://www.loc.gov/standards/datetime/spec.html).
|
|
8
8
|
Compatibility
|
9
9
|
-------------
|
10
10
|
|
11
|
-
EDTF-Ruby parser implements all levels and features of the EDTF
|
11
|
+
EDTF-Ruby parser implements all levels and features of the EDTF specification
|
12
12
|
(version September 16, 2011). With the following known caveats:
|
13
13
|
|
14
14
|
* Uncertain/approximate seasons will be parsed, but the Season class does
|
15
15
|
not implement attributes.
|
16
|
-
*
|
17
|
-
|
16
|
+
* In the latest revision of the EDTF specification alternative versions of
|
17
|
+
partial uncertain/approximate strings were introduced (with or without nested
|
18
|
+
parentheses); EDTF-Ruby currently uses the version that tries to reduce
|
19
|
+
parentheses for printing as we find that one easier to read; the
|
20
|
+
parser accepts all valid dates using this approach, plus some dates using
|
21
|
+
nested expressions (the parser will not accept some of the more complex
|
22
|
+
examples, though).
|
18
23
|
|
19
24
|
The level 2 list extensions (203 and 204) currently return simple Ruby arrays;
|
20
25
|
therefore, advanced behavior (such as 'earlier' or 'later') is parsed correctly
|
@@ -79,6 +84,8 @@ a Date, you can print the corresponding EDTF string using the `#edtf` method.
|
|
79
84
|
=> true
|
80
85
|
> Date.edtf('2004/open').cover?(Date.today)
|
81
86
|
=> true # an open ended interval covers today
|
87
|
+
> Date.edtf("(1999-(02)~-23)?").edtf
|
88
|
+
=> "1999?-(02)?~-23?" # when printing, EDTF-Ruby reduces nested parentheses
|
82
89
|
|
83
90
|
For additional features take a look at the documentation or the extensive
|
84
91
|
list of rspec examples.
|
@@ -0,0 +1,129 @@
|
|
1
|
+
Feature: Parse partial uncertain or approximate dates
|
2
|
+
As a Ruby programmer
|
3
|
+
I want to convert Date/Time objects to EDTF strings
|
4
|
+
|
5
|
+
@201 @level2
|
6
|
+
Scenario Outline: Prints uncertain or approximate dates
|
7
|
+
When I parse the string "<string>"
|
8
|
+
Then the year should be uncertain? "<?-year>"
|
9
|
+
And the month should be uncertain? "<?-month>"
|
10
|
+
And the day should be uncertain? "<?-day>"
|
11
|
+
And the year should be approximate? "<~-year>"
|
12
|
+
And the month should be approximate? "<~-month>"
|
13
|
+
And the day should be approximate? "<~-day>"
|
14
|
+
|
15
|
+
Scenarios: Uncertain or approximate dates, day precision
|
16
|
+
| date | precision | string | ?-year | ?-month | ?-day | ~-year | ~-month | ~-day |
|
17
|
+
| 2004-06-01 | day | 2004-06-01?~ | yes | yes | yes | yes | yes | yes |
|
18
|
+
| 2004-06-01 | day | 2004-06~-01? | yes | yes | yes | yes | yes | no |
|
19
|
+
| 2004-06-01 | day | (2004~-06-(01)~)? | yes | yes | yes | yes | no | yes |
|
20
|
+
| 2004-06-01 | day | 2004~-06?-(01)?~ | yes | yes | yes | yes | no | yes |
|
21
|
+
| 2004-06-01 | day | 2004~-06-01? | yes | yes | yes | yes | no | no |
|
22
|
+
| 2004-06-01 | day | (2004-(06-01)~)? | yes | yes | yes | no | yes | yes |
|
23
|
+
| 2004-06-01 | day | 2004?-(06-01)?~ | yes | yes | yes | no | yes | yes |
|
24
|
+
| 2004-06-01 | day | (2004-(06)~-01)? | yes | yes | yes | no | yes | no |
|
25
|
+
| 2004-06-01 | day | 2004?-(06)?~-01? | yes | yes | yes | no | yes | no |
|
26
|
+
| 2004-06-01 | day | (2004-06-(01)~)? | yes | yes | yes | no | no | yes |
|
27
|
+
| 2004-06-01 | day | 2004-06?-(01)?~ | yes | yes | yes | no | no | yes |
|
28
|
+
| 2004-06-01 | day | 2004-06-01? | yes | yes | yes | no | no | no |
|
29
|
+
| 2004-06-01 | day | 2004-06?-01~ | yes | yes | no | yes | yes | yes |
|
30
|
+
| 2004-06-01 | day | 2004-06?~-01 | yes | yes | no | yes | yes | no |
|
31
|
+
| 2004-06-01 | day | 2004~-06?-(01)~ | yes | yes | no | yes | no | yes |
|
32
|
+
| 2004-06-01 | day | 2004~-06?-01 | yes | yes | no | yes | no | no |
|
33
|
+
# | 2004-06-01 | day | 2004-(06?-01)~ | yes | yes | no | no | yes | yes | is this correct?
|
34
|
+
# | 2004-06-01 | day | 2004?-((06)?-01)~ | yes | yes | no | no | yes | yes |
|
35
|
+
| 2004-06-01 | day | 2004?-(06)?~-01~ | yes | yes | no | no | yes | yes |
|
36
|
+
# | 2004-06-01 | day | (2004-(06)~)?-01 | yes | yes | no | no | yes | no |
|
37
|
+
| 2004-06-01 | day | 2004?-(06)?~-01 | yes | yes | no | no | yes | no |
|
38
|
+
| 2004-06-01 | day | 2004-06?-(01)~ | yes | yes | no | no | no | yes |
|
39
|
+
| 2004-06-01 | day | 2004-06?-01 | yes | yes | no | no | no | no |
|
40
|
+
| 2004-06-01 | day | (2004?-06-(01)?)~ | yes | no | yes | yes | yes | yes |
|
41
|
+
| 2004-06-01 | day | 2004?-06~-(01)?~ | yes | no | yes | yes | yes | yes |
|
42
|
+
| 2004-06-01 | day | 2004?-06~-(01)? | yes | no | yes | yes | yes | no |
|
43
|
+
| 2004-06-01 | day | 2004?~-06-(01)?~ | yes | no | yes | yes | no | yes |
|
44
|
+
| 2004-06-01 | day | 2004?~-06-(01)? | yes | no | yes | yes | no | no |
|
45
|
+
| 2004-06-01 | day | 2004?-(06-(01)?)~ | yes | no | yes | no | yes | yes |
|
46
|
+
| 2004-06-01 | day | 2004?-(06)~-01?~ | yes | no | yes | no | yes | yes |
|
47
|
+
| 2004-06-01 | day | 2004?-(06)~-01? | yes | no | yes | no | yes | no |
|
48
|
+
| 2004-06-01 | day | 2004?-06-(01)?~ | yes | no | yes | no | no | yes |
|
49
|
+
| 2004-06-01 | day | 2004?-06-(01)? | yes | no | yes | no | no | no |
|
50
|
+
| 2004-06-01 | day | 2004?-06-01~ | yes | no | no | yes | yes | yes |
|
51
|
+
| 2004-06-01 | day | 2004?-06~-01 | yes | no | no | yes | yes | no |
|
52
|
+
| 2004-06-01 | day | 2004?~-06-(01)~ | yes | no | no | yes | no | yes |
|
53
|
+
| 2004-06-01 | day | 2004?~-06-01 | yes | no | no | yes | no | no |
|
54
|
+
| 2004-06-01 | day | 2004?-(06-01)~ | yes | no | no | no | yes | yes |
|
55
|
+
| 2004-06-01 | day | 2004?-(06)~-01 | yes | no | no | no | yes | no |
|
56
|
+
| 2004-06-01 | day | 2004?-06-(01)~ | yes | no | no | no | no | yes |
|
57
|
+
| 2004-06-01 | day | 2004?-06-01 | yes | no | no | no | no | no |
|
58
|
+
| 2004-06-01 | day | (2004-(06-01)?)~ | no | yes | yes | yes | yes | yes |
|
59
|
+
| 2004-06-01 | day | 2004~-(06-01)?~ | no | yes | yes | yes | yes | yes |
|
60
|
+
# | 2004-06-01 | day | 2004-(06~-01)? | no | yes | yes | yes | yes | no | is this correct?
|
61
|
+
# | 2004-06-01 | day | 2004~-((06)~-01)? | no | yes | yes | yes | yes | no |
|
62
|
+
| 2004-06-01 | day | 2004~-(06)?~-01? | no | yes | yes | yes | yes | no |
|
63
|
+
| 2004-06-01 | day | 2004~-(06-(01)~)? | no | yes | yes | yes | no | yes |
|
64
|
+
| 2004-06-01 | day | 2004~-(06)?-01?~ | no | yes | yes | yes | no | yes |
|
65
|
+
| 2004-06-01 | day | 2004~-(06-01)? | no | yes | yes | yes | no | no |
|
66
|
+
| 2004-06-01 | day | 2004-(06-01)?~ | no | yes | yes | no | yes | yes |
|
67
|
+
# | 2004-06-01 | day | 2004-((06)~-01)? | no | yes | yes | no | yes | no |
|
68
|
+
| 2004-06-01 | day | 2004-(06)?~-01? | no | yes | yes | no | yes | no |
|
69
|
+
| 2004-06-01 | day | 2004-(06-(01)~)? | no | yes | yes | no | no | yes |
|
70
|
+
| 2004-06-01 | day | 2004-(06)?-01?~ | no | yes | yes | no | no | yes |
|
71
|
+
| 2004-06-01 | day | 2004-(06-01)? | no | yes | yes | no | no | no |
|
72
|
+
| 2004-06-01 | day | (2004-(06)?-01)~ | no | yes | no | yes | yes | yes |
|
73
|
+
| 2004-06-01 | day | 2004~-(06)?~-01~ | no | yes | no | yes | yes | yes |
|
74
|
+
# | 2004-06-01 | day | (2004-(06)?)~-01 | no | yes | no | yes | yes | no |
|
75
|
+
| 2004-06-01 | day | 2004~-(06)?~-01 | no | yes | no | yes | yes | no |
|
76
|
+
| 2004-06-01 | day | 2004~-(06)?-01~ | no | yes | no | yes | no | yes |
|
77
|
+
| 2004-06-01 | day | 2004~-(06)?-01 | no | yes | no | yes | no | no |
|
78
|
+
# | 2004-06-01 | day | 2004-((06)?-01)~ | no | yes | no | no | yes | yes |
|
79
|
+
| 2004-06-01 | day | 2004-(06)?~-01~ | no | yes | no | no | yes | yes |
|
80
|
+
| 2004-06-01 | day | 2004-(06)?~-01 | no | yes | no | no | yes | no |
|
81
|
+
| 2004-06-01 | day | 2004-(06)?-01~ | no | yes | no | no | no | yes |
|
82
|
+
| 2004-06-01 | day | 2004-(06)?-01 | no | yes | no | no | no | no |
|
83
|
+
| 2004-06-01 | day | (2004-06-(01)?)~ | no | no | yes | yes | yes | yes |
|
84
|
+
| 2004-06-01 | day | 2004-06~-(01)?~ | no | no | yes | yes | yes | yes |
|
85
|
+
| 2004-06-01 | day | 2004-06~-(01)? | no | no | yes | yes | yes | no |
|
86
|
+
| 2004-06-01 | day | 2004~-06-(01)?~ | no | no | yes | yes | no | yes |
|
87
|
+
| 2004-06-01 | day | 2004~-06-(01)? | no | no | yes | yes | no | no |
|
88
|
+
| 2004-06-01 | day | 2004-(06-(01)?)~ | no | no | yes | no | yes | yes |
|
89
|
+
| 2004-06-01 | day | 2004-(06)~-01?~ | no | no | yes | no | yes | yes |
|
90
|
+
| 2004-06-01 | day | 2004-(06)~-01? | no | no | yes | no | yes | no |
|
91
|
+
| 2004-06-01 | day | 2004-06-(01)?~ | no | no | yes | no | no | yes |
|
92
|
+
| 2004-06-01 | day | 2004-06-(01)? | no | no | yes | no | no | no |
|
93
|
+
| 2004-06-01 | day | 2004-06-01~ | no | no | no | yes | yes | yes |
|
94
|
+
| 2004-06-01 | day | 2004-06~-01 | no | no | no | yes | yes | no |
|
95
|
+
| 2004-06-01 | day | 2004~-06-(01)~ | no | no | no | yes | no | yes |
|
96
|
+
| 2004-06-01 | day | 2004~-06-01 | no | no | no | yes | no | no |
|
97
|
+
| 2004-06-01 | day | 2004-(06-01)~ | no | no | no | no | yes | yes |
|
98
|
+
| 2004-06-01 | day | 2004-(06)~-01 | no | no | no | no | yes | no |
|
99
|
+
| 2004-06-01 | day | 2004-06-(01)~ | no | no | no | no | no | yes |
|
100
|
+
| 2004-06-01 | day | 2004-06-01 | no | no | no | no | no | no |
|
101
|
+
|
102
|
+
Scenarios: Uncertain or approximate dates, month precision
|
103
|
+
| date | precision | string | ?-year | ?-month | ?-day | ~-year | ~-month | ~-day |
|
104
|
+
| 2004-06-01 | month | 2004-06?~ | yes | yes | no | yes | yes | no |
|
105
|
+
| 2004-06-01 | month | 2004~-06? | yes | yes | no | yes | no | no |
|
106
|
+
| 2004-06-01 | month | (2004-(06)~)? | yes | yes | no | no | yes | no |
|
107
|
+
| 2004-06-01 | month | 2004?-(06)?~ | yes | yes | no | no | yes | no |
|
108
|
+
| 2004-06-01 | month | 2004-06? | yes | yes | no | no | no | no |
|
109
|
+
| 2004-06-01 | month | 2004?-06~ | yes | no | no | yes | yes | no |
|
110
|
+
| 2004-06-01 | month | 2004?~-06 | yes | no | no | yes | no | no |
|
111
|
+
| 2004-06-01 | month | 2004?-(06)~ | yes | no | no | no | yes | no |
|
112
|
+
| 2004-06-01 | month | 2004?-06 | yes | no | no | no | no | no |
|
113
|
+
| 2004-06-01 | month | (2004-(06)?)~ | no | yes | no | yes | yes | no |
|
114
|
+
| 2004-06-01 | month | 2004~-(06)?~ | no | yes | no | yes | yes | no |
|
115
|
+
| 2004-06-01 | month | 2004~-(06)? | no | yes | no | yes | no | no |
|
116
|
+
| 2004-06-01 | month | 2004-(06)?~ | no | yes | no | no | yes | no |
|
117
|
+
| 2004-06-01 | month | 2004-(06)? | no | yes | no | no | no | no |
|
118
|
+
| 2004-06-01 | month | 2004-06~ | no | no | no | yes | yes | no |
|
119
|
+
| 2004-06-01 | month | 2004~-06 | no | no | no | yes | no | no |
|
120
|
+
| 2004-06-01 | month | 2004-(06)~ | no | no | no | no | yes | no |
|
121
|
+
| 2004-06-01 | month | 2004-06 | no | no | no | no | no | no |
|
122
|
+
|
123
|
+
|
124
|
+
Scenarios: Uncertain or approximate dates, year precision
|
125
|
+
| date | precision | string | ?-year | ?-month | ?-day | ~-year | ~-month | ~-day |
|
126
|
+
| 2004-06-01 | year | 2004?~ | yes | no | no | yes | no | no |
|
127
|
+
| 2004-06-01 | year | 2004? | yes | no | no | no | no | no |
|
128
|
+
| 2004-06-01 | year | 2004~ | no | no | no | yes | no | no |
|
129
|
+
| 2004-06-01 | year | 2004 | no | no | no | no | no | no |
|
@@ -14,7 +14,6 @@ Feature: Print uncertain or approximate dates
|
|
14
14
|
When I convert the date
|
15
15
|
Then the EDTF string should be "<string>"
|
16
16
|
|
17
|
-
@wip
|
18
17
|
Scenarios: Uncertain or approximate dates, day precision
|
19
18
|
| date | precision | string | ?-year | ?-month | ?-day | ~-year | ~-month | ~-day |
|
20
19
|
| 2004-06-01 | day | 2004-06-01?~ | yes | yes | yes | yes | yes | yes |
|
@@ -102,7 +101,6 @@ Feature: Print uncertain or approximate dates
|
|
102
101
|
| 2004-06-01 | day | 2004-06-(01)~ | no | no | no | no | no | yes |
|
103
102
|
| 2004-06-01 | day | 2004-06-01 | no | no | no | no | no | no |
|
104
103
|
|
105
|
-
@wip
|
106
104
|
Scenarios: Uncertain or approximate dates, month precision
|
107
105
|
| date | precision | string | ?-year | ?-month | ?-day | ~-year | ~-month | ~-day |
|
108
106
|
| 2004-06-01 | month | 2004-06?~ | yes | yes | no | yes | yes | no |
|
@@ -125,7 +123,6 @@ Feature: Print uncertain or approximate dates
|
|
125
123
|
| 2004-06-01 | month | 2004-06 | no | no | no | no | no | no |
|
126
124
|
|
127
125
|
|
128
|
-
@wip
|
129
126
|
Scenarios: Uncertain or approximate dates, year precision
|
130
127
|
| date | precision | string | ?-year | ?-month | ?-day | ~-year | ~-month | ~-day |
|
131
128
|
| 2004-06-01 | year | 2004?~ | yes | no | no | yes | no | no |
|
data/lib/edtf/date.rb
CHANGED
@@ -266,9 +266,10 @@ class Date
|
|
266
266
|
|
267
267
|
# Returns true if this Date/Time has year precision and the year exceeds four digits.
|
268
268
|
def long_year?
|
269
|
-
|
269
|
+
year_precision? && year.abs > 9999
|
270
270
|
end
|
271
271
|
|
272
|
+
|
272
273
|
private
|
273
274
|
|
274
275
|
def ua_hash
|
data/lib/edtf/parser.y
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
class EDTF::Parser
|
4
4
|
|
5
|
-
token T Z E X U UNKNOWN OPEN LONGYEAR UNMATCHED DOTS PUA
|
5
|
+
token T Z E X U UNKNOWN OPEN LONGYEAR UNMATCHED DOTS UA PUA
|
6
6
|
|
7
7
|
expect 0
|
8
8
|
|
@@ -25,9 +25,9 @@ rule
|
|
25
25
|
;
|
26
26
|
|
27
27
|
positive_date :
|
28
|
-
year { result = Date.new(val[0])
|
29
|
-
| year_month { result = Date.new(*val.flatten)
|
30
|
-
| year_month_day { result = Date.new(*val.flatten)
|
28
|
+
year { result = Date.new(val[0]).year_precision! }
|
29
|
+
| year_month { result = Date.new(*val.flatten).month_precision! }
|
30
|
+
| year_month_day { result = Date.new(*val.flatten).day_precision! }
|
31
31
|
;
|
32
32
|
|
33
33
|
negative_date : '-' positive_date { result = -val[1] }
|
@@ -65,6 +65,7 @@ rule
|
|
65
65
|
}
|
66
66
|
|
67
67
|
month : d01_12
|
68
|
+
day : d01_31
|
68
69
|
|
69
70
|
year_month : year '-' month { result = [val[0], val[2]] }
|
70
71
|
|
@@ -72,7 +73,7 @@ rule
|
|
72
73
|
# do not consider leap years, as the EDTF BNF did not either.
|
73
74
|
# NB: an exception will be raised regardless, because the Ruby Date
|
74
75
|
# implementation calculates leap years.
|
75
|
-
year_month_day : year_month '-'
|
76
|
+
year_month_day : year_month '-' day {
|
76
77
|
result = val[0] << val[2]
|
77
78
|
if result[2] > 31 || (result[2] > 30 && [2,4,6,9,11].include?(result[1])) || (result[2] > 29 && result[1] == 2)
|
78
79
|
raise ArgumentError, "invalid date (invalid days #{result[2]} for month #{result[1]})"
|
@@ -92,13 +93,12 @@ rule
|
|
92
93
|
# NB: Uncertain/approximate Dates are covered by the Level 2 rules
|
93
94
|
level_1_expression : unspecified | level_1_interval | long_year_simple | season
|
94
95
|
|
95
|
-
# uncertain_or_approximate_date : date
|
96
|
+
# uncertain_or_approximate_date : date UA { result = uoa(val[0], val[1]) }
|
96
97
|
|
97
98
|
unspecified : unspecified_year
|
98
99
|
{
|
99
|
-
result = Date.new(val[0][0])
|
100
|
+
result = Date.new(val[0][0]).year_precision!
|
100
101
|
result.unspecified.year[2,2] = val[0][1]
|
101
|
-
result.precision = :year
|
102
102
|
}
|
103
103
|
| unspecified_month
|
104
104
|
| unspecified_day
|
@@ -159,7 +159,8 @@ rule
|
|
159
159
|
;
|
160
160
|
|
161
161
|
|
162
|
-
|
162
|
+
# TODO uncertain/approximate seasons
|
163
|
+
season : year '-' season_number ua { result = Season.new(val[0], val[2]) }
|
163
164
|
|
164
165
|
season_number : '2' '1' { result = 21 }
|
165
166
|
| '2' '2' { result = 22 }
|
@@ -186,39 +187,36 @@ rule
|
|
186
187
|
|
187
188
|
|
188
189
|
long_year_scientific :
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
result.precision = :year
|
198
|
-
}
|
190
|
+
long_year_simple E integer
|
191
|
+
{
|
192
|
+
result = Date.new(val[0].year * 10 ** val[2]).year_precision!
|
193
|
+
}
|
194
|
+
| LONGYEAR int1_4 E integer
|
195
|
+
{
|
196
|
+
result = Date.new(val[1] * 10 ** val[3]).year_precision!
|
197
|
+
}
|
199
198
|
| LONGYEAR '-' int1_4 E integer
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
;
|
199
|
+
{
|
200
|
+
result = Date.new(-1 * val[2] * 10 ** val[4]).year_precision!
|
201
|
+
}
|
202
|
+
;
|
205
203
|
|
206
204
|
|
207
205
|
date_and_calendar : date '^' { result = val[0]; result.calendar = val[1] }
|
208
206
|
|
209
207
|
|
210
208
|
masked_precision :
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
209
|
+
digit digit digit X
|
210
|
+
{
|
211
|
+
d = val[0,3].zip([1000,100,10]).reduce(0) { |s,(a,b)| s += a * b }
|
212
|
+
result = Date.new(d) ... Date.new(d+10)
|
213
|
+
}
|
216
214
|
| digit digit X X
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
215
|
+
{
|
216
|
+
d = val[0,2].zip([1000,100]).reduce(0) { |s,(a,b)| s += a * b }
|
217
|
+
result = Date.new(d) ... Date.new(d+100)
|
218
|
+
}
|
219
|
+
;
|
222
220
|
|
223
221
|
|
224
222
|
choice_list : '[' list ']' { result = val[1] }
|
@@ -232,37 +230,37 @@ rule
|
|
232
230
|
| list_elements ',' later { result = val[0] + [val[2]] }
|
233
231
|
| list_elements
|
234
232
|
| later { result = val }
|
235
|
-
|
233
|
+
;
|
236
234
|
|
237
235
|
list_elements : list_element { result = [val[0]].flatten }
|
238
236
|
| list_elements ',' list_element { result = val[0] + [val[2]].flatten }
|
239
|
-
|
237
|
+
;
|
240
238
|
|
241
239
|
list_element : date
|
242
240
|
| partial_uncertain_or_approximate
|
243
241
|
| unspecified
|
244
242
|
| consecutives { result = val[0].map { |d| Date.new(*d) } }
|
245
|
-
|
243
|
+
;
|
246
244
|
|
247
245
|
earlier : DOTS date { result = val[1] }
|
248
246
|
|
249
|
-
later : year_month_day DOTS { result = Date.new(*val[0])
|
250
|
-
| year_month DOTS { result = Date.new(*val[0])
|
251
|
-
| year DOTS { result = Date.new(val[0])
|
252
|
-
|
247
|
+
later : year_month_day DOTS { result = Date.new(*val[0]).year_precision! }
|
248
|
+
| year_month DOTS { result = Date.new(*val[0]).month_precision! }
|
249
|
+
| year DOTS { result = Date.new(val[0]).year_precision! }
|
250
|
+
;
|
253
251
|
|
254
252
|
consecutives : year_month_day DOTS year_month_day
|
255
253
|
| year_month DOTS year_month
|
256
254
|
| year DOTS year { result = (val[0]..val[2]).to_a.map }
|
257
|
-
|
255
|
+
;
|
258
256
|
|
259
257
|
partial_unspecified :
|
260
|
-
unspecified_year '-' month '-'
|
258
|
+
unspecified_year '-' month '-' day
|
261
259
|
{
|
262
260
|
result = Date.new(val[0][0], val[2], val[4])
|
263
261
|
result.unspecified.year[2,2] = val[0][1]
|
264
262
|
}
|
265
|
-
| unspecified_year '-' U U '-'
|
263
|
+
| unspecified_year '-' U U '-' day
|
266
264
|
{
|
267
265
|
result = Date.new(val[0][0], 1, val[5])
|
268
266
|
result.unspecified.year[2,2] = val[0][1]
|
@@ -280,7 +278,7 @@ rule
|
|
280
278
|
result.unspecified.year[2,2] = val[0][1]
|
281
279
|
result.unspecified!(:day)
|
282
280
|
}
|
283
|
-
| year '-' U U '-'
|
281
|
+
| year '-' U U '-' day
|
284
282
|
{
|
285
283
|
result = Date.new(val[0], 1, val[5])
|
286
284
|
result.unspecified!(:month)
|
@@ -289,71 +287,71 @@ rule
|
|
289
287
|
|
290
288
|
|
291
289
|
partial_uncertain_or_approximate : pua_base
|
292
|
-
| '(' pua_base ')'
|
290
|
+
| '(' pua_base ')' UA { result = uoa(val[1], val[3]) }
|
293
291
|
|
294
292
|
pua_base :
|
295
|
-
pua_year { result = val[0]
|
296
|
-
| pua_year_month { result = val[0]
|
297
|
-
| pua_year_month_day
|
293
|
+
pua_year { result = val[0].year_precision! }
|
294
|
+
| pua_year_month { result = val[0][0].month_precision! }
|
295
|
+
| pua_year_month_day { result = val[0].day_precision! }
|
298
296
|
|
299
|
-
pua_year : year
|
297
|
+
pua_year : year UA { result = uoa(Date.new(val[0]), val[1], :year) }
|
300
298
|
|
301
299
|
pua_year_month :
|
302
|
-
pua_year '-' month
|
303
|
-
|
304
|
-
result = uoa(val[0].change(:month => val[2]), val[3], [:month, :year])
|
300
|
+
pua_year '-' month ua {
|
301
|
+
result = [uoa(val[0].change(:month => val[2]), val[3], [:month, :year])]
|
305
302
|
}
|
306
|
-
| '
|
307
|
-
|
308
|
-
result = uoa(uoa(val[1], val[2], :year).change(:month => val[3]), val[4], :month)
|
303
|
+
| year '-' month UA {
|
304
|
+
result = [uoa(Date.new(val[0], val[2]), val[3], [:year, :month])]
|
309
305
|
}
|
310
|
-
| year '-' month
|
311
|
-
|
312
|
-
result = uoa(Date.new(val[0], val[2]), val[3], [:year, :month])
|
306
|
+
| year '-(' month ')' UA {
|
307
|
+
result = [uoa(Date.new(val[0], val[2]), val[4], [:month]), true]
|
313
308
|
}
|
314
|
-
|
|
315
|
-
|
316
|
-
result = uoa(Date.new(val[0], val[3]), val[5], [:month])
|
309
|
+
| pua_year '-(' month ')' UA {
|
310
|
+
result = [uoa(val[0].change(:month => val[2]), val[4], [:month]), true]
|
317
311
|
}
|
318
312
|
;
|
319
313
|
|
320
314
|
pua_year_month_day :
|
321
|
-
pua_year_month '-'
|
322
|
-
|
323
|
-
result = uoa(val[0].change(:day => val[2]), val[3])
|
315
|
+
pua_year_month '-' day ua {
|
316
|
+
result = uoa(val[0][0].change(:day => val[2]), val[3], val[0][1] ? [:day] : nil)
|
324
317
|
}
|
325
|
-
| pua_year_month '-
|
326
|
-
|
327
|
-
result = uoa(val[0].change(:day => val[3]), val[5], [:day])
|
318
|
+
| pua_year_month '-(' day ')' UA {
|
319
|
+
result = uoa(val[0][0].change(:day => val[2]), val[4], [:day])
|
328
320
|
}
|
329
|
-
| '('
|
330
|
-
|
331
|
-
result = uoa(uoa(val[1], val[2], [:year, :month]).change(:day => val[3]), val[4], :day)
|
321
|
+
| year '-(' month ')' UA day ua {
|
322
|
+
result = uoa(uoa(Date.new(val[0], val[2], val[5]), val[4], :month), val[6], :day)
|
332
323
|
}
|
333
|
-
|
|
334
|
-
|
335
|
-
result = uoa(uoa(Date.new(val[0], val[3], val[5]), val[4], :month), val[6], :day)
|
324
|
+
| year_month '-' day UA {
|
325
|
+
result = uoa(Date.new(val[0][0], val[0][1], val[2]), val[3])
|
336
326
|
}
|
337
|
-
| year_month '-'
|
338
|
-
|
339
|
-
result = uoa(Date.new(val[0][0], val[0][1], val[2]), val[3])
|
327
|
+
| year_month '-(' day ')' UA {
|
328
|
+
result = uoa(Date.new(val[0][0], val[0][1], val[2]), val[4], [:day])
|
340
329
|
}
|
341
|
-
|
|
342
|
-
|
343
|
-
result = uoa(Date.new(val[0][0], val[0][1], val[3]), val[5], [:day])
|
330
|
+
| year '-(' month '-' day ')' UA {
|
331
|
+
result = uoa(Date.new(val[0], val[2], val[4]), val[6], [:month, :day])
|
344
332
|
}
|
345
|
-
| year '-' '('
|
346
|
-
|
347
|
-
|
333
|
+
| year '-(' month '-(' day ')' UA ')' UA {
|
334
|
+
result = Date.new(val[0], val[2], val[4])
|
335
|
+
result = uoa(result, val[6], [:day])
|
336
|
+
result = uoa(result, val[8], [:month, :day])
|
348
337
|
}
|
338
|
+
| pua_year '-(' month '-' day ')' UA {
|
339
|
+
result = val[0].change(:month => val[2], :day => val[4])
|
340
|
+
result = uoa(result, val[6], [:month, :day])
|
341
|
+
}
|
342
|
+
| pua_year '-(' month '-(' day ')' UA ')' UA {
|
343
|
+
result = val[0].change(:month => val[2], :day => val[4])
|
344
|
+
result = uoa(result, val[6], [:day])
|
345
|
+
result = uoa(result, val[8], [:month, :day])
|
346
|
+
}
|
347
|
+
# | '(' pua_year '-(' month ')' UA ')' UA '-' day ua {
|
348
|
+
# result = val[1].change(:month => val[3], :day => val[9])
|
349
|
+
# result = uoa(result, val[5], [:month])
|
350
|
+
# result = [uoa(result, val[7], [:year]), true]
|
351
|
+
# }
|
349
352
|
;
|
350
353
|
|
351
|
-
|
352
|
-
|
353
|
-
ua : '?'
|
354
|
-
| '~'
|
355
|
-
| '?' '~' { result = val.flatten }
|
356
|
-
;
|
354
|
+
ua : { result = [] } | UA
|
357
355
|
|
358
356
|
# ---- Auxiliary Rules ----
|
359
357
|
|
@@ -438,7 +436,7 @@ require 'strscan'
|
|
438
436
|
@defaults = {
|
439
437
|
:level => 2,
|
440
438
|
:debug => false
|
441
|
-
}
|
439
|
+
}.freeze
|
442
440
|
|
443
441
|
class << self; attr_reader :defaults; end
|
444
442
|
|
@@ -448,22 +446,26 @@ require 'strscan'
|
|
448
446
|
@options = Parser.defaults.merge(options)
|
449
447
|
end
|
450
448
|
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
449
|
+
def debug?
|
450
|
+
!!(options[:debug] || ENV['DEBUG'])
|
451
|
+
end
|
452
|
+
|
453
|
+
def parse(input)
|
454
|
+
parse!(input)
|
455
|
+
rescue => e
|
456
|
+
warn e.message if debug?
|
457
|
+
nil
|
458
|
+
end
|
459
|
+
|
458
460
|
def parse!(input)
|
459
|
-
@yydebug =
|
461
|
+
@yydebug = debug?
|
460
462
|
@src = StringScanner.new(input)
|
461
463
|
do_parse
|
462
464
|
end
|
463
465
|
|
464
|
-
def on_error(tid,
|
466
|
+
def on_error(tid, value, stack)
|
465
467
|
raise ArgumentError,
|
466
|
-
|
468
|
+
"failed to parse date: unexpected '#{value}' at #{stack.inspect}"
|
467
469
|
end
|
468
470
|
|
469
471
|
def apply_uncertainty(date, uncertainty, scope = nil)
|
@@ -483,12 +485,12 @@ require 'strscan'
|
|
483
485
|
# ignore whitespace
|
484
486
|
when @src.scan(/\(/)
|
485
487
|
['(', @src.matched]
|
486
|
-
when @src.scan(/\)\?~-/)
|
487
|
-
|
488
|
-
when @src.scan(/\)\?-/)
|
489
|
-
|
490
|
-
when @src.scan(/\)~-/)
|
491
|
-
|
488
|
+
# when @src.scan(/\)\?~-/)
|
489
|
+
# [:PUA, [:uncertain!, :approximate!]]
|
490
|
+
# when @src.scan(/\)\?-/)
|
491
|
+
# [:PUA, [:uncertain!]]
|
492
|
+
# when @src.scan(/\)~-/)
|
493
|
+
# [:PUA, [:approximate!]]
|
492
494
|
when @src.scan(/\)/)
|
493
495
|
[')', @src.matched]
|
494
496
|
when @src.scan(/\[/)
|
@@ -503,10 +505,12 @@ require 'strscan'
|
|
503
505
|
[:T, @src.matched]
|
504
506
|
when @src.scan(/Z/)
|
505
507
|
[:Z, @src.matched]
|
508
|
+
when @src.scan(/\?~/)
|
509
|
+
[:UA, [:uncertain!, :approximate!]]
|
506
510
|
when @src.scan(/\?/)
|
507
|
-
[
|
511
|
+
[:UA, [:uncertain!]]
|
508
512
|
when @src.scan(/~/)
|
509
|
-
[
|
513
|
+
[:UA, [:approximate!]]
|
510
514
|
when @src.scan(/open/i)
|
511
515
|
[:OPEN, :open]
|
512
516
|
when @src.scan(/unkn?own/i) # matches 'unkown' typo too
|
@@ -521,6 +525,8 @@ require 'strscan'
|
|
521
525
|
[:E, @src.matched]
|
522
526
|
when @src.scan(/\+/)
|
523
527
|
['+', @src.matched]
|
528
|
+
when @src.scan(/-\(/)
|
529
|
+
['-(', @src.matched]
|
524
530
|
when @src.scan(/-/)
|
525
531
|
['-', @src.matched]
|
526
532
|
when @src.scan(/:/)
|
data/lib/edtf/version.rb
CHANGED
data/spec/edtf/parser_spec.rb
CHANGED
@@ -270,14 +270,69 @@ module EDTF
|
|
270
270
|
|
271
271
|
it 'parses "2004~-(06)?-01~": year and day approximate, month uncertain' do
|
272
272
|
d = Parser.new.parse!("2004~-(06)?-01~")
|
273
|
+
|
274
|
+
d.approximate?(:year).should be true
|
275
|
+
d.uncertain?(:year).should be false
|
276
|
+
|
277
|
+
d.approximate?(:month).should be false
|
278
|
+
d.uncertain?(:month).should be true
|
279
|
+
|
280
|
+
d.approximate?(:day).should be true
|
281
|
+
d.uncertain?(:day).should be false
|
273
282
|
end
|
274
283
|
|
275
284
|
it 'parses "2004~-(06-(01)~)?": year and day approximate, month and day uncertain' do
|
276
285
|
d = Parser.new.parse!("2004~-(06-(01)~)?")
|
286
|
+
|
287
|
+
d.approximate?(:year).should be true
|
288
|
+
d.uncertain?(:year).should be false
|
289
|
+
|
290
|
+
d.approximate?(:month).should be false
|
291
|
+
d.uncertain?(:month).should be true
|
292
|
+
|
293
|
+
d.approximate?(:day).should be true
|
294
|
+
d.uncertain?(:day).should be true
|
277
295
|
end
|
278
296
|
|
279
297
|
it 'parses "2004~-(06)?-01?~": year and day approximate, month and day uncertain' do
|
280
298
|
d = Parser.new.parse!("2004~-(06)?-01?~")
|
299
|
+
|
300
|
+
d.approximate?(:year).should be true
|
301
|
+
d.uncertain?(:year).should be false
|
302
|
+
|
303
|
+
d.approximate?(:month).should be false
|
304
|
+
d.uncertain?(:month).should be true
|
305
|
+
|
306
|
+
d.approximate?(:day).should be true
|
307
|
+
d.uncertain?(:day).should be true
|
308
|
+
end
|
309
|
+
|
310
|
+
it 'parses "2004~-(06)?": year approximate, month uncertain' do
|
311
|
+
d = Parser.new.parse!("2004~-(06)?")
|
312
|
+
|
313
|
+
d.approximate?(:year).should be true
|
314
|
+
d.uncertain?(:year).should be false
|
315
|
+
|
316
|
+
d.approximate?(:month).should be false
|
317
|
+
d.uncertain?(:month).should be true
|
318
|
+
|
319
|
+
d.approximate?(:day).should be false
|
320
|
+
d.uncertain?(:day).should be false
|
321
|
+
end
|
322
|
+
|
323
|
+
|
324
|
+
it 'parses "2004~-06?": year approximate, year and month uncertain' do
|
325
|
+
d = Parser.new.parse!("2004~-06?")
|
326
|
+
|
327
|
+
d.approximate?(:year).should be true
|
328
|
+
d.uncertain?(:year).should be true
|
329
|
+
|
330
|
+
d.approximate?(:month).should be false
|
331
|
+
d.uncertain?(:month).should be true
|
332
|
+
|
333
|
+
d.approximate?(:day).should be false
|
334
|
+
d.uncertain?(:day).should be false
|
335
|
+
|
281
336
|
end
|
282
337
|
|
283
338
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: edtf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-11-
|
12
|
+
date: 2011-11-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
16
|
-
requirement: &
|
16
|
+
requirement: &70235877316060 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '3.0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70235877316060
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &70235877525400 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0.9'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70235877525400
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: racc
|
38
|
-
requirement: &
|
38
|
+
requirement: &70235877523860 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '1.4'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70235877523860
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: cucumber
|
49
|
-
requirement: &
|
49
|
+
requirement: &70235877522840 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '1.0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70235877522840
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rspec
|
60
|
-
requirement: &
|
60
|
+
requirement: &70235877521760 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '2.6'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70235877521760
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: ZenTest
|
71
|
-
requirement: &
|
71
|
+
requirement: &70235877521200 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,7 +76,7 @@ dependencies:
|
|
76
76
|
version: '4.6'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70235877521200
|
80
80
|
description: A Ruby implementation of the Extended Date/Time Format (EDTF).
|
81
81
|
email:
|
82
82
|
- http://sylvester.keil.or.at
|
@@ -98,6 +98,7 @@ files:
|
|
98
98
|
- features/parser/dates.feature
|
99
99
|
- features/parser/intervals.feature
|
100
100
|
- features/parser/precision.feature
|
101
|
+
- features/parser/uncertain_or_approximate.feature
|
101
102
|
- features/parser/unspecified.feature
|
102
103
|
- features/print/level_0_edtf.feature
|
103
104
|
- features/print/level_1_edtf.feature
|
@@ -144,12 +145,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
144
145
|
- - ! '>='
|
145
146
|
- !ruby/object:Gem::Version
|
146
147
|
version: '0'
|
148
|
+
segments:
|
149
|
+
- 0
|
150
|
+
hash: -533372685399765203
|
147
151
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
152
|
none: false
|
149
153
|
requirements:
|
150
154
|
- - ! '>='
|
151
155
|
- !ruby/object:Gem::Version
|
152
156
|
version: '0'
|
157
|
+
segments:
|
158
|
+
- 0
|
159
|
+
hash: -533372685399765203
|
153
160
|
requirements: []
|
154
161
|
rubyforge_project:
|
155
162
|
rubygems_version: 1.8.10
|
@@ -161,6 +168,7 @@ test_files:
|
|
161
168
|
- features/parser/dates.feature
|
162
169
|
- features/parser/intervals.feature
|
163
170
|
- features/parser/precision.feature
|
171
|
+
- features/parser/uncertain_or_approximate.feature
|
164
172
|
- features/parser/unspecified.feature
|
165
173
|
- features/print/level_0_edtf.feature
|
166
174
|
- features/print/level_1_edtf.feature
|