gedcom();
$html = '';
// Recorded age
if (preg_match('/\n2 AGE (.+)/', $factrec, $match) === 1) {
$fact_age = $element_factory->make($fact->tag() . ':AGE')->value($match[1], $record->tree());
} else {
$fact_age = '';
}
if (preg_match('/\n2 HUSB\n3 AGE (.+)/', $factrec, $match) === 1) {
$husb_age = $element_factory->make($fact->tag() . ':HUSB:AGE')->value($match[1], $record->tree());
} else {
$husb_age = '';
}
if (preg_match('/\n2 WIFE\n3 AGE (.+)/', $factrec, $match) === 1) {
$wife_age = $element_factory->make($fact->tag() . ':WIFE:AGE')->value($match[1], $record->tree());
} else {
$wife_age = '';
}
// Calculated age
[, $tag] = explode(':', $fact->tag());
if (preg_match('/\n2 DATE (.+)/', $factrec, $match) === 1) {
$date = new Date($match[1]);
$html .= ' ' . $date->display($cal_link ? $record->tree() : null, null, true);
// Time isn't valid GEDCOM, but it is widely used.
if ($time && preg_match('/\n3 TIME (.+)/', $factrec, $match) === 1) {
$html .= ' – ' . $match[1] . '';
}
if ($record instanceof Individual) {
if (
in_array($tag, Gedcom::BIRTH_EVENTS, true) &&
$record === $fact->record() &&
$record->tree()->getPreference('SHOW_PARENTS_AGE') === '1'
) {
// age of parents at child birth
$html .= view('fact-parents-age', ['individual' => $record, 'birth_date' => $date]);
}
if ($tag !== 'BIRT' && $tag !== 'CHAN' && $tag !== '_TODO') {
// age at event
$birth_date = $record->getBirthDate();
// Can't use getDeathDate(), as this also gives BURI/CREM events, which
// wouldn't give the correct "days after death" result for people with
// no DEAT.
$death_event = $record->facts(['DEAT'])->first();
if ($death_event instanceof Fact) {
$death_date = $death_event->date();
} else {
$death_date = new Date('');
}
$ageText = '';
if ($tag === 'DEAT' || Date::compare($date, $death_date) <= 0 || !$record->isDead()) {
// Before death, print age
$age = (string) new Age($birth_date, $date);
// Only show calculated age if it differs from recorded age
if ($age !== '') {
if (
$fact_age !== '' && !str_starts_with($fact_age, $age) ||
$fact_age === '' && $husb_age === '' && $wife_age === '' ||
$husb_age !== '' && !str_starts_with($husb_age, $age) && $record->sex() === 'M' ||
$wife_age !== '' && !str_starts_with($wife_age, $age) && $record->sex() === 'F'
) {
switch ($record->sex()) {
case 'M':
/* I18N: The age of an individual at a given date */
$ageText = I18N::translateContext('Male', '(aged %s)', $age);
break;
case 'F':
/* I18N: The age of an individual at a given date */
$ageText = I18N::translateContext('Female', '(aged %s)', $age);
break;
default:
/* I18N: The age of an individual at a given date */
$ageText = I18N::translate('(aged %s)', $age);
break;
}
}
}
}
if ($tag !== 'DEAT' && $death_date->isOK() && Date::compare($death_date, $date) <= 0) {
$death_day = $death_date->minimumDate()->day();
$event_day = $date->minimumDate()->day();
if ($death_day !== 0 && $event_day !== 0 && Date::compare($death_date, $date) === 0) {
// On the exact date of death?
// NOTE: this path is never reached. Keep the code (translation) in case
// we decide to re-introduce it.
$ageText = I18N::translate('(on the date of death)');
} else {
// After death
$age = (string) new Age($death_date, $date);
$ageText = I18N::translate('(%s after death)', $age);
}
// Family events which occur after death are probably errors
if ($fact->record() instanceof Family) {
$ageText .= view('icons/warning');
}
}
if ($ageText !== '') {
$html .= ' ' . $ageText . '';
}
}
}
}
// print gedcom ages
$age_labels = [
I18N::translate('Age') => $fact_age,
I18N::translate('Husband') => $husb_age,
I18N::translate('Wife') => $wife_age,
];
foreach (array_filter($age_labels) as $label => $age) {
$html .= ' ' . $label . ': ' . $age . '';
}
?>
= $html ?>