如何将给定天数转换为MySQL中的年,月和日?

时间:2012-05-26 11:57:18

标签: php mysql datetime datediff

我正在尝试获取贷款和付费日期之间的日期和时间。我使用了PHP日期和时间函数,但它并不总是准确的。我怎样才能在MySQL中准确地做到这一点?

假设两个日期,即贷款日期

  

2009-05-24

和贷款返还日期

  

2012-04-30

我写了一个MySQL查询

SELECT DATEDIFF('2012-04-30', '2009-05-24') `total_days`;

返回1072天,大约2年,11个月,12天。

  

请不要用PHP代码回答,我已经尝试过了。这里是   代码。

下面的函数使用PHP> = 5.3函数并将天数转换为年,月和日。

function date_interval($date1, $date2)
{
    $date1 = new DateTime($date1);
    $date2 = new DateTime($date2);

    $interval = date_diff($date2, $date1);
    return ((($y = $interval->format('%y')) > 0) ? $y . ' Year' . ($y > 1 ? 's' : '') . ', ' : '') . ((($m = $interval->format('%m')) > 0) ? $m . ' Month' . ($m > 1 ? 's' : '') . ', ' : '') . ((($d = $interval->format('%d')) > 0) ? $d . ' Day' . ($d > 1 ? 's' : '') : '');
}

下面的函数使用PHP> = 5.2函数并将天数转换为年,月和日。

function date_interval($date1, $date2)
{
    $diff = abs(strtotime($date2) - strtotime($date1));

    $years = floor($diff / (365 * 60 * 60 * 24));
    $months = floor(($diff - $years * 365 * 60 * 60 * 24) / (30 * 60 * 60 * 24));
    $days = floor(($diff - $years * 365 * 60 * 60 * 24 - $months * 30 * 60 * 60 * 24) / (60 * 60 * 24));

    return (($years > 0) ? $years . ' Year' . ($years > 1 ? 's' : '') . ', ' : '') . (($months > 0) ? $months . ' Month' . ($months > 1 ? 's' : '') . ', ' : '') . (($days > 0) ? $days . ' Day' . ($days > 1 ? 's' : '') : '');
}

4 个答案:

答案 0 :(得分:6)

主要问题如下:

  1. 为了找出您需要使用datediff()
  2. 的天数之间的差异
  3. datediff()以天为单位返回差异。
  4. 为了将天数转换为日期,您可以获得需要使用的年数等from_days()
  5. from_days()在1582年之前没有真正起作用,引用文档:

      

    “在旧日期时谨慎使用FROM_DAYS()。它不打算使用   在格里高利历(1582年)出现之前的值“

    最低限度是1582,因为这是欧洲从朱利安转换为格里高利日历的时候。

  6. 0000-00-00 + 6天是0000-01-06,早于1582年。

  7. 这实际上意味着MySQL日期函数对您来说毫无用处。

    您要求在MySQL “准确”中完成此操作。由于你不能使用日期功能,你将不得不自己组成。此不会准确。一年有多少天?它当然不总是365.一个月有多少天?

    我强烈建议在PHP中执行此操作。

    然而,由于你坚持认为你不想这样做,你将不得不作弊。

    将日期1600-01-01添加到所有内容。然后从最后的答案中删除1600年,1个月和1天。我只使用这个日期,因为它大于1582,这是一个很好的整数。任何事情都会有效,但越早越好,所以你不会遇到问题。

    假设我们已经构建了下表:

    create table dates (a date, b date);
    insert into dates
    values ( str_to_date('2012-04-30','%Y-%m-%d')
           , str_to_date('2012-04-24','%Y-%m-%d')
            );
    
    insert into dates
    values ( str_to_date('2012-04-30','%Y-%m-%d')
           , str_to_date('2009-05-24','%Y-%m-%d')
            );
    

    以下查询将获得您想要的内容:

    select extract(year from from_days(days)) - 1600
         , extract(month from from_days(days)) - 1
         , extract(day from from_days(days)) - 1
      from ( select to_days(a) - to_days(b) + 
                    to_days(str_to_date('1600-01-01', '%Y-%m-%d')) as days
               from dates ) as b
    

    Here's a SQL Fiddle to prove it

    再次,这真的非常hacky,并没有真正推荐。

答案 1 :(得分:4)

使用MySQL的TIMESTAMPDIFF()功能:

SELECT TIMESTAMPDIFF(YEAR
       , '2009-05-24'
       , '2012-04-30'
       ) AS Years,
       TIMESTAMPDIFF(MONTH
       , '2009-05-24'
           + INTERVAL TIMESTAMPDIFF(YEAR, '2009-05-24', '2012-04-30') YEAR
       , '2012-04-30'
       ) AS Months,
       TIMESTAMPDIFF(DAY
       , '2009-05-24'
           + INTERVAL TIMESTAMPDIFF(YEAR, '2009-05-24', '2012-04-30') YEAR
           + INTERVAL TIMESTAMPDIFF(YEAR, '2009-05-24', '2012-04-30') MONTH
       , '2012-04-30'
       ) AS Days

sqlfiddle上查看。

答案 2 :(得分:2)

我用过这个:

SELECT TIMESTAMPDIFF(YEAR
       , '2010-08-29'
       , '2014-09-18'
       ) AS Years,
       TIMESTAMPDIFF(MONTH
       , '2010-08-29'
           + INTERVAL TIMESTAMPDIFF(YEAR, '2010-08-29', '2014-09-18') YEAR
       , '2014-09-18'
       ) AS Months,
       TIMESTAMPDIFF(DAY
       , '2010-08-29'
           + INTERVAL TIMESTAMPDIFF(MONTH, '2010-08-29', '2014-09-18') MONTH
       , '2014-09-18'
       ) AS Days

答案 3 :(得分:0)

SELECT DATE_FORMAT(FROM_DAYS(DATEDIFF('2012-04-30', '2009-05-24')), '%Y-%m-%d') AS `total_days`