Skip to content

Commit 4caa6fe

Browse files
geostagDr. Georg Ostertag
andauthored
GEDCOM specification compliance: DatePeriod and Date (#3)
* fix dateperiod pattern * change date parsing to accept empty day; add test * chore: cleanup * cleanup dateperiod; special case epoch * align with updated GEDCOM7 definition --------- Co-authored-by: Dr. Georg Ostertag <[email protected]>
1 parent 95b76bc commit 4caa6fe

File tree

3 files changed

+42
-5
lines changed

3 files changed

+42
-5
lines changed

gedcom7/grammar.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,19 @@
2121
ucletter = '[A-Z]'
2222
tagchar = f'({ucletter}|[0-9]|{underscore})'
2323
exttag = f'{underscore}({tagchar})+'
24-
calendar = f'(GREGORIAN|JULIAN|FRENCH_R|HEBREW|{exttag})'
24+
daterestrict = 'FROM|TO|BET|AND|BEF|AFT|ABT|CAL|EST'
25+
calendar = f'(?!{daterestrict})(GREGORIAN|JULIAN|FRENCH_R|HEBREW|{exttag})'
2526
day = f'{integer}'
2627
stdtag = f'{ucletter}({tagchar})*'
27-
month = f'({stdtag}|{exttag})'
28+
month = f'(?!{daterestrict})({stdtag}|{exttag})'
2829
year = f'{integer}'
29-
epoch = f'(BCE|{exttag})'
30+
epoch = f'(?!{daterestrict})(BCE|{exttag})'
3031
date = f'({calendar}{d})?(({day}{d})?{month}{d})?{year}({d}{epoch})?'
3132
date_capture = f'((?P<calendar>{calendar}){d})?(((?P<day>{day}){d})?(?P<month>{month}){d})?(?P<year>{year})({d}(?P<epoch>{epoch}))?'
3233
dateapprox = f'(?P<qualifier>ABT|CAL|EST){d}(?P<dateapprox>{date})'
3334
dateexact = f'(?P<day>{day}){d}(?P<month>{month}){d}(?P<year>{year})'
3435
dateperiod = f'((TO{d}(?P<todate1>{date}))?|FROM{d}(?P<fromdate>{date})({d}TO{d}(?P<todate2>{date}))?)'
3536
daterange = f'(BET{d}(?P<between>{date}){d}AND{d}(?P<and>{date})|AFT{d}(?P<after>{date})|BEF{d}(?P<before>{date}))'
36-
daterestrict = '(FROM|TO|BET|AND|BEF|AFT|ABT|CAL|EST|BCE)'
3737
datevalue = f'({date}|{dateperiod}|{daterange}|{dateapprox})?'
3838
tag = f'({stdtag}|{exttag})'
3939
enum = f'{tag}'

gedcom7/types.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ def parse(self) -> Dict[str, Union[str, int]]:
234234
match = self.match.groupdict()
235235
return {
236236
"calendar": match["calendar"],
237-
"day": int(match["day"]),
237+
"day": int(match["day"]) if match["day"] else None,
238238
"month": match["month"],
239239
"year": int(match["year"]),
240240
"epoch": match["epoch"],

test/test_types.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,27 @@ def test_date():
126126
"year": 2022,
127127
"epoch": "BCE",
128128
}
129+
assert T.DateValue("11 JAN 2022").parse() == {
130+
"calendar": None,
131+
"day": 11,
132+
"month": "JAN",
133+
"year": 2022,
134+
"epoch": None,
135+
}
136+
assert T.DateValue("JAN 2022").parse() == {
137+
"calendar": None,
138+
"day": None,
139+
"month": "JAN",
140+
"year": 2022,
141+
"epoch": None,
142+
}
143+
assert T.DateValue("2022").parse() == {
144+
"calendar": None,
145+
"day": None,
146+
"month": None,
147+
"year": 2022,
148+
"epoch": None,
149+
}
129150

130151

131152
def test_dateperiod():
@@ -149,6 +170,22 @@ def test_dateperiod():
149170
"epoch": None,
150171
},
151172
}
173+
assert T.DatePeriod("FROM 2021 TO 2022").parse() == {
174+
"from": {
175+
"calendar": None,
176+
"year": 2021,
177+
"month": None,
178+
"day": None,
179+
"epoch": None,
180+
},
181+
"to": {
182+
"calendar": None,
183+
"year": 2022,
184+
"month": None,
185+
"day": None,
186+
"epoch": None,
187+
},
188+
}
152189
assert T.DatePeriod("FROM 1 JAN 2021 TO 11 JAN 2022").parse() == {
153190
"from": {
154191
"calendar": None,

0 commit comments

Comments
 (0)