it-swarm.com.de

Die Anzahl der Tage zwischen zwei Terminen ermitteln

Wie finde ich die Anzahl der Tage zwischen zwei Daten mit PHP?

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

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

Wenn Sie PHP 5.3 > verwenden, ist dies bei weitem der genaueste Weg, um den Unterschied zu berechnen:

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

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

Ab PHP Version 5.3 wurden neue Datums Zeitfunktionen -/hinzugefügt, um Unterschiede zu erhalten:

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

Ergebnis wie folgt:

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
)

Ich hoffe es hilft !

142
Aditya P Bhatt

Konvertieren Sie Ihre Datumsangaben in Unix-Zeitstempel und ziehen Sie dann einen Wert vom anderen ab. Das gibt Ihnen die Differenz in Sekunden, die Sie durch 86400 (Anzahl Sekunden pro Tag) teilen, um Ihnen eine ungefähre Anzahl von Tagen in diesem Bereich zu geben.

Wenn Ihre Daten im Format 25.1.2010, 01/25/2010 oder 2010-01-25 vorliegen, können Sie die Funktion strtotime verwenden:

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

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

Die Verwendung von ceil rundet die Anzahl der Tage bis zum nächsten vollen Tag. Verwenden Sie stattdessen floor, wenn Sie die Gesamtzahl der Tage zwischen diesen beiden Daten ermitteln möchten.

Wenn Ihre Datumsangaben bereits im Unix-Zeitstempelformat vorliegen, können Sie die Konvertierung überspringen und den Teil $days_between ausführen. Bei exotischeren Datumsformaten müssen Sie möglicherweise etwas benutzerdefiniertes Parsing durchführen, um es richtig zu machen.

122
Tatu Ulmanen

TL; DR do not Verwenden Sie UNIX-Zeitstempel. Verwenden Sie nicht time(). Wenn Sie dies tun,seien Sie vorbereitetsollte die Zuverlässigkeit von 98.0825% ausfallen. Verwenden Sie DateTime (oder Carbon).

Die richtige Antwort ist die von Saksham Gupta gegebene (andere Antworten sind auch richtig):

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

Oder prozedural als Einzeiler:

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

Mit einer Einschränkung: Das '% a' scheint die absolute Anzahl der Tage anzuzeigen. Wenn Sie möchten, dass es eine Ganzzahl mit Vorzeichen ist, d. H. Negativ, wenn das zweite Datum vor dem ersten liegt, müssen Sie das Präfix '% r' (d. H. format('%r%a')) verwenden.


Wenn Sie wirklich UNIX-Zeitstempel verwenden müssen, setzen Sie die Zeitzone auf GMT , umdie meistender unten aufgeführten Fehlerquellen zu vermeiden.


Lange Antwort: Warum das Teilen durch 24 * 60 * 60 (aka 86400) unsicher ist

Die meisten Antworten, die UNIX-Zeitstempel verwenden (und 86400, um diese in Tage umzuwandeln), gehen von zwei Annahmen aus, die zusammengenommen zu Szenarien mit falschen Ergebnissen und ) führen können subtile Bugs , die möglicherweise schwer zu verfolgen sind und sogar Tage, Wochen oder Monate nach einer erfolgreichen Bereitstellung auftreten. Es ist nicht so, dass die Lösung nicht funktioniert - es funktioniert. Heute. Aber es könnte morgen aufhören zu arbeiten.

Der erste Fehler ist, dass ein Computer, wenn er gefragt wird: "Wie viele Tage sind seit gestern vergangen?", Wahrheitsgemäß antworten könnte 0 , wenn zwischen der Gegenwart und dem durch "gestern" angezeigten Zeitpunkt weniger alsein ganzer Tagist vergangen.

Normalerweise wird beim Konvertieren eines "Tages" in einen UNIX-Zeitstempel der Zeitstempel für den Mitternacht des jeweiligen Tages ermittelt.

