Wie bekomme ich bei einem Unix-Zeitstempel den Beginn und das Ende dieses Tages?

Lesezeit: 8 Minuten

Benutzer-Avatar
Kralle

Ich habe einen Unix-Zeitstempel wie folgt:

$timestamp=1330581600

Wie bekomme ich den Beginn des Tages und das Ende des Tages für diesen Zeitstempel?

e.g.
$beginOfDay = Start of Timestamp's Day
$endOfDay = End of Timestamp's Day

Ich habe das versucht:

$endOfDay = $timestamp + (60 * 60 * 23);

Aber ich glaube nicht, dass es funktionieren wird, weil der Zeitstempel selbst nicht der genaue Beginn des Tages ist.

  • Wenn es GMT ist, wahrscheinlich: $boundary = floor/ceil($timestamp / (60 * 60 * 24)) * (60 * 60 * 24);

    – hakre

    17. April 2012 um 19:36 Uhr

  • Wenn Ihre erwartete Ausgabe ein Zeitstempel als Ganzzahl ist, gibt es einen einfachen Einzeiler: $beginOfDay = mktime(0, 0, 0, date(‘n’), date(‘j’) – 1); $endOfDay = mktime(0, 0, 0, date(‘n’), date(‘j’));

    – Jarederaj

    18. Januar 2016 um 18:54 Uhr

Benutzer-Avatar
rrehbein

strtotime kann verwendet werden, um die Stunden/Minuten/Sekunden schnell abzuschneiden

$beginOfDay = strtotime("today", $timestamp);
$endOfDay   = strtotime("tomorrow", $beginOfDay) - 1;

DateTime kann auch verwendet werden, erfordert jedoch einige zusätzliche Schritte, um einen langen Zeitstempel zu erhalten

$dtNow = new DateTime();
// Set a non-default timezone if needed
$dtNow->setTimezone(new DateTimeZone('Pacific/Chatham'));
$dtNow->setTimestamp($timestamp);

$beginOfDay = clone $dtNow;
$beginOfDay->modify('today');

$endOfDay = clone $beginOfDay;
$endOfDay->modify('tomorrow');
// adjust from the start of next day to the end of the day,
// per original question
// Decremented the second as a long timestamp rather than the
// DateTime object, due to oddities around modifying
// into skipped hours of day-lights-saving.
$endOfDateTimestamp = $endOfDay->getTimestamp();
$endOfDay->setTimestamp($endOfDateTimestamp - 1);

var_dump(
    array(
        'time ' => $dtNow->format('Y-m-d H:i:s e'),
        'start' => $beginOfDay->format('Y-m-d H:i:s e'),
        'end  ' => $endOfDay->format('Y-m-d H:i:s e'),
    )
);

Mit der Hinzufügung der erweiterten Zeit in PHP7 besteht die Möglichkeit, dass bei der Verwendung eine Sekunde verpasst wird $now <= $end damit prüfen. Verwenden $now < $nextStart Das Überprüfen würde diese Lücke vermeiden, zusätzlich zu den Kuriositäten rund um das Subtrahieren von Sekunden und Sommerzeit in der Zeitverwaltung von PHP.

  • Warum minus 1 Sekunde am Ende?

    – Kurt Zhong

    28. Januar 2013 um 7:31 Uhr

  • Ich hatte die ursprüngliche Frage so gelesen, dass sie die letzte Sekunde des Tages bekam, und nicht die erste Sekunde des nächsten Tages. ‘morgen’ gibt die erste Sekunde des Tages an, also ‘-1’, um die Sekunde vor der ersten Sekunde des Tages zu erhalten.

    – rrehbein

    28. Januar 2013 um 14:24 Uhr

  • ‘today’ gibt auch den Beginn des Tages zurück strtotime('today', $timestamp)

    – Semra

    23. März 2015 um 17:46 Uhr

  • Scheint anfällig für Schaltsekundenprobleme zu sein

    – Brad Kent

    27. Juli 2015 um 19:45 Uhr

  • $endOfDay->modify('tomorrow -1 second'); funktioniert auch.

    – CGodo

    28. Dezember 2017 um 0:32 Uhr

Nur DateTime

$beginOfDay = DateTime::createFromFormat('Y-m-d H:i:s', (new DateTime())->setTimestamp($timestamp)->format('Y-m-d 00:00:00'))->getTimestamp();
$endOfDay = DateTime::createFromFormat('Y-m-d H:i:s', (new DateTime())->setTimestamp($timestamp)->format('Y-m-d 23:59:59'))->getTimestamp();

