Skip to content

Commit df6b92e

Browse files
committed
Add util module
1 parent 9d3b9d3 commit df6b92e

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

gedcom7/util.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
"""Utility functions for GEDCOM 7 processing."""
2+
3+
import datetime
4+
5+
from . import const, types
6+
7+
8+
def get_first_child_with_tag(
9+
structure: types.GedcomStructure, tag: str
10+
) -> types.GedcomStructure | None:
11+
"""Get the first child of a GEDCOM structure with a specific tag.
12+
13+
If no child with the specified tag is found, return None.
14+
"""
15+
for child in structure.children:
16+
if child.tag == tag:
17+
return child
18+
return None
19+
20+
21+
def date_exact_to_python_date(date: types.DateExact) -> datetime.date:
22+
"""Convert a GEDCOM DateExact to a Python date."""
23+
try:
24+
month = const.GEDCOM_MONTHS[date.month.upper()]
25+
except KeyError:
26+
raise ValueError(f"Invalid month in date: {date.month}")
27+
return datetime.date(year=date.year, month=month, day=date.day)
28+
29+
30+
def time_to_python_time(time: types.Time) -> datetime.time:
31+
"""Convert a GEDCOM Time to a Python time."""
32+
second = 0
33+
microsecond = 0
34+
if time.second:
35+
second = time.second
36+
if time.fraction:
37+
fraction = float(f"0.{time.fraction}")
38+
microsecond = int(fraction * 1_000_000)
39+
return datetime.time(
40+
hour=time.hour,
41+
minute=time.minute,
42+
second=second,
43+
microsecond=microsecond,
44+
tzinfo=datetime.timezone.utc,
45+
)
46+
47+
48+
def date_exact_and_time_to_python_datetime(
49+
date: types.DateExact, time: types.Time | None = None
50+
) -> datetime.datetime:
51+
"""Convert a GEDCOM date and optional time to a Python datetime."""
52+
date_obj = date_exact_to_python_date(date)
53+
if time:
54+
time_obj = time_to_python_time(time)
55+
return datetime.datetime.combine(date_obj, time_obj)
56+
return datetime.datetime.combine(
57+
date_obj, datetime.time.min, tzinfo=datetime.timezone.utc
58+
)

0 commit comments

Comments
 (0)