Zwischen dem 1. Oktober und dem 15. Oktober sind also fünfzehn Tage vergangen. Aber zwischen 13:00 am 1. Oktober und 14:55 am 15. Oktober sindfünfzehn Tage minus 5 Minutenvergangen, und die meisten Lösungen verwenden floor() oder implizite Ganzzahlkonvertierung durchführen meldet einen Tag weniger als erwartet .

Also, "vor wie vielen Tagen war Y-m-d H: i: s"? ergibt falsche Antwort .

Der zweite Fehler entspricht einem Tag und 86400 Sekunden. Dies ist fast immer wahr - es passiert oft genug, um die Zeiten zu übersehen, in denen es nicht passiert. Aber die Entfernung in Sekunden zwischen zwei aufeinanderfolgenden Mitternächten beträgt sicherlich nicht mindestens zweimal im Jahr 86400, wenn die Sommerzeit ins Spiel kommt. Wenn Sie zwei Daten über eine DST-Grenze hinweg vergleichen, erhalten Sie die falsche Antwort.

Auch wenn Sie den "Hack" verwenden, der alle Datumszeitstempel auf eine feste Stunde zwingt, sagen Sie "Mitternacht" (dies wird implizit auch von verschiedenen Sprachen und Frameworks durchgeführt, wenn Sie nur Tag-Monat-Jahr und nicht auch Stunde-Minute-Sekunde angeben. Dasselbe geschieht mit dem Typ DATE in Datenbanken wie MySQL, der weit verbreiteten Formel

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

oder

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

gibt beispielsweise 17 zurück, wenn sich DATE1 und DATE2 im selben DST-Segment des Jahres befinden. aber es kann 17,042 und noch schlimmer 16,958 zurückgeben. Die Verwendung vonfloor ()oder einer impliziten Kürzung in eine Ganzzahl konvertiert dann eine 17 in eine 16. Unter anderen Umständen können Ausdrücke wie "$ days> 17" verwendet werden "gibt true für 17,042 zurück, auch wenn dies anzeigt, dass die Anzahl der verstrichenen Tage 18 beträgt.

Und die Dinge werden noch hässlicher, da ein solcher Code ist nicht portabel plattformübergreifend ist, weil einige von ihnen möglicherweise Schaltsekunden anwenden und andere möglicherweise nicht . Auf den Plattformen, diedosind, beträgt der Unterschied zwischen zwei Daten nicht 86400, sondern 86401 oder vielleicht 86399. Code, der im Mai funktioniert hat und alle Tests bestanden hat, bricht als nächstes ab Juni, wenn 12.99999 Tage als 12 statt 13 Tage betrachtet werden. Zwei Daten, die 2015 gearbeitet haben, funktionieren 2017 nicht - diegleichenDaten, und keines der beiden Jahre ist ein Schaltjahr . Aber zwischen dem 01.03.2018 und dem 01.03.2017 sind auf diesen Plattformen 366 Tage vergangen, anstatt 365, was 2017 zu einem Schaltjahr macht.

Wenn Sie also wirklich UNIX-Zeitstempel verwenden möchten:

  • benutze round() mit Bedacht, nicht floor().

  • berechnen Sie alternativ keine Unterschiede zwischen D1-M1-YYY1 und D2-M2-YYY2. Diese Daten werden als D1-M1-YYY1 00:00:00 und D2-M2-YYY2 00:00:00 betrachtet. Konvertieren Sie stattdessen zwischen D1-M1-YYY1 22:30:00 und D2-M2-YYY2 04:30:00. Sie werdenimmereinen Rest von ungefähr zwanzig Stunden bekommen. Dies kann einundzwanzig Stunden oder neunzehn werden, und vielleicht achtzehn Stunden, neunundfünfzig Minuten und sechsunddreißig Sekunden. Ganz gleich. Es ist eingroßer Spielraum, der dort bleiben und auf absehbare Zeit positiv bleiben wird.Jetztkönnen Sie es mit floor() in Sicherheit abschneiden.

Die richtige Lösung ist jedoch, um magische Konstanten, Rundungsklumpen und eine Unterhaltsschuld zu vermeiden

  • verwenden Sie eine Zeitbibliothek (Datetime, Carbon, was auch immer); Würfle nicht deine eigenen

  • schreiben Sie umfassende Testfälle mit wirklich schlechten Datumswahlen - über die DST-Grenzen, über Schaltjahre, Schaltsekunden usw. hinweg sowie über alltägliche Daten. Im Idealfall (Aufrufe von datetime sindfast!) Generieren Sievier ganze Jahre (und einen Tag)im Wert von Datumsangaben indem Sie sie nacheinander aus Zeichenfolgen zusammensetzen und sicherstellen, dass der Unterschied zwischen dem ersten Tag und dem zu testenden Tag stetig um eins zunimmt. Dies stellt sicher, dass, wenn sich Änderungen an den Routinen auf niedriger Ebene und an den SchaltsekundenFixesergeben, zumindest Siewissen.

  • führen Sie diese Tests regelmäßig zusammen mit dem Rest der Testsuite durch. Sie sind eine Frage von Millisekunden und können Ihnen buchstäblichStundenKopfkratzen ersparen.


Was auch immer Ihre Lösung ist, testen Sie sie!

Die Funktion funcdiff unten implementiert eine der Lösungen (wie es passiert, die akzeptierte) in einem realen Szenario.

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

Das Ergebnis ist,

This function failed 280 of its 14603 tests

Horror Story: Die Kosten für "Zeitersparnis"

Das ist tatsächlich vor einigen Monaten passiert. Ein genialer Programmierer entschied sich dafür, mehrere Mikrosekunden weniger zu berechnen, als es an einigen Stellen etwa dreißig Sekunden dauerte, indem er den berüchtigten Code "(MidnightOfDateB-MidnightOfDateA)/86400" einfügte. Eine Optimierung war so offensichtlich, dass er sie nicht einmal dokumentierte, und die Optimierung bestand die Integrationstests und lauerte unbemerkt mehrere Monate im Code.

Dies geschah in einem Programm, das die Löhne für mehrere umsatzstärkste Verkäufer berechnet, von denen die wenigsten viel mehr Einfluss haben als ein ganzes bescheidenes fünfköpfiges Programmiererteam zusammen. Eines Tages vor einigen Monaten wurde der Fehler aus Gründen, die keine Rolle spielen, aufgedeckt - undeinigedieser Jungs haben einen ganzen Tag lang fette Provisionen verloren. Sie waren definitivnichtamüsiert.

Schlimmer noch, sie verloren das (ohnehin sehr geringe) Vertrauen in das Programmnot, das darauf ausgelegt war, sie heimlich zu beschützen, und gaben vor - und ) erhalten zu haben - eine vollständige, detaillierte Codeüberprüfung mit Testfällen, die von Laien ausgeführt und kommentiert wurden (plus viel Behandlung auf dem roten Teppich in den folgenden Wochen).

