Mam taki znacznik czasu w Uniksie:
$timestamp=1330581600
Jak uzyskać początek i koniec dnia dla tego znacznika czasu?
e.g.
$beginOfDay = Start of Timestamp's Day
$endOfDay = End of Timestamp's Day
Próbowałem tego:
$endOfDay = $timestamp + (60 * 60 * 23);
Ale nie sądzę, żeby to zadziałało, ponieważ sam znacznik czasu nie jest dokładnym początkiem dnia.
Odpowiedzi:
strtotime może służyć do szybkiego odcinania godziny / minut / sekund
$beginOfDay = strtotime("today", $timestamp); $endOfDay = strtotime("tomorrow", $beginOfDay) - 1;
Można również użyć DateTime, ale wymaga to kilku dodatkowych kroków, aby uzyskać z długiego znacznika czasu
$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'), ) );
Z dodaniem wydłużonego czasu w PHP7, istnieje możliwość pominięcia sekundy, jeśli używasz
$now <= $end
sprawdzania z tym. Użycie$now < $nextStart
sprawdzania pozwoliłoby uniknąć tej luki, oprócz dziwactw związanych z odejmowaniem sekund i oszczędzaniem światła dziennego w obsłudze czasu PHP.źródło
strtotime('today', $timestamp)
$endOfDay->modify('tomorrow -1 second');
też działa.Just 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();
Najpierw tworzony jest obiekt DateTime, a sygnatura czasowa jest ustawiana na żądany znacznik czasu. Następnie obiekt jest formatowany jako ciąg znaków określający godzinę / minutę / sekundę na początek lub koniec dnia. Na koniec tworzony jest nowy obiekt DateTime z tego ciągu i pobierany jest znacznik czasu.
Czytelny
$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();
Koniec dnia możemy uzyskać w alternatywny sposób korzystając z tej dłuższej wersji:
$endOfDayObject = clone $beginOfDayOject(); // Cloning because add() and sub() modify the object $endOfDayObject->add(new DateInterval('P1D'))->sub(new DateInterval('PT1S')); $endOfDay = $endOfDayOject->getTimestamp();
Strefa czasowa
Strefę czasową można również ustawić, dodając wskaźnik czasu do formatu, na przykład
O
i określając sygnaturę czasową po utworzeniu obiektu DateTime:$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();
Elastyczność DateTime
Możemy również uzyskać inne informacje, takie jak początek / koniec miesiąca lub początek / koniec godziny, zmieniając drugi określony format. Przez miesiąc:
'Y-m-01 00:00:00'
i'Y-m-t 23:59:59'
. Na godzinę:'Y-m-d H:00:00'
i'Y-m-d H:59:59'
Używając różnych formatów w połączeniu z obiektami add () / sub () i DateInterval, możemy uzyskać początek lub koniec dowolnego okresu, chociaż należy zachować ostrożność, aby poprawnie obsłużyć lata przestępne.
Odpowiednie linki
Z dokumentacji PHP:
źródło
modify
. Nie wiedziałem o tym wcześniej.Możesz użyć kombinacji
date()
imktime()
: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()
jest wystarczająco sprytny, aby zawijać miesiące / lata, gdy podany jest dzień poza określonym miesiącem (32 stycznia będzie 1 lutego itp.)źródło
Możesz przekonwertować czas na aktualne dane, a następnie użyć funkcji strtotime, aby znaleźć początek dnia i po prostu dodać 24 godziny do tego, aby znaleźć koniec dnia.
Możesz również użyć operatora reszty (%), aby znaleźć najbliższy dzień. Na przykład:
$start_of_day = time() - 86400 + (time() % 86400); $end_of_day = $start_of_day + 86400;
źródło
time()
dwa razy, mogą to być różne sekundy.Zaakceptowana odpowiedź niestety psuje się z powodu błędu php, który występuje w bardzo specyficznych sytuacjach. Omówię te scenariusze, ale najpierw odpowiedź przy użyciu DateTime. Jedyna różnica między tą a zaakceptowaną odpowiedzią występuje po
// IMPORTANT
linii:$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);
Zauważysz więc, że zamiast używać
->modify('1 second ago');
, otrzymujemy znacznik czasu i odejmujemy jeden. Zaakceptowana odpowiedź przy użyciumodify
powinna działać, ale psuje się z powodu błędu php w bardzo specyficznych sytuacjach. Ten błąd występuje w strefach czasowych, które zmieniają czas letni o północy, w dniu roku, w którym zegary są przesuwane „do przodu”. Oto przykład, którego możesz użyć do zweryfikowania tego błędu.przykładowy kod błędu
// 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;
przykładowy kod błędu
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
źródło
Dzisiaj Znacznik czasu daty rozpoczęcia. Prosty
$stamp = mktime(0, 0, 0); echo date('m-d-Y H:i:s',$stamp);
źródło
Dla każdego, kto ma to pytanie w przyszłości:
Kod na dowolny dzień
<?php $date = "2015-04-12 09:20:00"; $midnight = strtotime("midnight", strtotime($date)); $now = strtotime($date); $diff = $now - $midnight; echo $diff; ?>
Kod bieżącego dnia
<?php $midnight = strtotime("midnight"); $now = date('U'); $diff = $now - $midnight; echo $diff; ?>
źródło
$start_of_day = floor (time() / 86400) * 86400; $end_of_day = ceil (time() / 86400) * 86400;
Jeśli potrzebujesz obu wartości w tym samym skrypcie. Jest szybszy do +/- 86400 sekund dla jednej ze zmiennych niż wystrzelenie zarówno podłogi, jak i sufitu. Na przykład:
$start_of_day = floor (time() / 86400) * 86400; $end_of_day = $start_of_day + 86400;
źródło