การค้นหาจำนวนวันระหว่างสองวัน


617

จะค้นหาจำนวนวันระหว่างสองวันด้วย PHP ได้อย่างไร



6
สายการบินหนึ่ง:(new DateTime("2010-01-11"))->diff(new DateTime("2019-08-19"))->days;
billynoah

@billynoah - นี่เป็นคำตอบที่ง่ายและสะอาดที่สุด!
rolinger

คำตอบ:


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
ฉันคิดว่าการคืนจำนวนวันติดลบให้ข้อมูลที่เกี่ยวข้อง และคุณควรใช้$your_date-$nowถ้าคุณต้องการให้วันที่ในอนาคตคืนค่าจำนวนเต็มบวก
Tim

23
กระโดดวินาที? ไม่ใช่ทุกวันมี 24 * 60 * 60 วินาที รหัสนี้อาจเพียงพอสำหรับการใช้งานจริง แต่มันไม่ถูกต้องในกรณีขอบหายากมาก
Benjamin Brizzi

49
ลืมวินาทีเผ่น (ไม่จริงพิจารณาสิ่งเหล่านั้นด้วยเช่นกัน) แต่นี่ไม่ได้หมายถึงการเปลี่ยนแปลงเวลาออมแสง! สามารถปิดได้ตลอดทั้งวันผ่านขอบเขตเหล่านั้นทุกปี คุณต้องใช้คลาส DateTime
เลวี

6
@billynoah ขออภัยฉันไม่เคยกลับมาอัปเดตความคิดเห็นของฉัน คุณต้องระมัดระวังด้วยการปรับเวลาตามฤดูกาล หากคุณเปรียบเทียบวันที่ด้วยการปรับเวลาตามฤดูกาลจะไม่มีการใส่วันที่ลงไปแทนที่จะเป็นตัวอย่างเช่นคืน 7 วันและส่งคืน 6.9 วัน การรับพื้นส่งคืน 6 แทน 7
Alex Angelico

4
ไม่เพียง แต่ strtotime () ล้มเหลวใน 20 ปี แต่ตอนนี้ใช้ไม่ได้ OP ระบุวันที่ไม่ใช่เวลา วันที่ค่อนข้างเก่า นี่คือคำตอบที่ง่ายกว่า: $ NumberDays = gregoriantojd ($ EndM, $ EndD, $ EndY) - gregoriantojd ($ StartM, $ StartD, $ StartY); (สำหรับช่วงรวม) ไม่เหมือนคลาส Datetime Gregorian ถึง Julian มีให้ใน v4 ขึ้นไป ช่วงที่ถูกต้องคือ 4714 BC ถึง 9999 AD ระวังลำดับพารามิเตอร์ขี้ขลาด (เช่นคุณต้องการคำเตือนสำหรับ php)
Guy Gordon

524

หากคุณกำลังใช้PHP 5.3 >นี่เป็นวิธีที่แม่นยำที่สุดในการคำนวณความแตกต่าง:

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

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

14
โปรดทราบว่าเนื่องจากเรากำลังพูดถึงช่วงเวลาที่ไม่ใช่จุดเฉพาะเวลารูปแบบไวยากรณ์จะแตกต่างจากไวยากรณ์วันที่ () และ strftime () ไวยากรณ์ช่วงเวลาสามารถพบได้ที่นี่: php.net/manual/en/dateinterval.format.php
Andrew

1
หรือในกรณีของฉันจำนวนวันระหว่างคือ $ date2-> diff ($ date1) -> รูปแบบ ("% a") - 1
xeo

13
โปรดทราบว่าหากคุณมีเวลาในวันที่สิ่งนี้จะไม่ทำงานอย่างที่คุณคาดหวัง ตัวอย่างเช่นหากคุณมีช่วงเวลา 23:30 น. ... และพวกเขาอยู่ในวันที่แตกต่างกันความแตกต่างจะเป็น 0
Layke