Was kann ich sagen: Auf der positiven Seite haben wir eine Menge technischer Schulden beseitigt und konnten mehrere Teile eines Spaghetti-Chaos, das auf einen COBOL-Befall in den 90er-Jahren zurückzuführen war, umschreiben und umgestalten. Zweifellos läuft das Programm jetzt besser und es gibt viel mehr Debugging-Informationen, die Sie schnell finden können, wenn etwas faul aussieht. Ich schätze, dass gerade diese letzte Sache auf absehbare Zeit vielleicht ein oder zwei Manntage pro Monat einsparen wird.

Auf der negativen Seite kostete das ganze Brouhaha das Unternehmen im Vorfeld rund 200.000 Euro - plus Gesicht plus zweifellos etwas Verhandlungsmacht (und damit noch mehr Geld).

Der für die "Optimierung" Verantwortliche hatte vor einem Jahr vor der Katastrophe den Job gewechselt, aber es gab immer noch Gespräche, um ihn auf Schadensersatz zu verklagen. Und es war nicht gut für die Oberklasse, dass es "die Schuld des letzten Mannes" war - es sah so aus, als hätten wir uns vorgenommen, die Angelegenheit zu klären, und am Ende sind wir immer noch in der Hundehütte und einer der Teammitglieder plant aufzuhören.