Zuerst wird ein DateTime-Objekt erstellt und der Zeitstempel auf den gewünschten Zeitstempel gesetzt. Dann wird das Objekt als String formatiert, der die Stunde/Minute/Sekunde auf den Beginn oder das Ende des Tages setzt. Schließlich wird aus dieser Zeichenfolge ein neues DateTime-Objekt erstellt und der Zeitstempel abgerufen.

Lesbar

$dateTimeObject = new DateTime();
$dateTimeObject->setTimestamp($timestamp);
$beginOfDayString = $dateTimeObject->format('Y-m-d 00:00:00');
$beginOfDayObject = DateTime::createFromFormat('Y-m-d H:i:s', $beginOfDayString);
$beginOfDay = $beginOfDayObject->getTimestamp();

Wir können das Ende des Tages auf alternative Weise mit dieser längeren Version erhalten:

$endOfDayObject = clone $beginOfDayOject(); // Cloning because add() and sub() modify the object
$endOfDayObject->add(new DateInterval('P1D'))->sub(new DateInterval('PT1S'));
$endOfDay = $endOfDayOject->getTimestamp();

Zeitzone

Die Zeitzone kann auch eingestellt werden, indem dem Format ein Zeitstempel-Indikator hinzugefügt wird, z O und Angabe des Zeitstempels nach dem Erstellen des DateTime-Objekts:

$beginOfDay = DateTime::createFromFormat('Y-m-d H:i:s O', (new DateTime())->setTimezone(new DateTimeZone('America/Los_Angeles'))->setTimestamp($timestamp)->format('Y-m-d 00:00:00 O'))->getTimestamp();

Flexibilität von DateTime

Wir können auch andere Informationen wie Anfang/Ende des Monats oder Anfang/Ende der Stunde erhalten, indem wir das zweite angegebene Format ändern. Für Monat: 'Y-m-01 00:00:00' und 'Y-m-t 23:59:59'. Für Stunde: 'Y-m-d H:00:00' und 'Y-m-d H:59:59'

Durch die Verwendung verschiedener Formate in Kombination mit add()/sub()- und DateInterval-Objekten können wir den Anfang oder das Ende jeder Periode erhalten, obwohl einige Vorsicht geboten ist, um Schaltjahre korrekt zu behandeln.

Relevante Links

Aus den PHP-Dokumenten:

  • Was Sie erstellt haben, ist prägnant und lesbar. Leider scheitert es an Schaltsekunden. Manche Tage enden um 23:59:58, andere um 23:59:60. Dies führt insbesondere zu Problemen, wenn versucht wird, ein Datum für eine nicht vorhandene Datumszeit zu erstellen, z. B. 23:59:59 an einem Tag, der theoretisch eine Sekunde vorher enden könnte. Die akzeptierte Antwort, die die \DateTime::modify-Methode von PHP verwendet, würde dies vermeiden. Die in PHP eingebaute Bibliothek ist intelligent genug, um alle Kuriositäten zu berücksichtigen, die Datums- und Zeitangaben umgeben, einschließlich Schaltsekunden.

    – Elimin

    8. Juni 2017 um 9:33 Uhr


  • @Elimm, mir war nicht bewusst, dass einige Tage wegen des Schalttages eine Sekunde früher oder später endeten. Ich dachte, dieser Sprung fügte in Schaltjahren nur einen Tag hinzu und sonst nichts war betroffen. Können Sie ein Beispiel im Code dafür geben, wie dies fehlschlägt (oder können Sie einen Tag mit einer Sekunde mehr oder einer Sekunde weniger teilen)? Gibt es auch einen Artikel, den Sie teilen können, der mehr darüber sagt? Danke für den Hinweis modify. Das wusste ich vorher nicht.

    – Robert Hickmann

    8. Juni 2017 um 16:24 Uhr

  • Mit Sicherheit. Diese werden Sprung genannt Sekunden nicht springen Tage oder Jahre. Sie erklären, dass die Rotation der Erde keine konstante Geschwindigkeit ist. Ich glaube, der 30. Juni 2016 war unsere letzte Schaltsekunde. Das Wikipedia-Seite taucht in die groben Details ein.

    – Elimin

    13. Juni 2017 um 19:37 Uhr

Sie können eine Kombination aus verwenden date() und mktime():

list($y,$m,$d) = explode('-', date('Y-m-d', $ts));
$start = mktime(0,0,0,$m,$d,$y);
$end = mktime(0,0,0,$m,$d+1,$y);

mktime() ist intelligent genug, um Monate/Jahre zu umbrechen, wenn ein Tag außerhalb des angegebenen Monats angegeben wird (der 32. Januar wird der 1. Februar usw.)

Sie könnten die Zeit in die aktuellen Daten konvertieren und dann die strtotime-Funktion verwenden, um den Beginn des Tages zu finden, und einfach 24 Stunden dazu addieren, um das Ende des Tages zu finden.

