2012-05-26 70 views
7

Tôi đang cố gắng lấy ngày và thời gian giữa Thời gian vay và Ngày trả tiền. Tôi đã sử dụng hàm ngày và giờ của PHP, nhưng nó không phải lúc nào cũng chính xác. Làm thế nào tôi có thể làm điều này một cách chính xác trong MySQL?Làm thế nào để chuyển đổi số ngày nhất định thành năm, tháng và ngày trong MySQL?

Hãy giả định hai ngày, The vay lấy ngày

2009-05-24

và ngày trở lại cho vay

2012-04-30

Tôi viết truy vấn MySQL

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

trả lại 1072 ngày, tức là khoảng 2 năm, 11 tháng, 12 ngày.

Vui lòng không trả lời bằng mã PHP, tôi đã dùng thử. Đây là mã số .

Hàm bên dưới sử dụng PHP> = 5.3 hàm và chuyển đổi ngày thành năm, tháng và ngày.

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' : '') : ''); 
} 

Hàm bên dưới sử dụng PHP> = 5.2 chức năng và chuyển đổi ngày thành năm, tháng và ngày.

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

bao nhiêu ngày là có trong một tháng? 28? 29? 30? 31? – liquorvicar

+0

Có thể bạn sẽ cần một thủ tục hoặc hàm được lưu trữ để thực hiện điều đó trong MySQL. – liquorvicar

Trả lời

5

Vấn đề chính là như sau:

  1. Để tìm sự khác nhau giữa ngày bạn cần phải sử dụng datediff()
  2. datediff() lợi nhuận chênh lệch trong ngày.
  3. Để chuyển đổi ngày đến một ngày, vì vậy bạn có thể nhận được số năm vv bạn cần phải sử dụng from_days()
  4. from_days() không thực sự làm việc trước năm 1582, trích dẫn từ tài liệu:

    "sử dụng FROM_DAYS() một cách thận trọng vào những ngày cũ. Nó không phải là dành cho sử dụng với giá trị mà trước sự ra đời của lịch Gregorian (1582)"

    Tối thiểu là 1582 vì đây là khi châu Âu chuyển đổi từ Julian đến lịch Gregorian.

  5. 0000-00-00 + 6 ngày là 0000-01-06, đó là sớm hơn so với 1582.

này có hiệu quả có nghĩa là MySQL ngày chức năng là vô ích cho bạn.

Bạn yêu cầu việc này được thực hiện trong MySQL "chính xác".Vì bạn không thể sử dụng các hàm ngày bạn sẽ phải tự tạo. Điều này sẽ không là chính xác. Có bao nhiêu ngày trong một năm? Nó chắc chắn không phải lúc nào cũng có 365. Có bao nhiêu ngày trong một tháng?

Tôi thực sự khuyên bạn nên làm điều này trong PHP.

Tuy nhiên, vì bạn kiên quyết rằng bạn không muốn làm như vậy, bạn sẽ phải lừa.

Thêm ngày 1600-01-01 đến mọi thứ. Sau đó, xóa 1600 năm, 1 tháng và 1 ngày kể từ câu trả lời của bạn ở cuối. Tôi chỉ sử dụng ngày này vì nó lớn hơn 1582 và đó là một số vòng đẹp. Bất cứ điều gì sẽ làm việc thực sự nhưng trước đó tốt hơn, do đó bạn không chạy vào vấn đề.

Giả sử chúng ta đã xây dựng bảng sau:

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') 
     ); 

Các truy vấn sau đây sẽ có được những gì bạn muốn:

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.

Một lần nữa, điều này thực sự khá khó khăn và không thực sự được đề xuất. TIMESTAMPDIFF() chức năng

+0

Nó là khá lạ mysql không có gì dễ dàng thiết lập cho vấn đề này. Tôi hy vọng họ sẽ mở rộng chức năng sớm :) –

+0

@ Adrius, tôi nghi ngờ nó :-). – Ben

+0

Sử dụng phiên bản PHP. Trong năm 2014. – topher

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

Chức năng này dường như không hoạt động nếu sự khác biệt nhỏ hơn một năm. Tôi không biết điều đó. –

4

Sử dụng MySQL:

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 

Xem nó trên sqlfiddle.

2

Tôi sử dụng này:

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 
Các vấn đề liên quan