Intervallsekunden zwischen zwei Datums- und Uhrzeitangaben in PHP abrufen?


Antworten:


131

Sie können dazu strtotime () verwenden:

$diff = strtotime('2009-10-05 18:11:08') - strtotime('2009-10-05 18:07:13')

Ein ähnlicher Ansatz ist mit DateTime-Objekten möglich, z

$date = new DateTime( '2009-10-05 18:07:13' );
$date2 = new DateTime( '2009-10-05 18:11:08' );

$diff = $date2->getTimestamp() - $date->getTimestamp();

1
Hinweis: Stellen Sie sicher, dass Sie das Großbuchstaben "H" für Stunden (24-Stunden-Modus) verwenden, wenn Ihre "niedrigere" Zeit "jetzt" ist und Sie verwenden date(), um die Datumszeit von jetzt ( date("Y-m-d H:i:s")) abzurufen .
jave.web

`` `Daten in den Formaten m / d / y oder dmy werden durch Betrachten des Trennzeichens zwischen den verschiedenen Komponenten eindeutig: Wenn das Trennzeichen ein Schrägstrich (/) ist, wird das amerikanische m / d / y angenommen; Wenn das Trennzeichen ein Bindestrich (-) oder ein Punkt (.) ist, wird das europäische dmy-Format angenommen. Wenn das Jahr jedoch in einem zweistelligen Format angegeben ist und das Trennzeichen ein Bindestrich ist (-, wird die Datumszeichenfolge als ymd analysiert. Um mögliche Mehrdeutigkeiten zu vermeiden, verwenden Sie am besten Datumsangaben oder ISO 8601 (JJJJ-MM-TT) DateTime :: createFromFormat () wenn möglich. `` `
Nikola Petkanski

Überprüfen Sie die JCM-Antwort und wählen Sie Ihren Fall aus
Leandro

156

Mit DateTime-Objekten können Sie dies folgendermaßen tun:

$date = new DateTime( '2009-10-05 18:07:13' );
$date2 = new DateTime( '2009-10-05 18:11:08' );

$diffInSeconds = $date2->getTimestamp() - $date->getTimestamp();

1
Dies berücksichtigt auch die Sommerzeit!
Brainware

5
Dies ist die eleganteste Lösung für die Frage. Dies sollte die akzeptierte Antwort sein.
Giel Berkers

1
Beachten Sie, dass Sie die richtige DateTimeZone angeben müssen, damit die Sommerzeit korrekt berücksichtigt wird. Wenn Ihr System korrekt eingerichtet ist, kennt PHP Ihre Zeitzone möglicherweise bereits aus dem Systemstandard. Wenn dies in Frage kommt, instanziieren Sie eine manuell wie folgt: $ tz = new DateTimeZone ('Europe / Berlin'); und übergeben Sie es als zweiten Parameter an den DateTime-Konstruktor.
j4k3

Tolle Lösung, aber für längere Zeiträume (Beispiel 1 Stunde) erhalte ich einen negativen Wert (Überlauf?). Gibt es eine Idee, wie ich das beheben kann?
Marto


4

Aufgrund von Einschränkungen der Unix-Epoche können Probleme beim Vergleichen von Daten vor 1970 und nach 2038 auftreten. Ich entscheide mich dafür, die Genauigkeit zu verlieren (= nicht auf die einzelne Sekunde schauen), aber es zu vermeiden, Unix-Epochen-Konvertierungen (getTimestamp) zu durchlaufen. Es hängt davon ab, was Sie tun ...

In meinem Fall hat die Verwendung von 365 (12 * 30) und "30" als mittlere Monatslänge den Fehler in einer verwendbaren Ausgabe verringert.

function DateIntervalToSec($start,$end){ // as datetime object returns difference in seconds
    $diff = $end->diff($start);
    $diff_sec = $diff->format('%r').( // prepend the sign - if negative, change it to R if you want the +, too
                ($diff->s)+ // seconds (no errors)
                (60*($diff->i))+ // minutes (no errors)
                (60*60*($diff->h))+ // hours (no errors)
                (24*60*60*($diff->d))+ // days (no errors)
                (30*24*60*60*($diff->m))+ // months (???)
                (365*24*60*60*($diff->y)) // years (???)
                );
    return $diff_sec;
}