19
หากคุณจำเป็นต้องมีญาติจำนวนวัน (ลบเมื่อ$date1อยู่ในหน้าไป$date2) แล้วใช้$diff = $date2->diff($date1)->format("%r%a");แทน
Socce

1
รูปแบบวันที่ในคืออะไรDateTime("2010-07-06")? คือมันY-m-dหรือY-d-m? สิ่งที่เป็นรูปแบบของDateTimeพารามิเตอร์ วันไหนของวัน
151291

165

จาก PHP เวอร์ชั่น 5.3 ขึ้นไปมีการเพิ่มฟังก์ชันวันที่ / เวลาใหม่เพื่อรับความแตกต่าง:

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

ผลลัพธ์ดังนี้:

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
)

หวังว่ามันจะช่วย!


8
ใช่ดูเหมือนว่าดีกว่าคำตอบที่ยอมรับซึ่งใช้ไม่ได้ในบางกรณี ไลค์: $ from = '2014-03-01'; ดอลลาร์ = '2014/03/31';
MBozic

1
ฉันเห็นด้วยง่ายมากที่จะติดตามและใช้งานได้ดีมาก !!! อย่าลืมใช้ฟังก์ชั่น date_default_timezone_set () ไม่เช่นนั้นจะให้ผลลัพธ์ที่แปลกประหลาดตามเวลา UTC
zeckdude

2
ฟังก์ชันนี้ล้มเหลว 0 จาก 14603 การทดสอบระหว่างปี 1980 และ 2020
LSerni

128

แปลงวันที่ของคุณให้เป็นเวลาประทับยูนิกซ์จากนั้นย่อส่วนจากวันที่อื่น นั่นจะให้ความแตกต่างเป็นวินาทีซึ่งคุณหารด้วย 86400 (จำนวนวินาทีในหนึ่งวัน) เพื่อให้จำนวนวันโดยประมาณในช่วงนั้น

หากวันที่ที่คุณอยู่ในรูปแบบ25.1.2010, 01/25/2010หรือ2010-01-25คุณสามารถใช้strtotimeฟังก์ชั่น:

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

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

ใช้ceilรอบจำนวนวันจนถึงวันเต็มถัดไป ใช้floorแทนหากคุณต้องการรับจำนวนวันเต็มระหว่างสองวันนั้น

หากวันที่ของคุณอยู่ในรูปแบบเวลาประทับยูนิกซ์คุณสามารถข้ามการแปลงและทำ$days_betweenส่วนนั้นได้ สำหรับรูปแบบวันที่แปลกใหม่มากขึ้นคุณอาจต้องทำการวิเคราะห์คำเองเพื่อให้ถูกต้อง


9
แล้ว DST ล่ะ?
toon81

3
@ toon81 - เราใช้การประทับเวลาของ Unixเพื่อหลีกเลี่ยงความยุ่งเหยิง! ;)
Alastair

6
ให้ฉันทำอย่างละเอียด: สมมุติว่าเช้านี้เวลาตี 3 เกือบยุโรปทั้งหมดย้ายนาฬิกากลับไปหนึ่งชั่วโมง นั่นหมายความว่าวันนี้มีเวลาเพิ่มอีก 3,600 วินาทีและควรสะท้อนให้เห็นในการประทับเวลาของ UNIX หากเป็นเช่นนั้นนั่นหมายความว่าวันนี้จะนับเป็นสองวันด้วยวิธีคำนวณจำนวนวันข้างต้น และฉันก็ไม่ได้เริ่มต้นด้วยการกระโดดวินาทีเพราะทั้ง PHP และ UNIX นั้นดูเหมือนว่าจะไม่เกี่ยวข้องกับสิ่งเหล่านั้น (ซึ่งเป็น IMO ที่เข้าใจได้จริง) TL; DR: ไม่ได้ทุกวันเป็น 86,400 วินาทียาว
toon81

