出生日期自死亡和年龄

时间:2014-03-15 09:19:13

标签: php datetime

我可以找到很多关于从出生日期开始计算年龄的参考文献,但是关于死亡和年龄的出生日期很少(即墓碑和家谱计算的信息)。

$ 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。

2 个答案:

答案 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');

Demo

答案 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);
}
}