Beachten Sie, dass der Fehler 0 sein kann, wenn "mittlere" Mengen für diff vorgesehen sind. Die PHP-Dokumente sprechen nicht darüber ... In einem schlechten Fall könnte ein Fehler sein:

  • 0 Sekunden, wenn diff auf Zeitlücken <1 Monat angewendet wird
  • 0 bis 3 Tage, wenn diff auf Zeitlücken> 1 Monat angewendet wird
  • 0 bis 14 Tage, wenn diff auf Zeitlücken> 1 Jahr angewendet wird

Ich nehme lieber an, dass jemand beschlossen hat, "m" als 30 Tage und "y" als 365 zu betrachten und "d" mit dem Unterschied zu berechnen, wenn "diff" durch Nicht-30-Tage-Monate läuft ...

Wenn jemand etwas mehr darüber weiß und offizielle Unterlagen vorlegen kann, ist er willkommen!


Verwenden Sie die Eigenschaft days anstelle der Eigenschaft d, um die genauen Tage zwischen den beiden Tagen abzurufen. Also keine ungenauen Ergebnisse da.
Nilz11

2
strtotime("2009-10-05 18:11:08") - strtotime("2009-10-05 18:07:13")

2

Wenn Sie den tatsächlichen lokalen Zeitunterschied benötigen und damit arbeiten möchten getTimestamp, müssen Sie die Sommerzeitschalter während des berechneten Zeitraums berücksichtigen. Daher muss der lokale Versatz zu UTC in die Gleichung einbezogen werden.

Nehmen Sie zum Beispiel die folgenden Daten:

$tz = new \DateTimeZone("Europe/Berlin");
$start = new \DateTime("2018-02-01 12:00:00", $tz);
$end = new \DateTime("2018-04-01 12:00:00", $tz);

$startist "2018-02-01 11:00:00" in UTC, während $end"2018-04-01 10:00:00" in UTC ist. Beachten Sie, dass die Tageszeit in der Berliner Zeitzone zwar gleich ist, in UTC jedoch anders. Der UTC-Offset beträgt eine Stunde $startund 2 Stunden $end.

Denken Sie daran, dass getTimestampimmer UTC zurückgibt! Daher müssen Sie den Versatz vom Zeitstempel abziehen, wenn Sie nach der tatsächlichen lokalen Differenz suchen.

// WRONG! returns 5094000, one hour too much due to DST in the local TZ
echo $end->getTimestamp() - $start->getTimestamp();

// CORRECT: returns 5090400
echo ($end->getTimestamp() - $end->getOffset()) - ($start->getTimestamp() - $start->getOffset());

Diese Antwort ist eine schreckliche Fehlinformation. Ich habe gerade meinen eigenen Testfall geschrieben, um dies zu überprüfen, und ich bin froh, dass sich herausstellt, dass es einfach völlig falsch ist. 5094000% 86400 = 82800. Das ist ein ganzer Tag von Sekunden minus 3600 für die "fehlende Stunde", wenn die Uhr an der Sommerzeitgrenze eine Stunde vorspringt. Einfachere Testfälle: Die Zeitstempeldifferenz zwischen "2019-03-31 01:59:59" und "2019-03-31 03:00:01" beträgt 2 Sekunden. Dies ist der richtige Betrag. Die Zeitstempeldifferenz zwischen "2019-10-27 01:59:59" und "2019-10-27 02:00:01" beträgt 3602 Sekunden, was der richtige Betrag ist.
j4k3

Weitere Informationen hierzu: getTimestamp und setTimestamp beziehen sich auf den Unix-Zeitstempel, der immer frei von Zeitzonen ist . Sie mischen zeitzonenfreie Formate mit Zeitzonen-Offsets. In Ihrem Beispiel "Umgang mit Unix-Zeitstempeln" suchen Sie nach 3600 + 1 = 3720 Sekunden, da die Uhr eine Stunde zurückgewählt wird, nicht zwei.
j4k3

-1

Eine einfache und genaue Lösung (als Beispiel für den Kommentar von Nilz11):

$hiDate = new DateTime("2310-05-22 08:33:26");
$loDate = new DateTime("1910-11-03 13:00:01");
$diff = $hiDate->diff($loDate);
$secs = ((($diff->format("%a") * 24) + $diff->format("%H")) * 60 + 
   $diff->format("%i")) * 60 + $diff->format("%s");
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.