2
@ toon81 ไม่มีวันเพิ่มอีก 3,600 วินาที ไม่มีอะไรเกิดขึ้นกับการประทับเวลา UNIX เมื่อไปหรือจาก DST
nickdnk

1
หากไม่มีอะไรเกิดขึ้นกับ UNIX Timestamp คุณก็เห็นด้วยกับฉัน: ความแตกต่างระหว่าง UNIX Timestamp ที่เวลา 13.00 น. $dayและเวลา UNIX ที่เวลา 13.00 น$day+1ไม่เท่ากับ 86400 วินาทีในเขตเวลาที่สังเกต DST มันอาจเป็น 23 หรือ 25 ชั่วโมง 'มูลค่าวินาทีแทน 24 ชั่วโมง
toon81

112

TL; DRจะไม่ใช้ timestamps ยูนิกซ์ อย่าใช้ time()หากคุณเตรียมให้น่าเชื่อถือ 98.0825% หากความน่าเชื่อถือของคุณล้มเหลว ใช้ DateTime (หรือ Carbon)

ตอบที่ถูกต้องเป็นหนึ่งที่ได้รับจาก Saksham Gupta (คำตอบอื่น ๆ ยังมีความถูกต้อง):

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

หรือเป็นขั้นตอนเดียว:

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

และด้วยคำเตือน: มี '% a' ดูเหมือนว่าจะระบุที่แน่นอนจำนวนวัน หากคุณต้องการให้มันเป็นจำนวนเต็มที่ลงนามเช่นลบเมื่อวันที่ที่สองอยู่ก่อนวันที่หนึ่งคุณต้องใช้คำนำหน้า '% r' (เช่นformat('%r%a'))


หากคุณต้องใช้การประทับเวลา UNIX จริง ๆ ให้ตั้งค่าเขตเวลาเป็น GMTเพื่อหลีกเลี่ยงข้อผิดพลาดส่วนใหญ่ที่มีรายละเอียดด้านล่าง


คำตอบยาว: ทำไมการหารด้วย 24 * 60 * 60 (aka 86400) ไม่ปลอดภัย

คำตอบส่วนใหญ่ที่ใช้การประทับเวลา UNIX (และ 86400 เพื่อแปลงเป็นวัน) ทำให้สมมติฐานสองข้อที่นำมารวมกันสามารถนำไปสู่สถานการณ์ที่มีผลลัพธ์ที่ไม่ถูกต้องและข้อบกพร่องที่บอบบางซึ่งอาจติดตามได้ยากและเกิดขึ้นแม้แต่วันสัปดาห์หรือเดือนหลัง การปรับใช้ที่ประสบความสำเร็จ ไม่ใช่วิธีแก้ปัญหาใช้งานไม่ได้ - ใช้งานได้ ในวันนี้ แต่มันอาจหยุดทำงานในวันพรุ่งนี้

ความผิดพลาดครั้งแรกไม่ได้พิจารณาว่าเมื่อถูกถามว่า "เมื่อวานนี้กี่วันผ่านไปแล้ว" คอมพิวเตอร์อาจตอบศูนย์อย่างแท้จริงถ้าระหว่างปัจจุบันและทันทีที่ระบุโดย "เมื่อวาน" น้อยกว่าหนึ่งวันผ่านไป

โดยปกติเมื่อแปลง "วัน" เป็น UNIX Timestamp สิ่งที่ได้รับคือ Timestamp สำหรับเที่ยงคืนของวันนั้น ๆ

ดังนั้นระหว่างเที่ยงคืนของวันที่ 1 ตุลาคมและ 15 ตุลาคมสิบห้าวันจึงผ่านไป แต่ระหว่าง 13:00 วันที่ 1 ตุลาคมถึง 14:55 วันที่ 15 ตุลาคมสิบห้าวันลบ 5 นาทีผ่านไปและการแก้ปัญหาส่วนใหญ่ใช้floor()หรือทำแปลงจำนวนเต็มนัยจะรายงานในวันหนึ่งน้อยกว่าที่คาด

