Tìm số ngày giữa hai ngày


617

Làm thế nào để tìm số ngày giữa hai ngày bằng PHP?


2
Các câu hỏi SO sau đây có thể giúp ích cho bạn: - Cách tính chênh lệch ngày giữa 2 ngày bằng php - Chênh lệch ngày với php - Tính chênh lệch giữa ngày / lần trong PHP - Chênh lệch ngày trong php? - [Nhận sự khác biệt giữa hai bên
Philip Morton

6
Một lớp lót:(new DateTime("2010-01-11"))->diff(new DateTime("2019-08-19"))->days;
billynoah

@billynoah - đây là câu trả lời sạch sẽ và đơn giản hơn!
rolinger

Câu trả lời:


907
$now = time(); // or your date as well
$your_date = strtotime("2010-01-31");
$datediff = $now - $your_date;

echo round($datediff / (60 * 60 * 24));

39
Tôi nghĩ rằng việc trả lại số ngày âm cung cấp thông tin liên quan. Và bạn nên sử dụng $your_date-$now, nếu bạn muốn một ngày trong tương lai trả về một số nguyên dương.
Tim

23
Còn giây nhuận thì sao? Không phải tất cả các ngày đều có chính xác 24 * 60 * 60 giây. Mã này có thể đủ cho các mục đích thực tế nhưng nó không chính xác trong các trường hợp cạnh cực kỳ hiếm.
Benjamin Brizzi

49
Quên đi những giây nhuận (không, thực tế cũng xem xét những điều đó) nhưng điều này KHÔNG tính đến sự thay đổi Thời gian tiết kiệm ánh sáng ban ngày! Nó có thể được tắt bởi cả ngày trên những ranh giới đó mỗi năm. Bạn cần sử dụng các lớp DateTime.
Levi

6
@billynoah Xin lỗi, tôi không bao giờ quay lại để cập nhật nhận xét của mình. Bạn phải cẩn thận với múi giờ tiết kiệm ánh sáng ban ngày. Nếu bạn so sánh một ngày với tiết kiệm ánh sáng ban ngày một lần nữa mà không có ngày đó, thay vì trả lại 7 ngày, nó sẽ trả về 6,9 ngày. Lấy sàn trả về 6 thay vì 7.
Alex Angelico

4
Không chỉ strtotime () thất bại trong 20 năm, ngay bây giờ nó không thể sử dụng được. OP chỉ định Ngày, không phải Thời gian. Ngày có thể khá cũ. Đây là một câu trả lời đơn giản hơn: $ NumberDays = gregoriantojd ($ EndM, $ EndD, $ EndY) - gregoriantojd ($ StartM, $ StartD, $ StartY); (cho một phạm vi bao gồm). Không giống như Class Datetime, Gregorian to Julian có sẵn trong phiên bản v4 trở lên. Phạm vi hợp lệ là 4714 BC đến 9999 AD Hãy coi chừng thứ tự tham số sôi nổi (giống như bạn cần cảnh báo đó cho php).
Guy Gordon

524

Nếu bạn đang sử dụng PHP 5.3 >, đây là cách tính chênh lệch chính xác nhất:

$earlier = new DateTime("2010-07-06");
$later = new DateTime("2010-07-09");

$diff = $later->diff($earlier)->format("%a");

14
Lưu ý rằng vì chúng ta đang nói về các khoảng thời gian không phải là các điểm cụ thể về thời gian, cú pháp định dạng khác với cú pháp date () và strftime (). Cú pháp khoảng thời gian có thể được tìm thấy ở đây: php.net/manual/en/dateinterval.format.php
Andrew

1
hoặc trong trường hợp của tôi, số ngày giữa là $ date2-> diff ($ date1) -> định dạng ("% a") - 1
xeo

13
Hãy nhớ rằng nếu bạn có thời gian trong các cuộc hẹn của mình, điều này sẽ không hoạt động như bạn mong đợi. Ví dụ: nếu bạn có một khoảng thời gian là 23:30 giờ ... và chúng vào các ngày khác nhau, sự khác biệt sẽ là 0.
Layke

20
Nếu bạn cần một số ngày tương đối (âm khi $date1trước là trước $date2), thì hãy sử dụng $diff = $date2->diff($date1)->format("%r%a");thay thế.
Socce

1
Định dạng của ngày trong là DateTime("2010-07-06")gì ?, Là nó Y-m-dhay Y-d-m?, Định dạng của DateTimetham số là gì. cái nào là ngày
151291

165

Từ phiên bản PHP 5.3 trở lên, các chức năng ngày / giờ mới đã được thêm vào để có sự khác biệt:

$datetime1 = new DateTime("2010-06-20");

$datetime2 = new DateTime("2011-06-22");

$difference = $datetime1->diff($datetime2);

echo 'Difference: '.$difference->y.' years, ' 
                   .$difference->m.' months, ' 
                   .$difference->d.' days';

print_r($difference);

Kết quả như sau:

Difference: 1 years, 0 months, 2 days

DateInterval Object
(
    [y] => 1
    [m] => 0
    [d] => 2
    [h] => 0
    [i] => 0
    [s] => 0
    [invert] => 0
    [days] => 367
)

Hy vọng nó giúp !


8
Có, điều này có vẻ tốt hơn câu trả lời được chấp nhận, không hoạt động trong một số trường hợp. Giống như: $ từ = '2014 / 03-01'; $ đến = '2014 / 03-31';
MBozic

1
Tôi đồng ý, rất dễ để làm theo và làm việc tuyệt vời !!! Chỉ cần đừng quên sử dụng hàm date_default_timezone_set () hoặc nó sẽ cho bạn kết quả lạ dựa trên thời gian UTC.
zeckdude

2
Chức năng này đã thất bại 0 trong số 14603 bài kiểm tra từ năm 1980 đến năm 2020.
LSerni

128

Chuyển đổi ngày của bạn thành dấu thời gian unix, sau đó trừ cái này từ cái khác. Điều đó sẽ cung cấp cho bạn sự khác biệt tính bằng giây, mà bạn chia cho 86400 (số giây trong một ngày) để cung cấp cho bạn số ngày xấp xỉ trong phạm vi đó.

Nếu ngày của bạn ở định dạng 25.1.2010, 01/25/2010hoặc 2010-01-25, bạn có thể sử dụng strtotimechức năng:

$start = strtotime('2010-01-25');
$end = strtotime('2010-02-20');

$days_between = ceil(abs($end - $start) / 86400);

Sử dụng làm ceiltròn số lượng ngày cho đến ngày tiếp theo. Sử dụng floorthay thế nếu bạn muốn có được số ngày đầy đủ giữa hai ngày đó.

Nếu ngày của bạn đã ở định dạng dấu thời gian unix, bạn có thể bỏ qua việc chuyển đổi và chỉ thực hiện $days_betweenmột phần. Đối với các định dạng ngày kỳ lạ hơn, bạn có thể phải thực hiện một số phân tích tùy chỉnh để làm cho đúng.


9
Còn DST thì sao?
toon81

3
@ toon81 - chúng tôi sử dụng dấu thời gian Unix để tránh những mớ hỗn độn đó! ;)
Alastair

6
Hãy để tôi giải thích: hãy nói rằng sáng nay lúc 3 giờ sáng, gần như toàn bộ châu Âu đã di chuyển đồng hồ trở lại một giờ. Điều đó có nghĩa là hôm nay có thêm 3600 giây và điều đó phải được phản ánh trong dấu thời gian UNIX. Nếu đúng như vậy, thì điều đó có nghĩa là hôm nay sẽ tính trong hai ngày với cách tính toán trên là số ngày. Và tôi thậm chí không bắt đầu khoảng vài giây vì cả PHP và UNIX dường như không tính đến những thứ đó (điều IMO thực sự dễ hiểu). TL; DR: không phải tất cả các ngày dài 86.400 giây .
toon81

2
@ toon81 KHÔNG còn 3600 giây nữa cho ngày đó. Không có gì xảy ra với dấu thời gian UNIX khi đi hoặc từ DST.
nickdnk

1
Nếu không có gì xảy ra với dấu thời gian UNIX, thì bạn đồng ý với tôi: sự khác biệt giữa dấu thời gian UNIX ở 1PM $dayvà dấu thời gian UNIX ở 1PM $day+1không phải lúc nào cũng là 86400 giây trong các múi giờ quan sát DST. Nó có thể là 23 hoặc 25 giờ của giây thay vì 24 giờ.
toon81

112

TL; DR làm không sử dụng timestamps UNIX. Không sử dụngtime() . Nếu bạn làm như vậy, hãy chuẩn bị nếu độ tin cậy 98,0825% của nó làm bạn thất vọng. Sử dụng DateTime (hoặc Carbon).

Các câu trả lời đúng là người do Saksham Gupta (câu trả lời khác cũng là chính xác):

$date1 = new DateTime('2010-07-06');
$date2 = new DateTime('2010-07-09');
$days  = $date2->diff($date1)->format('%a');

Hoặc thủ tục như một lớp lót:

/**
 * Number of days between two dates.
 *
 * @param date $dt1    First date
 * @param date $dt2    Second date
 * @return int
 */
