Skip to content

Instantly share code, notes, and snippets.

@marucc
Created March 3, 2012 04:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marucc/1964323 to your computer and use it in GitHub Desktop.
Save marucc/1964323 to your computer and use it in GitHub Desktop.
getAgeFromBirthday for php
<?php
// floor((Ymd - Ymd)/10000)
// 月齢、日にちまで求めないならこれで十分
function getAge($birthday, $today)
{
return (int)floor(((int)$today-(int)$birthday)/10000);
}
// test
if (debug_backtrace()) return;
$tests = array(
array('19960120', '20120119', 15),
array('19960120', '20120120', 16),
array('19960228', '20110227', 14),
array('19960228', '20110228', 15),
array('19960228', '20110301', 15),
array('19960229', '20110227', 14),
array('19960229', '20110228', 14),
array('19960229', '20110301', 15),
array('19970228', '20120227', 14),
array('19970228', '20120228', 15),
array('19970228', '20120229', 15),
array('19970228', '20120301', 15),
);
foreach ($tests as $t)
{
$ret = getAge($t[0], $t[1]);
echo sprintf("%s: %s -> %s = %s%s\n",
($ret === $t[2] ? 'ok' : 'ng'),
$t[0],
$t[1],
var_export($ret, true),
($ret === $t[2] ? '' : ' => ' . var_export($t[2], true))
);
}
/*
result
ok: 19960120 -> 20120119 = 15
ok: 19960120 -> 20120120 = 16
ok: 19960228 -> 20110227 = 14
ok: 19960228 -> 20110228 = 15
ok: 19960228 -> 20110301 = 15
ok: 19960229 -> 20110227 = 14
ok: 19960229 -> 20110228 = 14
ok: 19960229 -> 20110301 = 15
ok: 19970228 -> 20120227 = 14
ok: 19970228 -> 20120228 = 15
ok: 19970228 -> 20120229 = 15
ok: 19970228 -> 20120301 = 15
*/
<?php
/**
* getAgeFromBirthday
*
* @param string $birthday
* @param string|array $format %Y %y %M %m %D %d, string or array('year', 'month', 'day')
* @param string $now = null
* @return string
*/
function getAgeFromBirthday($birthday, $format = '%y', $today = null)
{
$birthday = new DateTime($birthday);
$birthday->setTime(0, 0, 0);
$today = new DateTime($today);
$today->setTime(0, 0, 0);
if ($today <= $birthday) return false;
$birthday_m = (int)$birthday->format('n');
$today_m = (((int)$today->format('Y') - (int)$birthday->format('Y')) * 12)
+ (int)$today->format('n');
$diff_m = ($today_m - $birthday_m);
if ($today->format('d') < $birthday->format('d')) {
$diff_m--;
$birthday->setDate(
$today->format('y'),
$today->format('m') - 1,
$birthday->format('d')
);
} else {
$birthday->setDate(
$today->format('y'),
$today->format('m'),
$birthday->format('d')
);
}
$diff_y = ($diff_m - ($diff_m % 12)) / 12;
$diff_m -= ($diff_y * 12);
//(PHP 5 >= 5.3.0)
$diff_d = (int)$birthday->diff($today)->format('%d');
//(PHP 5 < 5.3.0)
//$diff_d = ($birthday->format('m') == $today->format('m'))
// ? ((int)$today->format('j') - (int)$birthday->format('j'))
// : (((int)$birthday->format('t') - (int)$birthday->format('j')) + (int)$today->format('j'));
if (!$diff_y && !$diff_m && !$diff_d) {
return false;
} elseif (is_null($format)) {
return array(
$diff_y,
$diff_m,
$diff_d,
);
}
$formats = is_array($format) ? $format : array('', '', '', $format);
// like DateInterval::format
$replace_patterns = array(
'%Y' => '%1$02d',
'%y' => '%1$d',
'%M' => '%2$02d',
'%m' => '%2$d',
'%D' => '%3$02d',
'%d' => '%3$d',
);
//(PHP 5 >= 5.3.0)
array_walk($formats, function (&$val, $key) use ($replace_patterns) {
$val = str_replace(
array_keys($replace_patterns),
array_values($replace_patterns),
$val
);
});
//(PHP 5 < 5.3.0)
//array_walk($formats,
// create_function('&$val, $key, $p', '$val = str_replace(array_keys($p), array_values($p), $val);'),
// $replace_patterns);
$ret = '';
if (isset($formats[0]) && $diff_y) $ret .= sprintf($formats[0], $diff_y, $diff_m, $diff_d);
if (isset($formats[1]) && $diff_m) $ret .= sprintf($formats[1], $diff_y, $diff_m, $diff_d);
if (isset($formats[2]) && $diff_d) $ret .= sprintf($formats[2], $diff_y, $diff_m, $diff_d);
if (isset($formats[3])) $ret .= sprintf($formats[3], $diff_y, $diff_m, $diff_d);
return $ret;
}
// test
if (debug_backtrace()) return;
$tests = array(
array('2012-03-02', '2012-03-01', '%y-%m-%d', false),
array('2012-03-02', '2012-03-02', '%y-%m-%d', false),
array('2012-03-02', '2012-03-03', '%y-%m-%d', '0-0-1'),
array('2007-03-12', '2012-04-11', '%y', '5'),
array('2001-01-10', '2012-01-11', '%y歳%mヵ月', '11歳0ヵ月'),
array('2001-06-12', '2012-01-11', '%y歳%mヵ月', '10歳6ヵ月'),
array('2001-01-10', '2012-01-11', array('%y歳', '%mヵ月'), '11歳'),
array('2001-06-12', '2012-01-11', array('%y歳', '%mヵ月'), '10歳6ヵ月'),
array('2001-01-10', '2012-01-11', array('%y歳', '%mヵ月', '%d日'), '11歳1日'),
array('2001-06-12', '2012-01-12', array('%y歳', '%mヵ月', '%d日'), '10歳7ヵ月'),
array('2011-06-12', '2012-01-12', array('%y歳', '%mヵ月', '%d日'), '7ヵ月'),
array('2000-09-01', '2012-03-11', null, array(11, 6, 10)),
array('2011-09-01', '2012-03-01', '%y-%m-%d', '0-6-0'),
array('2011-09-10', '2012-03-10', '%y-%m-%d', '0-6-0'),
array('2011-09-01', '2012-09-01', '%y-%m-%d', '1-0-0'),
array('2011-09-10', '2012-09-09', '%y-%m-%d', '0-11-30'),
array('2011-07-10', '2012-07-09', '%y-%m-%d', '0-11-29'),
array('2010-11-30', '2012-12-31', '%y-%m-%d', '2-1-1'),
array('2010-10-31', '2012-11-30', '%y-%m-%d', '2-0-30'),
array('2012-02-29', '2013-02-28', '%y-%m-%d', '0-11-30'),
array('2012-02-29', '2013-03-01', '%y-%m-%d', '1-0-0'),
array('2011-02-28', '2012-02-29', '%y-%m-%d', '1-0-1'),
array('2011-03-01', '2012-02-29', '%y-%m-%d', '0-11-28'),
array('2011-02-20', '2012-03-10', '%y-%m-%d', '1-0-19'),
array('2012-02-20', '2013-03-10', '%y-%m-%d', '1-0-18'),
array('1996-01-20', '2012-01-19', '%y', '15'),
array('1996-01-20', '2012-01-20', '%y', '16'),
array('1996-02-28', '2011-02-27', '%y', '14'),
array('1996-02-28', '2011-02-28', '%y', '15'),
array('1996-02-28', '2011-03-01', '%y', '15'),
array('1996-02-29', '2011-02-27', '%y', '14'),
array('1996-02-29', '2011-02-28', '%y', '14'),
array('1996-02-29', '2011-03-01', '%y', '15'),
array('1997-02-28', '2012-02-27', '%y', '14'),
array('1997-02-28', '2012-02-28', '%y', '15'),
array('1997-02-28', '2012-02-29', '%y', '15'),
array('1997-02-28', '2012-03-01', '%y', '15'),
);
foreach ($tests as $t)
{
$ret = getAgeFromBirthday($t[0], $t[2], $t[1]);
echo sprintf("%s: %s -> %s = %s%s\n",
($ret === $t[3] ? 'ok' : 'ng'),
$t[0],
$t[1],
var_export($ret, true),
($ret === $t[3] ? '' : ' => ' . var_export($t[3], true))
);
}
/*
result
ok: 2012-03-02 -> 2012-03-01 = false
ok: 2012-03-02 -> 2012-03-02 = false
ok: 2012-03-02 -> 2012-03-03 = '0-0-1'
ok: 2007-03-12 -> 2012-04-11 = '5'
ok: 2001-01-10 -> 2012-01-11 = '11歳0ヵ月'
ok: 2001-06-12 -> 2012-01-11 = '10歳6ヵ月'
ok: 2001-01-10 -> 2012-01-11 = '11歳'
ok: 2001-06-12 -> 2012-01-11 = '10歳6ヵ月'
ok: 2001-01-10 -> 2012-01-11 = '11歳1日'
ok: 2001-06-12 -> 2012-01-12 = '10歳7ヵ月'
ok: 2011-06-12 -> 2012-01-12 = '7ヵ月'
ok: 2000-09-01 -> 2012-03-11 = array (
0 => 11,
1 => 6,
2 => 10,
)
ok: 2011-09-01 -> 2012-03-01 = '0-6-0'
ok: 2011-09-10 -> 2012-03-10 = '0-6-0'
ok: 2011-09-01 -> 2012-09-01 = '1-0-0'
ok: 2011-09-10 -> 2012-09-09 = '0-11-30'
ok: 2011-07-10 -> 2012-07-09 = '0-11-29'
ok: 2010-11-30 -> 2012-12-31 = '2-1-1'
ok: 2010-10-31 -> 2012-11-30 = '2-0-30'
ok: 2012-02-29 -> 2013-02-28 = '0-11-30'
ok: 2012-02-29 -> 2013-03-01 = '1-0-0'
ok: 2011-02-28 -> 2012-02-29 = '1-0-1'
ok: 2011-03-01 -> 2012-02-29 = '0-11-28'
ok: 2011-02-20 -> 2012-03-10 = '1-0-19'
ok: 2012-02-20 -> 2013-03-10 = '1-0-18'
ok: 1996-01-20 -> 2012-01-19 = '15'
ok: 1996-01-20 -> 2012-01-20 = '16'
ok: 1996-02-28 -> 2011-02-27 = '14'
ok: 1996-02-28 -> 2011-02-28 = '15'
ok: 1996-02-28 -> 2011-03-01 = '15'
ok: 1996-02-29 -> 2011-02-27 = '14'
ok: 1996-02-29 -> 2011-02-28 = '14'
ok: 1996-02-29 -> 2011-03-01 = '15'
ok: 1997-02-28 -> 2012-02-27 = '14'
ok: 1997-02-28 -> 2012-02-28 = '15'
ok: 1997-02-28 -> 2012-02-29 = '15'
ok: 1997-02-28 -> 2012-03-01 = '15'
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment