Php MySQL按年、月、日计算年龄

Php MySQL按年、月、日计算年龄,php,mysql,Php,Mysql,我想显示患者年龄的数据 mysql> select nama,gender,dob,TIMESTAMPDIFF(YEAR,dob,now()) as age from sampelaja; +------------------+--------+------------+------+ | nama | gender | dob | age | +------------------+--------+------------+------+ | Riz

我想显示患者年龄的数据

mysql> select nama,gender,dob,TIMESTAMPDIFF(YEAR,dob,now()) as age from sampelaja; +------------------+--------+------------+------+ | nama | gender | dob | age | +------------------+--------+------------+------+ | Rizkiyandi | 1 | 2010-05-21 | 4 | | Siti Khodijah | 0 | 1980-03-15 | 34 | | Aisyah Az-zahra | 0 | 1986-08-17 | 28 | | Paritem | 0 | 2005-12-13 | 8 | | Ngadimin | 1 | 2014-08-28 | 0 | +------------------+--------+------------+------+ 10 rows in set (0.00 sec) mysql>从sampelaja中选择nama、性别、dob、TIMESTAMPDIFF(年份、dob、now())作为年龄; +------------------+--------+------------+------+ |nama |性别| dob |年龄| +------------------+--------+------------+------+ |里兹基扬迪| 1 | 2010-05-21 | 4| |西蒂·霍迪杰| 0 | 1980-03-15 | 34| |Aiyah Az zahra | 0 | 1986-08-17 | 28| |巴黎会议2005-12-13| |Ngadimin | 1 | 2014-08-28 | 0| +------------------+--------+------------+------+ 一组10行(0.00秒) 这里有一个问题,当一个4天大的婴儿被认为是0岁的时候 我想要这样的结果

+------------------+--------+------------+------+-------+------+ | nama | gender | dob | year | month | day | +------------------+--------+------------+------+-------+------+ | Rizkiyandi | 1 | 2010-05-21 | 4 | 3 | 13 | | Siti Khodijah | 0 | 1980-03-15 | 34 | 5 | 18 | | Aisyah Az-zahra | 0 | 1986-08-17 | 28 | 0 | 16 | | Paritem | 0 | 2005-12-13 | 8 | 8 | 20 | | Ngadimin | 1 | 2014-08-28 | 0 | 0 | 6 | +------------------+--------+------------+------+-------+------+ +------------------+--------+------------+------+-------+------+ |nama |性别| dob |年|月|日| +------------------+--------+------------+------+-------+------+ |里兹基扬迪| 1 | 2010-05-21 | 4 | 3 | 13| |西蒂·霍迪杰| 0 | 1980-03-15 | 34 | 5 | 18| |Aiyah Az zahra | 0 | 1986-08-17 | 28 | 0 | 16| |巴黎会议2005-12-13| |恩加迪明| 1 | 2014-08-28 | 0 | 0 | 6| +------------------+--------+------------+------+-------+------+
您可以使用模来确定月和日的计数:

SELECT
      nama
    , gender
    , dob
    , TIMESTAMPDIFF( YEAR, dob, now() ) as _year
    , TIMESTAMPDIFF( MONTH, dob, now() ) % 12 as _month
    , FLOOR( TIMESTAMPDIFF( DAY, dob, now() ) % 30.4375 ) as _day
FROM 
    sampelaja
结果是:

+-----------------+--------+------------+-------+--------+------+
| nama            | gender | dob        | _year | _month | _day |
+-----------------+--------+------------+-------+--------+------+
| Rizkiyandi      |      1 | 2010-05-21 |     4 |      3 |   13 |
| Siti Khodijah   |      0 | 1980-03-15 |    34 |      5 |   19 |
| Aisyah Az-zahra |      0 | 1986-08-17 |    28 |      0 |   17 |
| Paritem         |      0 | 2005-12-13 |     8 |      8 |   20 |
| Ngadimin        |      1 | 2014-08-28 |     0 |      0 |    6 |
+-----------------+--------+------------+-------+--------+------+
天数从上个月的生日到今天计算


数字
30.4375
I使用以下公式计算:[一年中的天数]/12,其中[一年中的天数]=365.25

您应该能够使用下面的查询来计算。查询将计算确切的年、月和日

此信息也可以在mysql日期计算页面上找到:

这是我用来计算年、月、日年龄的查询

选择nama、性别、出生日期
,日期格式(CURDATE(),'%Y')-日期格式(dob,'%Y')-(日期格式(CURDATE(),'00-%m-%d')<日期格式(dob,'00-%m-%d'))作为年份
,期间差异(日期格式(CURDATE(),'%Y%m'),日期格式(dob,'%Y%m'))为月份
,DATEDIFF(CURDATE(),dob)作为天数
来自sampelaja
接受答案中的问题 公认的答案中的方法是好的,但闰年在生日时却把它搞砸了。以下是一些测试用例:

create table sample (dob datetime,now datetime);
insert into sample (dob,now)values
('2012-02-29', '2013-02-28'),
('2012-02-29', '2016-02-28'),
('2012-02-29', '2016-03-31'),
('2012-01-30', '2016-02-29'),
('2012-01-30', '2016-03-01'),
('2011-12-30', '2016-02-29');

SELECT
      date_format(dob,'%Y-%m-%d')
    , date_format(now,'%Y-%m-%d')
    , TIMESTAMPDIFF( YEAR, dob, now ) as _year
    , TIMESTAMPDIFF( MONTH, dob, now ) % 12 as _month
    , FLOOR( TIMESTAMPDIFF( DAY, dob, now ) % 30.4375 ) as _day
 FROM sample

       DOB         NOW YEAR     MONTH  DAY
2012-02-29  2013-02-28    0     11      30  -- 28 days would be better
2012-02-29  2016-02-28    3     11      29  -- 28 days would be better
2012-02-29  2016-03-31    4      1       0  -- 2 days would be better
2012-01-30  2016-02-29    4      0      30  
2012-01-30  2016-03-01    4      1       0  -- 2 days should be right
2011-12-30  2016-02-29    4      1       0  -- The right answer should be 4 years 1 months 30 days
这是我的方法,只使用算术 测试用例和结果:
当日期是同一天时,Jaugar Chang的答案中的days列出现了故障。我认为以下几点可以纠正这一点:

(SELECT CASE sign(day(now)-day(dob)) 
  WHEN 0 THEN 0 
  WHEN 1 THEN day(now)-day(dob)
  ELSE (DAY(STR_TO_DATE(DATE_FORMAT(dob + INTERVAL 1 MONTH,'%Y-%m-01'),'%Y-%m-%d')-INTERVAL 1 DAY)-day(dob)+day(now)) END)
  as days
为完整起见,Jaugar答案的修订版本如下:

SELECT 
FLOOR(( DATE_FORMAT(NOW(),'%Y%m%d') - DATE_FORMAT(dob,'%Y%m%d'))/10000) as year,
FLOOR((1200 + DATE_FORMAT(NOW(),'%m%d')-DATE_FORMAT(dob,'%m%d'))/100) %12 as month,
CASE sign(day(NOW())-day(dob))
  WHEN 0 THEN 0
  WHEN 1 THEN day(NOW())-day(dob)
  ELSE (DAY(STR_TO_DATE(DATE_FORMAT(dob + INTERVAL 1 MONTH,'%Y-%m-01'),'%Y-%m-%d')-INTERVAL 1 DAY)-day(dob)+day(NOW())) END as day
FROM sampelaja

以下函数从各种资源中复制并合并为一个。 这将返回以年、月和日为单位的完整日期。 也可以对其进行修改以显示其中一个。 此外,还将当前的_时间作为输入,以便我们也可以计算相对于任何其他日期的年龄

DROP function IF EXISTS `calculate_age`;

DELIMITER $$
CREATE FUNCTION `calculate_age`(`dob` DATE,  `current_time` DATETIME) 
RETURNS varchar(100) CHARSET utf8
BEGIN
DECLARE years varchar(10);
DECLARE months varchar(9);
DECLARE days varchar(7);
SELECT FLOOR(DATEDIFF(current_time, dob)/365) INTO years;
SELECT FLOOR((DATEDIFF(current_time,dob)/365 - FLOOR(DATEDIFF(current_time,dob)/365))* 12) INTO months;
SELECT CEILING((((DATEDIFF(CURDATE(),dob)/365 
- FLOOR(DATEDIFF(CURDATE(),dob)/365))* 12) - FLOOR((DATEDIFF(CURDATE(),dob)/365 - FLOOR(DATEDIFF(CURDATE(),dob)/365))* 12))* 30) into days;
RETURN CONCAT_WS
            ( ', '
        , CASE WHEN years = 0 THEN NULL ELSE CONCAT(years,'y') END
        , CASE WHEN months = 0 THEN NULL ELSE CONCAT(months, 'm') END
        , CASE WHEN days = 0 THEN NULL ELSE CONCAT(days, 'days') END
        );
END$$

DELIMITER ;

选中此选项可能会帮助您获得TIMESTAMPDIFF(DAY),然后除以365表示年份,剩余部分大于30,然后除以30表示平均月数,剩余部分为天。或者使用TIMESTAMPDIFF(YEAR)和MONTH and DAY的组合,然后使用YEAR*12和DAY by YEAR*365和MONTH*30的值减去月份,或者参见此处了解其他一些方法。如果结果是这样,我想如何显示30天以下患者的数据?谢谢兄弟。你答对了。但是太长了。是否可以用作表视图?我想选择一个答案,但不能,必须选择一个合适的答案:-(谢谢兄弟。这个查询是否可以用作表视图?因为我想确定一个标准,如果患者年龄超过10天,您可以添加
WHERE
子句来筛选10年以下的记录:
WHERE TIMESTAMPDIFF(YEAR,dob,now())<10
。或者您可以创建
检查约束
。一个测试用例是dob='2018-02-15 00:00:00',now='2018-04-17 00:00:00',您的查询返回0年2月0日,这不正确,您能帮我解决这个问题吗@Nicolai@MajbahHabib,两次约会之间有61天。因为我使用了近似值(1个月为30.4375天),查询返回
0.1250
天。函数
FLOOR
将此值舍入为零。您可能更愿意将这部分天计算为全天。若要使用函数
CEIL
而不是
FLOOR
,希望这有帮助。
       DOB         NOW  YEARS   MONTHS  DAYS
2012-02-29  2013-02-28     0    11      28
2012-02-29  2016-02-28     3    11      28
2012-02-29  2016-03-31     4     1       2
2012-01-30  2016-02-29     4     0      30
2012-01-30  2016-03-01     4     1       2
2011-12-30  2016-02-29     4     1      30
SELECT TIMESTAMPDIFF(year, dt.dt, NOW()) AS y,
       TIMESTAMPDIFF(month, dt.dt, NOW())%12  AS m,
       TIMESTAMPDIFF ( day, 
        DATE_ADD( adddate(curdate(), day( dt.dt) - day(curdate())), interval 
        -(day( dt.dt)>day(curdate())) month), 
        curdate()) as days
FROM (select date('1975-08-07') as dt ) as dt;
(SELECT CASE sign(day(now)-day(dob)) 
  WHEN 0 THEN 0 
  WHEN 1 THEN day(now)-day(dob)
  ELSE (DAY(STR_TO_DATE(DATE_FORMAT(dob + INTERVAL 1 MONTH,'%Y-%m-01'),'%Y-%m-%d')-INTERVAL 1 DAY)-day(dob)+day(now)) END)
  as days
SELECT 
FLOOR(( DATE_FORMAT(NOW(),'%Y%m%d') - DATE_FORMAT(dob,'%Y%m%d'))/10000) as year,
FLOOR((1200 + DATE_FORMAT(NOW(),'%m%d')-DATE_FORMAT(dob,'%m%d'))/100) %12 as month,
CASE sign(day(NOW())-day(dob))
  WHEN 0 THEN 0
  WHEN 1 THEN day(NOW())-day(dob)
  ELSE (DAY(STR_TO_DATE(DATE_FORMAT(dob + INTERVAL 1 MONTH,'%Y-%m-01'),'%Y-%m-%d')-INTERVAL 1 DAY)-day(dob)+day(NOW())) END as day
FROM sampelaja
DROP function IF EXISTS `calculate_age`;

DELIMITER $$
CREATE FUNCTION `calculate_age`(`dob` DATE,  `current_time` DATETIME) 
RETURNS varchar(100) CHARSET utf8
BEGIN
DECLARE years varchar(10);
DECLARE months varchar(9);
DECLARE days varchar(7);
SELECT FLOOR(DATEDIFF(current_time, dob)/365) INTO years;
SELECT FLOOR((DATEDIFF(current_time,dob)/365 - FLOOR(DATEDIFF(current_time,dob)/365))* 12) INTO months;
SELECT CEILING((((DATEDIFF(CURDATE(),dob)/365 
- FLOOR(DATEDIFF(CURDATE(),dob)/365))* 12) - FLOOR((DATEDIFF(CURDATE(),dob)/365 - FLOOR(DATEDIFF(CURDATE(),dob)/365))* 12))* 30) into days;
RETURN CONCAT_WS
            ( ', '
        , CASE WHEN years = 0 THEN NULL ELSE CONCAT(years,'y') END
        , CASE WHEN months = 0 THEN NULL ELSE CONCAT(months, 'm') END
        , CASE WHEN days = 0 THEN NULL ELSE CONCAT(days, 'days') END
        );
END$$

DELIMITER ;
SELECT concat(
  cast(TIMESTAMPDIFF(YEAR, str_to_date('14/08/2018','%d/%m/%Y'), str_to_date('14/05/2019','%d/%m/%Y')) AS char),' years ',
    cast(MOD(TIMESTAMPDIFF(MONTH, str_to_date('14/08/2018','%d/%m/%Y'), str_to_date('14/05/2019','%d/%m/%Y')), 12) as char), ' months ',
  cast(DATEDIFF(str_to_date('14/05/2019','%d/%m/%Y'),
  DATE_ADD(DATE_ADD(str_to_date('14/08/2018','%d/%m/%Y'), INTERVAL
  TIMESTAMPDIFF(YEAR, str_to_date('14/08/2018','%d/%m/%Y'),str_to_date('14/05/2019','%d/%m/%Y'))
  YEAR),
  INTERVAL MOD(TIMESTAMPDIFF(MONTH, str_to_date('14/08/2018','%d/%m/%Y'),str_to_date('14/05/2019','%d/%m/%Y')),12) MONTH)) AS char),' days') as Age