function daysBetween($dt1, $dt2) {
    return date_diff(
        date_create($dt2),  
        date_create($dt1)
    )->format('%a');
}

Với một cảnh báo: '% a' dường như cho biết số ngày tuyệt đối . Nếu bạn muốn nó là số nguyên đã ký, tức là âm khi ngày thứ hai ở trước ngày đầu tiên, thì bạn cần sử dụng tiền tố '% r' (tức là format('%r%a')).


Nếu bạn thực sự phải sử dụng dấu thời gian UNIX, hãy đặt múi giờ thành GMT để tránh hầu hết các cạm bẫy chi tiết bên dưới.


Câu trả lời dài: tại sao chia cho 24 * 60 * 60 (còn gọi là 86400) là không an toàn

Hầu hết các câu trả lời sử dụng dấu thời gian UNIX (và 86400 để chuyển đổi thành ngày) đưa ra hai giả định, có thể dẫn đến các tình huống có kết quả saicác lỗi tinh vi có thể khó theo dõi và phát sinh ngay cả vài ngày, vài tuần hoặc vài tháng sau triển khai thành công. Không phải là giải pháp không hoạt động - nó hoạt động. Hôm nay. Nhưng nó có thể ngừng hoạt động vào ngày mai.

Lỗi đầu tiên là không xem xét rằng khi được hỏi, "Đã bao nhiêu ngày trôi qua kể từ ngày hôm qua?", Một máy tính có thể trả lời trung thực bằng 0 nếu giữa hiện tại và tức thời được chỉ ra bởi "ngày hôm qua" chưa đầy một ngày trôi qua.

Thông thường khi chuyển đổi "ngày" thành dấu thời gian UNIX, cái thu được là dấu thời gian cho nửa đêm của ngày cụ thể đó.

Vì vậy, giữa các ngày giữa tháng 1 và 15 tháng 10, mười lăm ngày đã trôi qua. Nhưng trong khoảng thời gian từ 13:00 ngày 1 tháng 10 đến 14:55 ngày 15 tháng 10, mười lăm ngày trừ đi 5 phút đã trôi qua và hầu hết các giải pháp sử dụng floor()hoặc thực hiện chuyển đổi số nguyên ngầm sẽ báo cáo ít hơn một ngày so với dự kiến .

Vậy, "Ymd H: i: s" cách đây bao nhiêu ngày? sẽ mang lại câu trả lời sai .

Sai lầm thứ hai là tương đương một ngày với 86400 giây. Điều này gần như luôn luôn đúng - nó thường xảy ra đủ để bỏ qua những lần nó không xảy ra. Nhưng khoảng cách tính bằng giây giữa hai lần giữa chừng liên tiếp chắc chắn không phải là 86400 ít nhất hai lần một năm khi thời gian tiết kiệm ánh sáng ban ngày phát huy tác dụng. So sánh hai ngày trên một ranh giới DST sẽ cho câu trả lời sai.

Vì vậy, ngay cả khi bạn sử dụng "hack" buộc tất cả các dấu thời gian trong một giờ cố định, hãy nói là nửa đêm (điều này cũng được thực hiện hoàn toàn bằng các ngôn ngữ và khung khác nhau khi bạn chỉ xác định ngày-tháng-năm và không phải giờ-phút-giây; cùng happpens với loại DATE trong cơ sở dữ liệu như MySQL), công thức được sử dụng rộng rãi

 (unix_timestamp(DATE2) - unix_timestamp(DATE1)) / 86400

hoặc là

 floor(time() - strtotime($somedate)) / 86400

sẽ trở lại, giả sử, 17 khi DATE1 và DATE2 nằm trong cùng phân khúc DST của năm; nhưng nó có thể trả về 17.042 và tệ hơn nữa là 16.958. Việc sử dụng sàn () hoặc bất kỳ phép cắt ngầm nào thành số nguyên sau đó sẽ chuyển đổi số 17 thành số 16. Trong các trường hợp khác, các biểu thức như "$ ngày> 17" sẽ trả về true17.042 ngay cả khi điều này cho biết số ngày đã trôi qua là 18.

Và mọi thứ thậm chí còn xấu hơn vì mã như vậy không thể di động trên các nền tảng, bởi vì một số trong số chúng có thể áp dụng giây nhuận và một số có thể không . Trên những nền tảng mà làm , sự khác biệt giữa hai ngày sẽ không được 86400 nhưng 86.401, hoặc có thể 86399. Vì vậy, mã mà làm việc vào tháng Năm và thực sự thông qua tất cả các bài kiểm tra sẽ phá vỡ tiếp theo tháng Sáu, khi 12,99999 ngày được coi là 12 ngày thay vì 13. Hai ngày đã làm việc trong năm 2015 sẽ không hoạt động trong năm 2017 - cùng ngày và không năm nào là năm nhuận. Nhưng giữa 2018/03/01 và 2017/03/01, trên những nền tảng mà chăm sóc, 366 ngày đã trôi qua sẽ thay vì 365, làm cho 2018 một năm nhuận (mà nó không phải là).

Vì vậy, nếu bạn thực sự muốn sử dụng dấu thời gian UNIX:

  • sử dụng round()chức năng một cách khôn ngoan, không floor().

  • thay thế, không tính toán sự khác biệt giữa D1-M1-YYY1 và D2-M2-YYY2. Những ngày đó sẽ thực sự được coi là D1-M1-YYY1 00:00:00 và D2-M2-YYY2 00:00:00. Thay vào đó, chuyển đổi giữa D1-M1-YYY1 22:30:00 và D2-M2-YYY2 04:30:00. Bạn sẽ luôn nhận được phần còn lại của khoảng hai mươi giờ. Điều này có thể trở thành hai mươi mốt giờ hoặc mười chín, và có thể mười tám giờ, năm mươi chín phút ba mươi sáu giây. Không vấn đề. Đó là một biên độ lớn sẽ ở đó và tích cực cho tương lai gần. Bây giờ bạn có thể cắt nó với floor()an toàn.

Các đúng giải pháp tuy nhiên, để tránh các hằng số ma thuật, kludges tròn và một món nợ bảo trì, là để

  • sử dụng thư viện thời gian (Datetime, Carbon, bất cứ điều gì); đừng tự lăn

  • viết các trường hợp kiểm tra toàn diện bằng cách sử dụng các lựa chọn ngày thực sự xấu - qua các ranh giới DST, qua các năm nhuận, qua các giây nhuận, v.v., cũng như các ngày phổ biến. Lý tưởng nhất là (các cuộc gọi đến datetime rất nhanh !) Tạo ra các ngày có giá trị trong bốn năm (và một ngày) bằng cách tập hợp chúng từ các chuỗi, theo tuần tự và đảm bảo rằng sự khác biệt giữa ngày đầu tiên và ngày được kiểm tra tăng dần theo từng ngày. Điều này sẽ đảm bảo rằng nếu có bất cứ điều gì thay đổi trong các thói quen ở mức độ thấp và các giây khắc phục lỗi cố gắng phá hoại, ít nhất bạn sẽ biết .

  • chạy các bài kiểm tra thường xuyên cùng với phần còn lại của bộ kiểm tra. Chúng là vấn đề của một phần nghìn giây và có thể giúp bạn tiết kiệm được hàng giờ .


Dù giải pháp của bạn là gì, hãy kiểm tra nó!

Hàm funcdiffbên dưới thực hiện một trong các giải pháp (như nó xảy ra, một giải pháp được chấp nhận) trong một kịch bản thế giới thực.

<?php
$tz         = 'Europe/Rome';
$yearFrom   = 1980;
$yearTo     = 2020;
$verbose    = false;

function funcdiff($date2, $date1) {
    $now        = strtotime($date2);
    $your_date  = strtotime($date1);
    $datediff   = $now - $your_date;
    return floor($datediff / (60 * 60 * 24));
}
########################################

date_default_timezone_set($tz);
$failures   = 0;
$tests      = 0;

$dom = array ( 0, 31, 28, 31, 30,
                  31, 30, 31, 31,
                  30, 31, 30, 31 );
(array_sum($dom) === 365) || die("Thirty days hath September...");
$last   = array();
for ($year = $yearFrom; $year < $yearTo; $year++) {
    $dom[2] = 28;
    // Apply leap year rules.
    if ($year % 4 === 0)   { $dom[2] = 29; }
    if ($year % 100 === 0) { $dom[2] = 28; }
    if ($year % 400 === 0) { $dom[2] = 29; }
    for ($month = 1; $month <= 12; $month ++) {
        for ($day = 1; $day <= $dom[$month]; $day++) {
            $date = sprintf("%04d-%02d-%02d", $year, $month, $day);
            if (count($last) === 7) {
                $tests ++;
                $diff = funcdiff($date, $test = array_shift($last));
                if ((double)$diff !== (double)7) {
                    $failures ++;
                    if ($verbose) {
                        print "There seem to be {$diff} days between {$date} and {$test}\n";
                    }
                }
            }
            $last[] = $date;
        }
    }
}

print "This function failed {$failures} of its {$tests} tests between {$yearFrom} and {$yearTo}.\n";

Kết quả là,

This function failed 280 of its 14603 tests

Câu chuyện kinh dị: chi phí "tiết kiệm thời gian"

Điều này thực sự đã xảy ra vài tháng trước. Một lập trình viên khéo léo đã quyết định tiết kiệm vài micro giây trong một phép tính mất tối đa ba mươi giây, bằng cách cắm mã "khét tiếng" (MidnightOfDateB-MidnightOfDateA) / 86400 "ở một số nơi. Rõ ràng là một tối ưu hóa mà anh ta thậm chí không ghi lại nó, và tối ưu hóa đã vượt qua các bài kiểm tra tích hợp và ẩn trong mã trong vài tháng, tất cả đều không được chú ý.

Điều này đã xảy ra trong một chương trình tính toán tiền lương cho một số nhân viên bán hàng bán chạy nhất, ít nhất trong số đó có sức mạnh đáng sợ hơn nhiều so với một nhóm lập trình viên năm người khiêm tốn cùng nhau. Một ngày cách đây vài tháng, vì những lý do ít quan trọng, lỗi đã xảy ra - và một vài trong số những người đó đã bị đổi một ngày hoa hồng béo. Họ chắc chắn không thích thú.

Tệ hơn nữa, họ đã mất niềm tin (đã rất ít) mà họ có trong chương trình không được thiết kế để lén lút trục trặc họ, và giả vờ - và thu được - một bản đánh giá mã đầy đủ, chi tiết với các trường hợp thử nghiệm được chạy và nhận xét theo các điều khoản của giáo dân (cộng với rất nhiều điều trị thảm đỏ trong những tuần tiếp theo).

Tôi có thể nói gì: về mặt tích cực, chúng tôi đã thoát khỏi rất nhiều khoản nợ kỹ thuật, và đã có thể viết lại và tái cấu trúc một vài mớ hỗn độn spaghetti được nghe lại từ sự phá hoại của COBOL trong thập niên 90. Chương trình chắc chắn chạy tốt hơn bây giờ, và có nhiều thông tin gỡ lỗi hơn để nhanh chóng chuyển sang số 0 khi mọi thứ trông có vẻ tanh. Tôi ước tính rằng chỉ một điều cuối cùng này sẽ tiết kiệm được một hoặc hai ngày công mỗi tháng trong tương lai gần.

Về mặt trừ, toàn bộ brouhaha đã tiêu tốn của công ty khoảng 200.000 euro tiền mặt - cộng với khuôn mặt, cộng với chắc chắn là một số quyền lực thương lượng (và, do đó, còn nhiều tiền hơn).

Anh chàng chịu trách nhiệm "tối ưu hóa" đã thay đổi công việc một năm trước, trước thảm họa, nhưng vẫn có người nói chuyện để kiện anh ta về những thiệt hại. Và nó đã không thành công với các tiếng vang trên rằng đó là "lỗi của người cuối cùng" - nó trông giống như một sự sắp đặt để chúng ta giải quyết vấn đề, và cuối cùng, chúng ta vẫn ở trong nhà ổ chuột và một trong những nhóm đang lên kế hoạch bỏ việc.

Chín mươi chín lần trong số một trăm, "hack 86400" sẽ hoạt động hoàn hảo. (Ví dụ: trong PHP, strtotime()sẽ bỏ qua DST và báo cáo rằng giữa các ngày thứ Bảy cuối cùng của tháng Mười và thứ Hai tuần sau, chính xác là 2 * 24 * 60 * 60 giây đã trôi qua, ngay cả khi điều đó hoàn toàn không đúng ... và hai cái sai sẽ hạnh phúc làm cho một cái đúng).

Điều này, thưa quý vị và quý ông, là một ví dụ khi nó không xảy ra. Như với túi khí và dây an toàn, có lẽ bạn sẽ không bao giờ thực sự cần sự phức tạp (và dễ sử dụng) của DateTimehoặc Carbon. Nhưng ngày mà bạn có thể (hoặc ngày mà bạn sẽ phải chứng minh bạn nghĩ về điều này) sẽ đến như một tên trộm trong đêm. Được chuẩn bị.


7
Khi tôi nhìn thấy những câu trả lời này, tôi đã nghĩ rằng mình thật ngu ngốc và điên rồ vì tôi luôn sử dụng DateTime, nhưng bạn đã khiến tôi hiểu rằng sử dụng DateTime là đúng cách. Cảm ơn bạn
Syncro

Này, mọi người ở đây, trên SO, đã đến đây bằng cách tìm kiếm trong google days between two days in phphoặc tương tự, chỉ vì cuộc sống quá ngắn để tự viết mọi thứ.
Denis Matafonov

1
giải thích chi tiết. + 1
Anant Singh --- Sống đến

1
Đôi khi tôi ước chúng ta có thể yêu thích các câu trả lời thay vì câu hỏi.
Clément Baconnier

đây phải là câu trả lời được chấp nhận
Franz

16

Dễ dàng sử dụng date_diff

$from=date_create(date('Y-m-d'));
$to=date_create("2013-03-15");
$diff=date_diff($to,$from);
print_r($diff);
echo $diff->format('%R%a days');

Đây là một cách thủ tục tốt để thực hiện bằng lớp DateTime. Nó chỉ thiếu một cách sử dụng rõ ràng của đối tượng khoảng ( $diffbiến trong trường hợp này). Một cái gì đó giống như if ($diff->days > 30) { [doyourstuff]; }
Gusstavv Gil

16

Phong cách hướng đối tượng:

$datetime1 = new DateTime('2009-10-11');
$datetime2 = new DateTime('2009-10-13');
$interval = $datetime1->diff($datetime2);
echo $interval->format('%R%a days');

Phong cách thủ tục:

$datetime1 = date_create('2009-10-11');
$datetime2 = date_create('2009-10-13');
$interval = date_diff($datetime1, $datetime2);
echo $interval->format('%R%a days');

11

Đã sử dụng cái này :)

$days = (strtotime($endDate) - strtotime($startDate)) / (60 * 60 * 24);
print $days;

Bây giờ nó hoạt động


14
Nhận xét rất cũ ở trên, nhưng nó không chính xác. StackOverflow không cho phép bạn trả lời câu hỏi của riêng bạn (ngay cả khi bạn đặt câu hỏi của mình). Tự trả lời câu hỏi sau khi ai đó đã đăng cùng một giải pháp tuy nhiên được coi là thô lỗ.
Maarten Bodewes

Chức năng này đã thất bại với 560 trong số 14603 thử nghiệm từ năm 1980 đến năm 2020.
LSerni

10

Chà, câu trả lời được chọn không phải là câu trả lời đúng nhất vì nó sẽ thất bại ngoài UTC. Tùy thuộc vào múi giờ ( danh sách ), có thể có các điều chỉnh thời gian tạo ngày "không" trong 24 giờ và điều này sẽ khiến phép tính (60 * 60 * 24) thất bại.

Đây là một ví dụ về nó:

date_default_timezone_set('europe/lisbon');
$time1 = strtotime('2016-03-27');
$time2 = strtotime('2016-03-29');
echo floor( ($time2-$time1) /(60*60*24));
 ^-- the output will be **1**

Vì vậy, giải pháp chính xác sẽ là sử dụng DateTime

date_default_timezone_set('europe/lisbon');
$date1 = new DateTime("2016-03-27");
$date2 = new DateTime("2016-03-29");

echo $date2->diff($date1)->format("%a");
 ^-- the output will be **2**

7

Tính hiệu số giữa hai ngày:

$date1=date_create("2013-03-15");
$date2=date_create("2013-12-12");

$diff=date_diff($date1,$date2);

echo $diff->format("%R%a days");

Sản lượng: +272 ngày

Hàm date_diff () trả về sự khác biệt giữa hai đối tượng DateTime.


6
$start = '2013-09-08';
$end = '2013-09-15';
$diff = (strtotime($end)- strtotime($start))/24/3600; 
echo $diff;

Chức năng này đã thất bại 560 trong số 14603 thử nghiệm từ năm 1980 đến năm 2020.
LSerni

6

Tôi đang sử dụng Carbon trong các dự án sáng tác của mình cho mục đích này và các mục đích tương tự.

Nó sẽ dễ dàng như thế này:

$dt = Carbon::parse('2010-01-01');
echo $dt->diffInDays(Carbon::now());

5

Bạn có thể tìm thấy ngày chỉ đơn giản bằng cách

<?php
$start  = date_create('1988-08-10');
$end    = date_create(); // Current time and date
$diff   = date_diff( $start, $end );

echo 'The difference is ';
echo  $diff->y . ' years, ';
echo  $diff->m . ' months, ';
echo  $diff->d . ' days, ';
echo  $diff->h . ' hours, ';
echo  $diff->i . ' minutes, ';
echo  $diff->s . ' seconds';
// Output: The difference is 28 years, 5 months, 19 days, 20 hours, 34 minutes, 36 seconds

echo 'The difference in days : ' . $diff->days;
// Output: The difference in days : 10398

4
$datediff = floor(strtotime($date1)/(60*60*24)) - floor(strtotime($date2)/(60*60*24));

