У меня есть такая метка времени Unix:
$timestamp=1330581600
Как мне узнать начало и конец дня для этой отметки времени?
e.g.
$beginOfDay = Start of Timestamp's Day
$endOfDay = End of Timestamp's Day
Я пробовал это:
$endOfDay = $timestamp + (60 * 60 * 23);
Но я не думаю, что это сработает, потому что метка времени не является точным началом дня.
Ответы:
strtotime можно использовать для быстрого сокращения часов / минут / секунд
$beginOfDay = strtotime("today", $timestamp); $endOfDay = strtotime("tomorrow", $beginOfDay) - 1;
DateTime также можно использовать, хотя для получения длинной временной метки требуется несколько дополнительных шагов.
$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'), ) );
С добавлением расширенного времени в PHP7 есть вероятность пропустить секунду при использовании
$now <= $end
проверки с этим. Использование$now < $nextStart
проверки позволило бы избежать этого пробела, в дополнение к странностям, связанным с вычитанием секунд и переходом на летнее время при обработке времени PHP.источник
strtotime('today', $timestamp)
$endOfDay->modify('tomorrow -1 second');
тоже работает.Просто 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();
Сначала создается объект DateTime, и в качестве метки времени устанавливается желаемая метка времени. Затем объект форматируется как строка, устанавливающая час / минуту / секунду для начала или конца дня. Наконец, из этой строки создается новый объект DateTime и извлекается метка времени.
Удобочитаемый
$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();
Мы можем получить конец дня альтернативным способом, используя эту более длинную версию:
$endOfDayObject = clone $beginOfDayOject(); // Cloning because add() and sub() modify the object $endOfDayObject->add(new DateInterval('P1D'))->sub(new DateInterval('PT1S')); $endOfDay = $endOfDayOject->getTimestamp();
Часовой пояс
Часовой пояс также можно установить, добавив индикатор отметки времени к формату, например,
O
и указав отметку времени после создания объекта 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();
Гибкость DateTime
Мы также можем получить другую информацию, такую как начало / конец месяца или начало / конец часа, изменив второй указанный формат. За месяц:
'Y-m-01 00:00:00'
а'Y-m-t 23:59:59'
. В течение часа:'Y-m-d H:00:00'
и'Y-m-d H:59:59'
Используя различные форматы в сочетании с объектами add () / sub () и DateInterval, мы можем получить начало или конец любого периода, хотя для правильной обработки високосных лет потребуется определенная осторожность.
Соответствующие ссылки
Из документов PHP:
источник
modify
. Я не знал об этом раньше.Вы можете использовать комбинацию
date()
и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()
достаточно умен, чтобы переносить месяцы / годы, когда дается день за пределами указанного месяца (32 января будет 1 февраля и т. д.)источник
Вы можете преобразовать время в текущие данные, а затем использовать функцию strtotime, чтобы найти начало дня, и просто добавить к нему 24 часа, чтобы найти конец дня.
Вы также можете использовать оператор остатка (%), чтобы найти ближайший день. Например:
$start_of_day = time() - 86400 + (time() % 86400); $end_of_day = $start_of_day + 86400;
источник
time()
дважды, они могут быть разными секундами.Принятый ответ, к сожалению, не работает из-за ошибки php, которая возникает в очень конкретных сценариях. Я буду обсуждать эти сценарии, но сначала отвечу с помощью DateTime. Единственная разница между этим и принятым ответом появляется после
// IMPORTANT
строки:$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);
Итак, вы заметите, что вместо использования
->modify('1 second ago');
мы получаем метку времени и вычитаем ее. Принятый ответ с использованиемmodify
должен работать, но ломается из-за ошибки php в очень конкретных сценариях. Эта ошибка возникает в часовых поясах, которые изменяют летнее время в полночь, в день года, когда часы переводятся «вперед». Вот пример, который вы можете использовать для проверки этой ошибки.пример кода ошибки
// 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;
вывод кода примера ошибки
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
источник
Сегодня Отметка времени даты начала. просто
$stamp = mktime(0, 0, 0); echo date('m-d-Y H:i:s',$stamp);
источник
Для всех, у кого в будущем возникнет этот вопрос:
Код любого дня
<?php $date = "2015-04-12 09:20:00"; $midnight = strtotime("midnight", strtotime($date)); $now = strtotime($date); $diff = $now - $midnight; echo $diff; ?>
Код текущего дня
<?php $midnight = strtotime("midnight"); $now = date('U'); $diff = $now - $midnight; echo $diff; ?>
источник
$start_of_day = floor (time() / 86400) * 86400; $end_of_day = ceil (time() / 86400) * 86400;
Если вам нужны оба значения в одном скрипте. Это быстрее +/- 86400 секунд для одной из переменных, чем запускать и floor, и ceil. Например:
$start_of_day = floor (time() / 86400) * 86400; $end_of_day = $start_of_day + 86400;
источник