GEDCOM Date Handling
Relevant source files
The following files were used as context for generating this wiki page:
The Vata application implements a robust system for handling genealogical dates according to the GEDCOM 5.5.1 standard. This system ensures that dates—which may be exact, approximate, ranges, or periods—are correctly parsed from files, stored in the database with high fidelity, and made searchable via normalized sort strings. Sources: README.md:16, src/gedcom-date/types.ts
This module is critical for maintaining chronological integrity across the family tree, supporting features like age calculation, event sequencing, and interoperability with other genealogy software through standard GEDCOM import and export workflows. Sources: src/gedcom-date/sort.ts:133-150, src/lib/gedcom/importer.ts:12-16
Core Architecture and Data Structures
The system represents dates using structured TypeScript interfaces that capture the complexity of genealogical time. Instead of simple timestamps, dates are categorized by type (simple, range, or period) and can include modifiers like "ABT" (about) or "BEF" (before). Sources: src/gedcom-date/types.ts
Date Representation
| Component | Description |
|---|---|
DatePoint | Represents a specific point in time with year, month (optional), and day (optional). Supports BC years via negative integers. |
GedcomDate | A union type for date structures: simple, range, or period. |
Modifier | Qualifiers for simple dates, such as ABT, CAL, EST, BEF, or AFT. |
Sources: src/gedcom-date/types.ts, src/gedcom-date/sort.ts:46-56
Data Flow for Date Processing
The following diagram illustrates how a raw date string from a GEDCOM file is processed into the system's internal representation and database storage.
The system maintains both the original string for display and a normalized sort string for querying. Sources: src/lib/gedcom/importer.ts:79-88, src/gedcom-date/sort.ts:10-33
Date Parsing and Normalization
During GEDCOM parsing, date strings are extracted from DATE tags within events (e.g., BIRT, DEAT, MARR). Sources: src/gedcom-parser/parse.ts:255-260
Sort Date Generation
To enable database-level sorting, the system converts complex GedcomDate objects into ISO 8601-like strings (YYYY-MM-DD). This normalization follows specific rules:
- Defaulting: Missing months and days default to
01. - Complex Types: Ranges and periods typically use the "start" or "from" date for sorting.
- BC Dates: Handled by padding the year and adding a negative sign (e.g.,
-0500-01-01). - Modifiers: Modifiers like "About" or "Calculated" are ignored for the purpose of the sort string to ensure they appear in the correct chronological sequence.
Sources: src/gedcom-date/sort.ts:10-44
// Example of sort date conversion
// 15 JAN 1845 -> "1845-01-15"
// 1845 -> "1845-01-01"
function datePointToSortDate(point: DatePoint): string {
const year = String(Math.abs(point.year)).padStart(4, '0');
const month = String(point.month ?? 1).padStart(2, '0');
const day = String(point.day ?? 1).padStart(2, '0');
if (point.year < 0) {
return `-${year}-${month}-${day}`;
}
return `${year}-${month}-${day}`;
}
Sources: src/gedcom-date/sort.ts:46-58
Chronological Logic and Age Calculation
The system provides utilities for comparing dates and calculating ages, which is essential for determining if individuals are still living or for validating the tree's logical consistency.
Comparison Logic
Dates are compared numerically using their sort strings. This handles BC dates correctly where standard string comparison (localeCompare) might fail. Sources: src/gedcom-date/sort.ts:70-85
Age Calculation
The calculateAge function determines the number of years between two GedcomDate objects. It adjusts the result if the anniversary of the birth has not yet occurred in the event year. If either date is approximate or a range, the age is flagged as approximate. Sources: src/gedcom-date/sort.ts:133-165
Sources: src/gedcom-date/sort.ts:145-163
Integration in GEDCOM Import
The importGedcom module utilizes the date handling system to populate the database during file ingestion. The tryParseSortDate helper attempts to derive a sortable value, but the system always preserves the original raw string in the date_original column to ensure no data loss occurs if the date is non-standard. Sources: src/lib/gedcom/importer.ts:79-88, src/lib/gedcom/importer.ts:182-191
Living Status Determination
The system uses the presence of a DEAT (Death) event as a primary indicator of whether an individual is living. This logic is applied during the initial phase of the import process. Sources: src/lib/gedcom/importer.ts:114-118
Conclusion
The GEDCOM Date Handling system in Vata provides a comprehensive bridge between the flexible, text-heavy nature of genealogical dates and the structured requirements of a relational database. By maintaining both raw original strings and normalized sortable representations, the application ensures high fidelity for user display while enabling powerful chronological sorting and analytical features. Sources: CONTEXT.md:27-31, src/gedcom-date/sort.ts:10-15