ดังนั้น "กี่วันที่ผ่านมาคือ Ymd H: i: s"? จะให้คำตอบที่ผิด

ความผิดพลาดที่สองนั้นเท่ากับหนึ่งวันถึง 86400 วินาที นี่เป็นเรื่องจริงเสมอ - มันเกิดขึ้นบ่อยครั้งพอที่จะมองข้ามเวลาที่มันไม่ได้ แต่ระยะทางในวินาทีระหว่างสอง midnights ติดต่อกันเป็นก็ไม่ได้ 86400 อย่างน้อยปีละสองครั้งเมื่อเวลาออมแสงเข้ามาในเล่น การเปรียบเทียบสองวันในขอบเขต DST จะให้คำตอบที่ผิด

ดังนั้นแม้ว่าคุณจะใช้ "แฮ็ค" ในการบังคับให้ประทับเวลาวันที่ทั้งหมดเป็นเวลาคงที่ให้พูดเที่ยงคืน (ซึ่งจะทำโดยภาษาและกรอบต่าง ๆ โดยปริยายเมื่อคุณระบุวันเดือนปีและไม่ชั่วโมงนาทีวินาที; happpens เดียวกันกับประเภท DATE ในฐานข้อมูลเช่น MySQL) สูตรที่ใช้กันอย่างแพร่หลาย

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

หรือ

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

จะกลับมาพูด 17 เมื่อ DATE1 และ DATE2 อยู่ในส่วน DST เดียวกันของปี; แต่มันอาจกลับ 17.042 และยิ่งแย่ไปกว่า 16.958 การใช้floor ()หรือการตัดโดยปริยายใด ๆ เป็นจำนวนเต็มจะแปลงสิ่งที่ควรเป็น 17 ถึง 16 ในสถานการณ์อื่น ๆ นิพจน์เช่น "$ days> 17" จะกลับมาtrueเป็น 17.042 แม้ว่าสิ่งนี้จะบ่งบอกว่าจำนวนวันที่ผ่านไป คือ 18

และสิ่งที่เติบโตได้ไม่สวยงามเท่าตั้งแต่รหัสดังกล่าวไม่ได้เป็นแบบพกพาข้ามแพลตฟอร์มเพราะบางคนอาจใช้เผ่นวินาทีและบางส่วนอาจจะไม่ บนแพลตฟอร์มที่ทำแตกต่างระหว่างสองวันจะไม่เป็น 86400 แต่ 86401 หรืออาจจะ 86399. ดังนั้นรหัสที่ทำงานในเดือนพฤษภาคมและจริงผ่านการทดสอบทั้งหมดจะทำลายมิถุนายนถัดไปเมื่อ 12.99999 วันที่ได้รับการพิจารณา 12 วันแทน 13. สองวัน ที่ทำงานในปี 2558 จะไม่ทำงานในปี 2560 - วันเดียวกันและปีที่ไม่เป็นปีอธิกสุรทิน แต่ระหว่างปี 2018-03-01 ถึง 2560-03-01 บนแพลตฟอร์มที่ดูแล366วันจะผ่านไปแทนที่จะเป็น 365 ทำให้ปี 2018 เป็นปีอธิกสุรทิน (ซึ่งไม่ใช่)

