8

我正在尝试获取贷款日期和支付日期之间的日期和持续时间。我使用了 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

4 回答 4

7

主要问题如下:

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

    “在旧日期上谨慎使用 FROM_DAYS()。它不适用于公历 (1582) 出现之前的值”

    最小值是 1582 年,因为这是欧洲从儒略历转换为公历的时候。

  5. 0000-00-00 + 6 天是 0000-01-06,比 1582 早。

这实际上意味着 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

这是一个 SQL Fiddle 来证明它

再一次,这真的很hacky,并不推荐。

于 2012-05-26T13:30:18.693 回答
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上查看。

于 2012-05-29T10:48:57.273 回答
3

我用这个:

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
于 2014-09-18T22:22:20.570 回答
-1
SELECT DATE_FORMAT(FROM_DAYS(DATEDIFF('2012-04-30', '2009-05-24')), '%Y-%m-%d') AS `total_days`
于 2012-05-26T12:11:57.190 回答