Sie können auch den Restoperator (%) verwenden, um den nächsten Tag zu finden. Zum Beispiel:

$start_of_day = time() - 86400 + (time() % 86400);
$end_of_day = $start_of_day + 86400;

Benutzer-Avatar
KayakinKoder

Die akzeptierte Antwort bricht leider aufgrund eines PHP-Fehlers, der in ganz bestimmten Szenarien auftritt. Ich werde diese Szenarien besprechen, aber zuerst die Antwort mit DateTime. Der einzige Unterschied zwischen dieser und der akzeptierten Antwort tritt nach dem auf // IMPORTANT Linie:

$dtNow = new DateTime();
// Set a non-default timezone if needed
$dtNow->setTimezone(new DateTimeZone('America/Havana'));
$dtNow->setTimestamp($timestamp);

$beginOfDay = clone $dtNow;

// Go to midnight.  ->modify('midnight') does not do this for some reason
$beginOfDay->modify('today');

// now get the beginning of the next day
$endOfDay = clone $beginOfDay;
$endOfDay->modify('tomorrow');

// IMPORTANT
// get the timestamp
$ts = $endOfDay->getTimestamp();
// subtract one from that timestamp
$tsEndOfDay = $ts - 1;

// we now have the timestamp at the end of the day. we can now use that timestamp
// to set our end of day DateTime
$endOfDay->setTimestamp($tsEndOfDay);

Sie werden das also notieren, anstatt zu verwenden ->modify('1 second ago'); wir erhalten stattdessen den Zeitstempel und subtrahieren eins. Die akzeptierte Antwort mit modify sollte funktioniert, bricht aber wegen eines PHP-Bugs in ganz bestimmten Szenarien ab. Dieser Fehler tritt in Zeitzonen auf, die die Sommerzeit um Mitternacht ändern, an dem Tag des Jahres, an dem die Uhren “vorgestellt” werden. Hier ist ein Beispiel, mit dem Sie diesen Fehler überprüfen können.

Beispielcode für Fehler

// a time zone, Cuba, that changes their clocks forward exactly at midnight. on
// the day before they make that change. there are other time zones which do this
$timezone="America/Santiago";
$dateString = "2020-09-05";

echo 'the start of the day:<br>';
$dtStartOfDay = clone $dtToday;
$dtStartOfDay->modify('today');
echo $dtStartOfDay->format('Y-m-d H:i:s');
echo ', '.$dtStartOfDay->getTimestamp();

echo '<br><br>the start of the *next* day:<br>';
$dtEndOfDay = clone $dtToday;
$dtEndOfDay->modify('tomorrow');
echo $dtEndOfDay->format('Y-m-d H:i:s');
echo ', '.$dtEndOfDay->getTimestamp();

echo '<br><br>the end of the day, this is incorrect. notice that with ->modify("-1 second") the second does not decrement the timestamp by 1:<br>';
$dtEndOfDayMinusOne = clone $dtEndOfDay;
$dtEndOfDayMinusOne->modify('1 second ago');
echo $dtEndOfDayMinusOne->format('Y-m-d H:i:s');
echo ', '.$dtEndOfDayMinusOne->getTimestamp();

echo '<br><br>the end of the day, this is correct:<br>';
$dtx = clone $dtEndOfDay;
$tsx = $dtx->getTimestamp() - 1;
$dty = clone $dtEndOfDay;
$dty->setTimestamp($tsx);
echo $dty->format('Y-m-d H:i:s');
echo ', '.$tsx;

Fehlerbeispielcodeausgabe

the start of the day:
2020-03-26 00:00:00, 1585173600

the start of the *next* day:
2020-03-27 01:00:00, 1585260000

the end of the day, this is incorrect. notice that with ->modify("1 second ago") the
second does not decrement the timestamp by 1:
2020-03-27 01:59:59, 1585263599

the end of the day, this is correct:
2020-03-26 23:59:59, 1585259999

Benutzer-Avatar
Ganesh

Heute Zeitstempel des Startdatums. Einfach

$stamp = mktime(0, 0, 0);
echo date('m-d-Y H:i:s',$stamp);

Benutzer-Avatar
Kareem

$start_of_day = floor (time() / 86400) * 86400;
$end_of_day = ceil (time() / 86400) * 86400;

Wenn Sie beide Werte im selben Skript benötigen. Es ist schneller auf +/- 86400 Sekunden zu einer der Variablen, als sowohl den Boden als auch die Decke abzufeuern. Zum Beispiel:

$start_of_day = floor (time() / 86400) * 86400;
$end_of_day = $start_of_day + 86400;

1353170cookie-checkWie bekomme ich bei einem Unix-Zeitstempel den Beginn und das Ende dieses Tages?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy