我可以找到很多关于从出生日期开始计算年龄的参考文献,但是关于死亡和年龄的出生日期很少(即墓碑和家谱计算的信息)。
$ death_date是以下格式之一的文本字段:
3 Dec 1847
Nov 1904
1860
或者可以包含无效数据吗? 12月18日?? (即,墓碑不完全可读)
我目前只服用了整整一年的年龄。如果年龄是72岁,死亡日期是1976年7月24日,我目前将出生日期定为“1902年”?通过简单地从年份中减去年龄。我现在正在努力满足数月,数周和数天,以便更准确。因此,如果年龄为72岁6米,死亡日期是1976年7月24日,我想将出生日期设定为“1902年1月”?
$ age将采用3y7m2w6d格式,其中任何值都可以存在或丢失。例如。它可能是3y2d或27w
我正在使用此代码将年龄分为几年,几个月,几周或几天:
$yrs=$mths=$wks=$days=0;
if (is_numeric($age))
$yrs = $age;
else {
$pos = strpos($age, 'y');
if ($pos !== false)
list($yrs, $age) = explode('y', $age);
$pos = strpos($age, 'm');
if ($pos !== false)
list($mths, $age) = explode('m', $age);
$pos = strpos($age, 'w');
if ($pos !== false)
list($wks, $age) = explode('w', $age);
$pos = strpos($age, 'd');
if ($pos !== false)
list($days, $age) = explode('d', $age);
}
我现在正试图从$ death_date和$ yrs,$ mths,$ wks,$ days生成大约$ birth_date。 (最好是程序而不是OOP)。我不能使用strtotime,因为我需要迎合非常旧的日期,所以假设将使用create_date。
答案 0 :(得分:0)
使用DateTime::sub()
来实现这一目标。它还有一个名为date_sub()
的别名 - 如果您更喜欢程序方法,则可以使用它。
程序风格:
$age = 72;
$str = '24 July 1976';
$date = date_create($str);
date_sub($date, date_interval_create_from_date_string("$age years"));
$birth_date = date_format($date, 'Y-m-d');
面向对象的风格:
$age = 72;
$str = '24 July 1976';
$date = new DateTime($str);
$interval = new DateInterval(sprintf('P%dY', $age));
$date->sub($interval);
$birth_date = $date->format('Y-m-d');
答案 1 :(得分:0)
以下是已完成并已实施的已完成代码。如果这对其他人有用,请向我推荐我的问题以消除对我名字的负面罢工。 (拜倒...)
//---------------------------------------------------------------------
// Process age and dates
//---------------------------------------------------------------------
function get_dates($birth_date, $death_date , $age)
{
// Generate year born from death and age
list($age,$age_flag,$mths,$wks,$days) = get_age($age); // get age and split up eg. 23y6m
$birth_doubt = strpos($birth_date, '?');
$death_doubt = strpos($death, '?');
if ($age_flag != 'nbg' && $birth_date == '' ) {
if ($age_flag == 'sb')
$birth_date = $death;
elseif ($death_doubt === false && $death != '') {
if (is_numeric($age) && $age_flag != 'fract' && $age_flag != 'fract?') { // normal situation, age in full years
$year = substr($death,-4);
if ($year > 1787 && $year <= date("Y") && $age >= 0 && $age <= 120)
$birth_date = $year - $age.'?';
}
elseif ($age_flag == 'fract' || $age_flag == 'fract?') { // 27y7m or 2w or 3w9d etc
$words = explode(' ', $death);
$yy = $death_yy = array_pop($words);
$death_mm = array_pop($words);
$death_dd = array_pop($words);
if (!empty($death_dd)) $dd = $death_dd; // if death day blank assume 15th. If death month blank assume June
else $dd = 15;
if (!empty($death_mm)) $mm = $death_mm;
else $mm = 'Jun';
//echo $dd.' '.$mm.' '.$yy.'<br>';
$date=date_create($dd.' '.$mm.' '.$yy);
// $datechk = date_format($date,"j M Y");
// if ($death != $datechk) echo $death.' '.$datechk.' different<br>';
if ($date) {
//echo 'bbb';
date_sub($date,date_interval_create_from_date_string($age."years ".$mths."months ".$wks."week ".$days."days"));
list($dd,$mm,$yy) = explode(' ', date_format($date,"j M Y"));
//echo $dd,$mm,$yy;
if (empty($death_dd) || empty($days) && empty($wks)) $dd = '';
if (empty($death_mm)) $mm = '';
$birth_date = trim($dd.' '.$mm.' '.$yy);
if ($age_flag == 'fract?' || $dd == '')
$birth_date .= '?';
}
}
}
}
// Generate age from birth date and death date
elseif ($birth_doubt === false && $death_doubt === false && $age == '' && $death != '' && $birth_date != '') {
if (strlen($birth_date) == 4)
$born = new DateTime('Jun '.$birth_date); // assume born/died in june if year-only given for birth or death. If use year only it assumes it is hhmm
else
$born = new DateTime($birth_date);
if (strlen($death) == 4)
$died = new DateTime('Jun '.$death);
else
$died = new DateTime($death);
$interval = $died->diff($born);
$age = $interval->y;
}
// Extract year born and year died
$year_born = year_from_date($birth_date);
$year_died = year_from_date($death);
$year_interred = year_from_date($interred_date);
if (empty($year_died) && !empty($year_interred))
$year_died = $year_interred;
if ($age_flag == '?')
$age .= '?'; // it was there to start with so add it back
return array($birth_date, $death_date, $age, $year_born, $year_died, $year_interred);
//---------------------------------------------------------------------------------------------------------------------------------------
// Get age and age components and age_flag. age_flag can have the following values:
// nbg - do not use age value further
// sb - stillborn
// ? - reinsert ? on the end when finished (it was on the end of age passed to us so remove it and use other part of age)
// fract - age is fractional eg. 6y7w
// fract? - age is fractional doubtful eg. 6y7w?
// empty - Age is integer
//---------------------------------------------------------------------------------------------------------------------------------------
function get_age($age)
{
$yrs=$mths=$wks=$days=0;
$age = trim($age);
if (is_numeric($age))
return array($age,'',0,0,0);
$age = str_replace(
array(' ','years','year','yrs','yr','mths','mth','mt','wks','wk','days','day','hrs','hr','s/b','stillborn'),
array('','y','y','y','y','m','m','m','w','w','d','d','h','h','sb','sb'),
strtolower($age));
if ($age == '' || $age == '?')
return array('','nbg',0,0,0);
if ($age == 'sb' || $age == 'sb?')
return array($age, 'sb',0,0,0);
$age_flag = '';
$pos = strpos($age, '?');
if ($pos !== false) {
if (substr($age,strlen($age)-1,1) == '?') {
$age = rtrim($age, "?"); // remove question mark on end for now
$age_flag = '?';
}
else
return array($age,'nbg',0,0,0); // eg. ?5
}
if (!is_numeric($age)) { // check for 27y7m or 2w or 3w9d etc
$pos = strpos($age, 'y');
if ($pos !== false)
list($yrs, $age) = explode('y', $age);
$pos = strpos($age, 'm');
if ($pos !== false)
list($mths, $age) = explode('m', $age);
$pos = strpos($age, 'w');
if ($pos !== false)
list($wks, $age) = explode('w', $age);
$pos = strpos($age, 'd');
if ($pos !== false)
list($days, $age) = explode('d', $age);
$age = $yrs;
if (!isset($age_flag))
$age_flag = 'fract'; // fractional age
else
$age_flag = 'fract'.$age_flag; // fractional age?
}
return array($age,$age_flag,$mths,$wks,$days);
}
}