edtf 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|