ดังนั้นหากคุณต้องการใช้การประทับเวลา UNIX จริง ๆ :

  • ใช้ฟังก์ชั่นอย่างชาญฉลาดไม่ได้round()floor()

  • เป็นทางเลือกอย่าคำนวณความแตกต่างระหว่าง D1-M1-YYY1 และ D2-M2-YYY2 วันที่เหล่านั้นจะได้รับการพิจารณาให้เป็น D1-M1-YYY1 00:00:00 และ D2-M2-YYY2 00:00:00 ค่อนข้างแปลงระหว่าง D1-M1-YYY1 22:30:00 และ D2-M2-YYY2 04:30:00 คุณจะมักจะได้รับส่วนที่เหลือประมาณยี่สิบสี่ชั่วโมง นี่อาจเป็นยี่สิบเอ็ดชั่วโมงหรือสิบเก้าและอาจจะสิบแปดชั่วโมงห้าสิบเก้านาทีสามสิบหกวินาที ไม่เป็นไร มันเป็นอัตรากำไรขั้นต้นขนาดใหญ่ซึ่งจะอยู่ที่นั่นและอยู่ในเชิงบวกสำหรับอนาคตอันใกล้ ตอนนี้คุณสามารถตัดมันด้วยfloor()ความปลอดภัย

วิธีการแก้ไขที่ถูกต้องแม้ว่าเพื่อหลีกเลี่ยงค่าคงที่เวทย์มนตร์, kludges ปัดเศษและหนี้การบำรุงรักษาคือการ

  • ใช้ไลบรารีเวลา (Datetime, Carbon, what) อย่าม้วนตัวคุณเอง

  • เขียนกรณีทดสอบที่ครอบคลุมโดยใช้ตัวเลือกวันที่ที่เลวร้ายจริงๆ - ข้ามขอบเขต DST ข้ามปีอธิกสุรทินข้ามวินาทีและอื่น ๆ เช่นเดียวกับวันธรรมดา (การโทรไปยังวันที่และเวลารวดเร็ว ) สร้างค่าวันที่สี่ปี (และหนึ่งวัน)โดยการรวบรวมจากสตริงเรียงตามลำดับและตรวจสอบให้แน่ใจว่าความแตกต่างระหว่างวันแรกและวันที่ทดสอบจะเพิ่มขึ้นอย่างต่อเนื่อง สิ่งนี้จะช่วยให้มั่นใจได้ว่าหากมีสิ่งใดเปลี่ยนแปลงในรูทีนระดับต่ำและการเผ่นวินาทีให้ลองแก้ไขความเสียหายอย่างน้อยที่สุดคุณจะรู้ได้

  • เรียกใช้การทดสอบเหล่านั้นเป็นประจำพร้อมกับชุดทดสอบที่เหลือ มันเป็นเรื่องของมิลลิวินาทีและอาจช่วยให้คุณประหยัดเวลาในการเกาหัวอย่างแท้จริง


ไม่ว่าวิธีการแก้ปัญหาของคุณทดสอบ!

ฟังก์ชั่นfuncdiffด้านล่างใช้หนึ่งในวิธีการแก้ปัญหา (ตามที่เกิดขึ้นได้รับการยอมรับ) ในสถานการณ์โลกแห่งความจริง

<?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";

ผลที่ได้คือ

This function failed 280 of its 14603 tests

เรื่องสยองขวัญ: ต้นทุนของ "การประหยัดเวลา"

เรื่องนี้เกิดขึ้นจริงเมื่อหลายเดือนก่อน โปรแกรมเมอร์ผู้ชาญฉลาดตัดสินใจบันทึกไมโครวินาทีจากการคำนวณซึ่งใช้เวลาประมาณสามสิบวินาทีโดยการเสียบรหัส "MidnightOfDateB-MidnightOfDateA" / Mid64OfDateA ที่น่าอับอาย "/ 86400" ในหลายแห่ง เห็นได้ชัดว่าเป็นการเพิ่มประสิทธิภาพที่เขาไม่ได้จัดทำเอกสารและการเพิ่มประสิทธิภาพผ่านการทดสอบการรวมและแฝงตัวอยู่ในรหัสเป็นเวลาหลายเดือนโดยไม่มีใครสังเกต

