2012-05-26 74 views
7

我想獲取貸款和付款日期之間的日期和時間期限。我使用了PHP日期和時間函數,但它並不總是準確的。我如何在MySQL中準確地做到這一點?如何在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' : '') : ''); 
} 
+3

有多少天有一個月? 28? 29? 30? 31? – liquorvicar

+0

您可能需要一個存儲過程或函數才能在MySQL中執行此操作。 – liquorvicar

回答

5

的主要問題如下:

  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 

Here's a SQL Fiddle to prove it

再次,這真的很hacky,並沒有真正推薦。

+0

這是很奇怪的mysql有沒有什麼容易爲這個問題設置。我希望他們能儘快擴展功能:) –

+0

@Adrius,我懷疑它:-)。 – Ben

+0

使用PHP版本。 2014年。 – topher

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

如果差異小於一年,該函數似乎不起作用。o我沒有意識到這一點。 –

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

我用這個:

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 
相關問題