Neunundneunzig von einhundert funktioniert der "86400 Hack" einwandfrei. (In PHP beispielsweise ignoriert strtotime() die Sommerzeit und meldet, dass zwischen dem letzten Samstag im Oktober und dem folgenden Montag genau 2 * 24 * 60 * 60 Sekunden vergangen sind, auch wenn dies der Fall ist ist eindeutignicht wahr... und zwei Fehler machen glücklich einen richtig).

Dies, meine Damen und Herren, wareineInstanz, als dies nicht der Fall war. Wie bei Airbags und Sicherheitsgurten werden Sie vielleicht niewirklichdie Komplexität (und Benutzerfreundlichkeit) von DateTime oder Carbon. Aber der Tag, an dem Sievielleicht(oder der Tag, an dem Siebeweisen müssenSie haben darüber nachgedacht) wird in der Nacht wie ein Dieb kommen. Sei vorbereitet.

91
LSerni

Einfach, date_diff zu benutzen

$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');
16
Balaji D

Objektorientierter Stil:

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

Verfahrensstil:

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

Nun, die ausgewählte Antwort ist nicht die korrekteste, da sie außerhalb von UTC fehlschlägt. Abhängig von der Zeitzone ( list ) kann es Zeitanpassungen geben, an denen Tage "ohne" 24 Stunden erstellt werden, und dies wird die Berechnung (60 * 60 * 24) schlägt fehl.

Hier ist ein Beispiel davon:

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

Die richtige Lösung wird also DateTime verwenden

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**
9
Miguel Costa

Verwendet das :)

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

Jetzt gehts

8
PHP Ferrari
$start = '2013-09-08';
$end = '2013-09-15';
$diff = (strtotime($end)- strtotime($start))/24/3600; 
echo $diff;
5
power66x

Ich verwende Carbon in meinen Komponistenprojekten für diese und ähnliche Zwecke.

Es wäre so einfach wie folgt:

$dt = Carbon::parse('2010-01-01');
echo $dt->diffInDays(Carbon::now());
5
Arda
$datediff = floor(strtotime($date1)/(60*60*24)) - floor(strtotime($date2)/(60*60*24));

und bei Bedarf:

$datediff=abs($datediff);
3
Gratian

anzahl der Tage zwischen zwei Daten in 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 "; 
2

Berechnen Sie die Differenz zwischen zwei Daten:

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

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

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

Leistung: +272 Tage

Die Funktion date_diff () gibt die Differenz zwischen zwei DateTime-Objekten zurück.

2

Wenn Sie die Zeiten in Sekunden haben (I.E. Unix-Zeitstempel), können Sie die Zeiten einfach abziehen und durch 86400 (Sekunden pro Tag) dividieren.

2
zmbush

Termine finden Sie einfach durch

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

Wenn Sie alle Tage zwischen Start- und Enddatum wiederholen möchten, habe ich Folgendes gefunden:

$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>";
}
1
Refilon
function howManyDays($startDate,$endDate) {

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

return $res;
} 
1
Thor

Hier ist meine verbesserte Version, die 1 Jahr (e) 2 Monat (e) 25 Tag (e) anzeigt, wenn der 2. Parameter übergeben wird.

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;
    }
}
0
$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;
}
0
radhason power
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);
0
user3216114
<?php
$date1=date_create("2013-03-15");
$date2=date_create("2013-12-12");
$diff=date_diff($date1,$date2);
echo $diff->format("%R%a days");
?>

benutzte den obigen Code sehr einfach. Vielen Dank.

0
    // 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";
0
engineervix

Sie können den folgenden Code ausprobieren:

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

Verwendung dieser einfachen Funktion. Funktion deklarieren

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

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

und rufen Sie diese Funktion so auf, wo Sie möchten

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

// OR

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