สิ่งนี้เกิดขึ้นในโปรแกรมที่คำนวณค่าแรงสำหรับพนักงานขายที่มียอดขายหลายรายซึ่งอย่างน้อยที่สุดก็มีความน่ากลัวมากกว่าทีมโปรแกรมเมอร์ห้าคนที่ถ่อมตัว วันหนึ่งหลายเดือนที่ผ่านมาด้วยเหตุผลที่สำคัญเล็กน้อยข้อผิดพลาดที่เกิดขึ้น - และคนเหล่านั้นบางส่วนได้รับค่าคอมมิชชั่นไขมันทั้งวัน พวกเขาไม่ได้สนุกอย่างแน่นอน

ยิ่งแย่ไปกว่านั้นพวกเขาสูญเสียศรัทธา (น้อยมาก) ที่พวกเขามีในโปรแกรมที่ไม่ได้รับการออกแบบมาเพื่อยึดมั่นพวกเขาอย่างแอบแฝงและแสร้งทำเป็น - และได้รับ - การตรวจสอบรหัสโดยละเอียดพร้อมรายละเอียด การรักษาด้วยพรมแดงในสัปดาห์ต่อมา)

สิ่งที่ฉันสามารถพูดได้: ในด้านบวกเราได้กำจัดหนี้ทางเทคนิคจำนวนมากและสามารถเขียนและปรับโครงสร้างสปาเก็ตตี้หลายชิ้นที่ฟังกลับไปที่การบุกรุกของโคบอลในยุค 90 ที่แกว่งไปมา โปรแกรมไม่ต้องสงสัยทำงานได้ดีขึ้นในขณะนี้และมีข้อมูลการดีบักมากขึ้นเพื่อให้เป็นศูนย์ได้อย่างรวดเร็วเมื่อมีอะไรที่ดูคาว ฉันคาดการณ์ว่าสิ่งสุดท้ายสิ่งนี้อาจช่วยให้มนุษย์ประหยัดได้หนึ่งหรือสองวันต่อเดือนสำหรับอนาคตอันใกล้

ในด้านลบ brouhaha ทั้ง บริษัท มีค่าใช้จ่ายประมาณ 200,000 ยูโรต่อหน้า - บวกกับใบหน้าและไม่ต้องสงสัยเลยว่าอำนาจการต่อรองบางอย่าง (และดังนั้นจึงยังมีเงินมากขึ้น)

คนที่แต่งตัวประหลาดที่รับผิดชอบในการ "เพิ่มประสิทธิภาพ" ได้เปลี่ยนงานเมื่อปีที่แล้วก่อนเกิดภัยพิบัติ แต่ก็ยังมีการพูดคุยกับเขาเพื่อฟ้องเรียกค่าเสียหาย และมันก็ไปได้ไม่ดีกับตำแหน่งบนที่ว่ามันเป็น "ความผิดของคนสุดท้าย" - ดูเหมือนว่าเราจะได้ทำความสะอาดเรื่องและในที่สุดเราก็ยังอยู่ในคอกหมา และหนึ่งในทีมกำลังวางแผนที่จะลาออก

เก้าสิบเก้าครั้งจากหนึ่งร้อย "86400 แฮ็ค" จะทำงานได้อย่างไร้ที่ติ (ตัวอย่างเช่นใน PHP strtotime()จะละเว้น DST และรายงานว่าระหว่างเที่ยงคืนของวันเสาร์สุดท้ายของเดือนตุลาคมและของวันจันทร์ถัดไปตรงเวลา 2 * 24 * 60 * 60 วินาทีผ่านไปแม้ว่าจะไม่เป็นความจริง ... และความผิดสองอย่างจะทำให้มีความสุข)

นี่คือสุภาพสตรีและสุภาพบุรุษเป็นหนึ่งในตัวอย่างเมื่อมันไม่ได้ เช่นเดียวกับเครื่องกระเป๋าและเข็มขัดนิรภัยคุณจะอาจจะไม่เคยจริงๆต้องซับซ้อน (และความสะดวกในการใช้งาน) ของหรือDateTime Carbonแต่วันที่คุณอาจ (หรือวันที่คุณต้องพิสูจน์ว่าคุณคิดเกี่ยวกับสิ่งนี้) จะมาเป็นขโมยในเวลากลางคืน เตรียมตัว.