và, nếu cần:

$datediff=abs($datediff);

3

Nếu bạn có thời gian tính bằng giây (dấu thời gian unix IE), thì bạn có thể chỉ cần trừ thời gian và chia cho 86400 (giây mỗi ngày)


3

số ngày giữa hai ngày trong PHP

      function dateDiff($date1, $date2)  //days find function
        { 
            $diff = strtotime($date2) - strtotime($date1); 
            return abs(round($diff / 86400)); 
        } 
       //start day
       $date1 = "11-10-2018";        
       // end day
       $date2 = "31-10-2018";    
       // call the days find fun store to variable 
       $dateDiff = dateDiff($date1, $date2); 

       echo "Difference between two dates: ". $dateDiff . " Days "; 

1
Thật tuyệt khi nó hoạt động như bùa mê, bạn có thể cho tôi biết 86400 num dùng để làm gì không?
Parth Shah

Số 86400 được sử dụng trong 1 ngày = 24 giờ và 24 * 60 * 60 = 86400 giây trong một ngày
mallikarjun SK

3

Bạn có thể thử mã dưới đây:

$dt1 = strtotime("2019-12-12"); //Enter your first date
$dt2 = strtotime("12-12-2020"); //Enter your second date
echo abs(($dt1 - $dt2) / (60 * 60 * 24));

2
Với những câu hỏi cũ hơn đã có câu trả lời, thật hữu ích để giải thích khía cạnh mới mà câu trả lời của bạn mang đến cho câu hỏi. Nếu có liên quan, cũng hữu ích khi thừa nhận bất kỳ thay đổi nào có thể xảy ra kể từ khi câu hỏi được hỏi.
Jason Aller

2
function howManyDays($startDate,$endDate) {

    $date1  = strtotime($startDate." 0:00:00");
    $date2  = strtotime($endDate." 23:59:59");
    $res    =  (int)(($date2-$date1)/86400);        

return $res;
} 

Chức năng này đã thất bại 320 trong số 14603 thử nghiệm từ năm 1980 đến 2020.
LSerni

2

Nếu bạn muốn lặp lại tất cả các ngày giữa ngày bắt đầu và ngày kết thúc, tôi đã nghĩ ra điều này:

$startdatum = $_POST['start']; // starting date
$einddatum = $_POST['eind']; // end date

$now = strtotime($startdatum);
$your_date = strtotime($einddatum);
$datediff = $your_date - $now;
$number = floor($datediff/(60*60*24));

for($i=0;$i <= $number; $i++)
{
    echo date('d-m-Y' ,strtotime("+".$i." day"))."<br>";
}

2

Cách dễ nhất để tìm sự khác biệt ngày giữa hai ngày

$date1 = strtotime("2019-05-25"); 
$date2 = strtotime("2010-06-23");

$date_difference = $date2 - $date1;

$result =  round( $date_difference / (60 * 60 * 24) );

echo $result;

1
    // Change this to the day in the future
$day = 15;

// Change this to the month in the future
$month = 11;

// Change this to the year in the future
$year = 2012;

// $days is the number of days between now and the date in the future
$days = (int)((mktime (0,0,0,$month,$day,$year) - time(void))/86400);

echo "There are $days days until $day/$month/$year";

1

Đây là phiên bản cải tiến của tôi hiển thị 1 năm 2 tháng 25 ngày nếu tham số thứ 2 được thông qua.

class App_Sandbox_String_Util {
    /**
     * Usage: App_Sandbox_String_Util::getDateDiff();
     * @param int $your_date timestamp
     * @param bool $hr human readable. e.g. 1 year(s) 2 day(s)
     * @see http://stackoverflow.com/questions/2040560/finding-the-number-of-days-between-two-dates
     * @see http://qSandbox.com
     */
    static public function getDateDiff($your_date, $hr = 0) {
        $now = time(); // or your date as well
        $datediff = $now - $your_date;
        $days = floor( $datediff / ( 3600 * 24 ) );

        $label = '';

        if ($hr) {
            if ($days >= 365) { // over a year
                $years = floor($days / 365);
                $label .= $years . ' Year(s)';
                $days -= 365 * $years;
            }

            if ($days) {
                $months = floor( $days / 30 );
                $label .= ' ' . $months . ' Month(s)';
                $days -= 30 * $months;
            }

            if ($days) {
                $label .= ' ' . $days . ' day(s)';
            }
        } else {
            $label = $days;
        }

        return $label;
    }
}

1
$early_start_date = date2sql($_POST['early_leave_date']);


$date = new DateTime($early_start_date);
$date->modify('+1 day');