7
เมื่อฉันเห็นคำตอบเหล่านี้ฉันคิดว่าฉันโง่และบ้าคลั่งเพราะฉันใช้ DateTime เสมอ แต่คุณทำให้ฉันเข้าใจว่าการใช้ DateTime นั้นเป็นวิธีที่ถูกต้อง ขอขอบคุณ
Syncro

เฮ้ทุกคนที่นี่บน SO มาที่นี่โดยค้นหาใน google days between two days in phpหรือสิ่งที่คล้ายกันเพียงเพราะชีวิตนั้นสั้นเกินไปที่จะเขียนทุกอย่างด้วยตัวเอง
เดนิส Matafonov

1
คำอธิบายโดยละเอียด + 1
Anant Singh --- ยังมีชีวิตอยู่เพื่อตาย

1
บางครั้งฉันก็หวังว่าเราจะได้คำตอบที่ชื่นชอบมากกว่าคำถาม
Clément Baconnier

นี่จะต้องเป็นคำตอบที่ได้รับการยอมรับ
Franz

16

ง่ายต่อการใช้ 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');

นี่เป็นวิธีการที่ดีในการทำโดยใช้คลาส DateTime มันขาดการใช้วัตถุช่วงเวลาอย่างชัดเจนเท่านั้น ( $diffตัวแปรในกรณีนี้) บางสิ่งบางอย่างที่เหมือนกัน if ($diff->days > 30) { [doyourstuff]; }
Gusstavv Gil

16

สไตล์เชิงวัตถุ:

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

สไตล์ขั้นตอน:

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

11

ใช้สิ่งนี้ :)

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

ตอนนี้มันใช้งานได้


14
ความคิดเห็นเก่ามากด้านบน แต่ไม่ถูกต้อง StackOverflow ไม่ช่วยให้คุณสามารถที่จะตอบคำถามของคุณเอง (แม้เมื่อคุณถามคำถามของคุณ) การตอบคำถามด้วยตัวคุณเองหลังจากที่ใครบางคนโพสต์ไปแล้วด้วยวิธีการแก้ปัญหาเดียวกันนี้ถือเป็นเรื่องหยาบคาย
Maarten Bodewes

ฟังก์ชั่นนี้ล้มเหลว 560 จากการทดสอบ 14603 ครั้งระหว่างปี 1980 และ 2020
LSerni

10

คำตอบที่เลือกไม่ใช่คำตอบที่ถูกที่สุดเพราะมันจะล้มเหลวนอก UTC ขึ้นอยู่กับเขตเวลา ( รายการ ) อาจมีการปรับเวลาในการสร้างวัน "โดยไม่มี" 24 ชั่วโมงและสิ่งนี้จะทำให้การคำนวณ (60 * 60 * 24) ล้มเหลว

นี่คือตัวอย่างของมัน:

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**

ดังนั้นทางออกที่ถูกต้องจะใช้ 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

คำนวณความแตกต่างระหว่างวันที่สองวัน:

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

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

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

เอาท์พุต: +272 วัน

ฟังก์ชัน date_diff () จะคืนค่าความแตกต่างระหว่างวัตถุ DateTime สองตัว


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

ฟังก์ชั่นนี้ล้มเหลว 560 จากการทดสอบ 14603 ครั้งระหว่างปี 1980 และ 2020
LSerni

6

ฉันกำลังใช้Carbonในโครงการผู้แต่งเพื่อวัตถุประสงค์นี้และสิ่งที่คล้ายกัน

มันจะง่ายอย่างนี้:

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

5

คุณสามารถค้นหาวันที่ได้ง่ายๆ

<?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


3

หากคุณมีเวลาเป็นวินาที (IE unix time stamp) คุณสามารถลบเวลาและหารด้วย 86400 (วินาทีต่อวัน)


3

จำนวนวันระหว่างสองวันใน 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
ยอดเยี่ยมมันใช้งานได้อย่างมีเสน่ห์คุณสามารถบอกฉันได้ว่า 86400 NUM มีไว้เพื่ออะไร
Parth Shah

ใช้หมายเลข 86400 เป็นเวลา 1 วัน = 24 ชั่วโมงและ 24 * 60 * 60 = 86400 วินาทีต่อวัน
mallikarjun SK

3

คุณสามารถลองรหัสด้านล่าง:

$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
ด้วยคำถามที่มีอายุมากกว่าซึ่งมีคำตอบอยู่แล้วจะเป็นประโยชน์ในการอธิบายแง่มุมใหม่ที่คำตอบของคุณนำมาสู่คำถาม หากมีความเกี่ยวข้องจะเป็นประโยชน์ในการรับทราบการเปลี่ยนแปลงใด ๆ ที่อาจเกิดขึ้นตั้งแต่คำถามถูกถาม
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;
} 

ฟังก์ชั่นนี้ล้มเหลว 320 การทดสอบ 14603 ครั้งระหว่างปี 1980 และ 2020
LSerni

2

ถ้าคุณต้องการที่จะสะท้อนทุกวันระหว่างวันที่เริ่มต้นและวันที่สิ้นสุดฉันมาพร้อมกับสิ่งนี้:

$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

วิธีที่ง่ายที่สุดในการค้นหาความแตกต่างของวันระหว่างสองวัน

$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

นี่คือเวอร์ชั่นที่ปรับปรุงของฉันซึ่งแสดง 1 ปี 2 เดือน 25 วันหากพารามิเตอร์ที่ 2 ถูกส่งผ่าน

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");
?>

ใช้รหัสข้างต้นง่ายมาก ขอบคุณ


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

ใช้ฟังก์ชั่นที่เรียบง่ายนี้ ประกาศฟังก์ชั่น

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

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

และเรียกฟังก์ชั่นนี้แบบนี้ในที่ที่คุณต้องการ

<?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
ยินดีต้อนรับสู่ SO! เมื่อคุณตอบกลับโพสต์ด้วยรหัสเพียงโปรดอธิบายเล็กน้อย รหัสที่คุณนำมาคำนวณระหว่างวันที่ 2019-11-10 ถึง 2019-11-25 ดังนั้นจึงไม่ได้ตอบคำถาม นั่นเป็นเหตุผลที่ดีที่จะอธิบาย POV ของคุณให้ดีกว่าการลงคะแนน
David García Bodego

0

หากคุณใช้ 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

ลองใช้ Carbon

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

นอกจากนี้คุณสามารถใช้

\Carbon\Carbon::parse('')

เพื่อสร้างวัตถุของวันที่คาร์บอนโดยใช้สตริงเวลาที่กำหนด


คุณช่วยกรุณาบอกความแตกต่างระหว่างนี้และคำตอบของฉันได้อย่างไร
Arda

1
หากต้องการทำวันที่ที่แตกต่างอย่างง่ายคุณแนะนำให้รวมแพ็คเกจใหม่ทั้งหมดไว้ด้วยหรือไม่
tomazahlin

0

หาคำตอบทั้งหมดฉันเขียนฟังก์ชั่นสากลว่าทำงานได้กับ 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;

โดยทั่วไปแล้วฉันใช้ 'DateTime' เพื่อค้นหาวันระหว่าง 2 วัน แต่ถ้าด้วยเหตุผลบางอย่างการตั้งค่าเซิร์ฟเวอร์บางอย่างไม่ได้เปิดใช้งาน 'DateTime' มันจะใช้การคำนวณแบบง่าย ๆ (แต่ไม่ปลอดภัย) ด้วย 'strtotime ()'

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.