$date_a = new DateTime($early_start_date . ' ' . $_POST['start_hr'] . ':' . $_POST['start_mm']);
$date_b = new DateTime($date->format('Y-m-d') . ' ' . $_POST['end_hr'] . ':' . $_POST['end_mm']);

$interval = date_diff($date_a, $date_b);


$time = $interval->format('%h:%i');
$parsed = date_parse($time);
$seconds = $parsed['hour'] * 3600 + $parsed['minute'] * 60;
//        display_error($seconds);

$second3 = $employee_information['shift'] * 60 * 60;

if ($second3 < $seconds)
    display_error(_('Leave time can not be greater than shift time.Please try again........'));
    set_focus('start_hr');
    set_focus('end_hr');
    return FALSE;
}

1
<?php
$date1=date_create("2013-03-15");
$date2=date_create("2013-12-12");
$diff=date_diff($date1,$date2);
echo $diff->format("%R%a days");
?>

sử dụng đoạn mã trên rất đơn giản. Cảm ơn.


1
function get_daydiff($end_date,$today)
{
    if($today=='')
    {
        $today=date('Y-m-d');
    }
    $str = floor(strtotime($end_date)/(60*60*24)) - floor(strtotime($today)/(60*60*24));
    return $str;
}
$d1 = "2018-12-31";
$d2 = "2018-06-06";
echo get_daydiff($d1, $d2);

1

Sử dụng chức năng đơn giản này. Khai báo hàm

<?php
function dateDiff($firstDate,$secondDate){
    $firstDate = strtotime($firstDate);
    $secondDate = strtotime($secondDate);

    $datediff = $firstDate - $secondDate;
    $output = round($datediff / (60 * 60 * 24));
    return $output;
}
?>

và gọi hàm này như thế này ở nơi bạn muốn

<?php
    echo dateDiff("2018-01-01","2018-12-31");    

// OR

    $firstDate = "2018-01-01";
    $secondDate = "2018-01-01";
    echo dateDiff($firstDate,$secondDate);    
?>

1
$diff = strtotime('2019-11-25') - strtotime('2019-11-10');
echo abs(round($diff / 86400));

2
Chào mừng đến với SO! Khi bạn trả lời một bài viết chỉ bằng mã, vui lòng giải thích một chút. Mã bạn mang theo đang tính toán trong khoảng thời gian từ 2019-11-10 đến 2019-11-25. Vì vậy, nó không trả lời cho câu hỏi. Đó là lý do tại sao tốt để giải thích POV của bạn tốt hơn là bị hạ cấp.
David García Bodego

0

Nếu bạn đang sử dụng MySql

function daysSince($date, $date2){
$q = "SELECT DATEDIFF('$date','$date2') AS days;";
$result = execQ($q);
$row = mysql_fetch_array($result,MYSQL_BOTH);
return ($row[0]);

}

function execQ($q){
$result = mysql_query( $q);
if(!$result){echo ('Database error execQ' . mysql_error());echo $q;}    
return $result;

}


0

Hãy thử sử dụng Carbon

$d1 = \Carbon\Carbon::now()->subDays(92);
$d2 = \Carbon\Carbon::now()->subDays(10);
$days_btw = $d1->diffInDays($d2);

Ngoài ra bạn có thể sử dụng

\Carbon\Carbon::parse('')

để tạo một đối tượng của ngày Carbon bằng chuỗi dấu thời gian đã cho.


Bạn có thể vui lòng cho biết sự khác biệt giữa điều này và câu trả lời của tôi không?
Arda

1
Để làm một sự khác biệt ngày đơn giản, bạn đề nghị bao gồm một gói hoàn toàn mới?
tomazahlin

0

Nhìn vào tất cả các câu trả lời tôi soạn thảo hàm phổ quát, những gì hoạt động trên tất cả các phiên bản PHP.

if(!function_exists('date_between')) :
    function date_between($date_start, $date_end)
    {
        if(!$date_start || !$date_end) return 0;

        if( class_exists('DateTime') )
        {
            $date_start = new DateTime( $date_start );
            $date_end   = new DateTime( $date_end );
            return $date_end->diff($date_start)->format('%a');
        }
        else
        {           
            return abs( round( ( strtotime($date_start) - strtotime($date_end) ) / 86400 ) );
        }
    }
endif;

Nói chung, tôi sử dụng 'DateTime' để tìm ngày giữa 2 ngày. Nhưng nếu trong một số lý do, một số thiết lập máy chủ không kích hoạt 'DateTime', nó sẽ sử dụng phép tính đơn giản (nhưng không an toàn) với 'strtotime ()'.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.