Tengo una marca de tiempo de Unix como esta:
$timestamp=1330581600
¿Cómo obtengo el comienzo del día y el final del día para esa marca de tiempo?
e.g.
$beginOfDay = Start of Timestamp's Day
$endOfDay = End of Timestamp's Day
Probé esto:
$endOfDay = $timestamp + (60 * 60 * 23);
Pero no creo que funcione porque la marca de tiempo en sí no es el comienzo exacto del día.
Respuestas:
strtotime se puede utilizar para cortar rápidamente las horas / minutos / segundos
$beginOfDay = strtotime("today", $timestamp); $endOfDay = strtotime("tomorrow", $beginOfDay) - 1;
También se puede usar DateTime, aunque requiere algunos pasos adicionales para obtener una marca de tiempo larga
$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'), ) );
Con la adición de tiempo extendido en PHP7, existe la posibilidad de perder un segundo si se usa la
$now <= $end
verificación con esto. El uso de la$now < $nextStart
verificación evitaría esa brecha, además de las rarezas de restar segundos y ahorro de luz en el manejo del tiempo de PHP.fuente
strtotime('today', $timestamp)
$endOfDay->modify('tomorrow -1 second');
también funciona.Sólo 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();
Primero se crea un objeto DateTime y la marca de tiempo se establece en la marca de tiempo deseada. Luego, el objeto se formatea como una cadena que establece la hora / minuto / segundo al principio o al final del día. Por último, se crea un nuevo objeto DateTime a partir de esta cadena y se recupera la marca de tiempo.
Legible
$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();
Podemos obtener el final del día de una manera alternativa usando esta versión más larga:
$endOfDayObject = clone $beginOfDayOject(); // Cloning because add() and sub() modify the object $endOfDayObject->add(new DateInterval('P1D'))->sub(new DateInterval('PT1S')); $endOfDay = $endOfDayOject->getTimestamp();
Zona horaria
La zona horaria también se puede establecer agregando un indicador de marca de tiempo al formato
O
y especificando la marca de tiempo después de crear el objeto 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();
Flexibilidad de DateTime
También podemos obtener otra información como el comienzo / final del mes o el comienzo / final de la hora cambiando el segundo formato especificado. Por mes:
'Y-m-01 00:00:00'
y'Y-m-t 23:59:59'
. Por hora:'Y-m-d H:00:00'
y'Y-m-d H:59:59'
Utilizando varios formatos en combinación con add () / sub () y objetos DateInterval, podemos obtener el comienzo o el final de cualquier período, aunque habrá que tener cuidado para manejar correctamente los años bisiestos.
Enlaces relevantes
De los documentos de PHP:
fuente
modify
. No sabía de eso antes.Puede utilizar una combinación de
date()
ymktime()
: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()
es lo suficientemente inteligente como para envolver meses / años cuando se le da un día fuera del mes especificado (el 32 de enero será el 1 de febrero, etc.)fuente
Puede convertir la hora a los datos actuales y luego usar la función strtotime para encontrar el comienzo del día y simplemente agregar 24 horas a eso para encontrar el final del día.
También puede usar el operador restante (%) para encontrar el día más cercano. Por ejemplo:
$start_of_day = time() - 86400 + (time() % 86400); $end_of_day = $start_of_day + 86400;
fuente
time()
dos veces, pueden ser segundos diferentes.Desafortunadamente, la respuesta aceptada se rompe debido a un error de php que ocurre en escenarios muy específicos. Discutiré esos escenarios, pero primero la respuesta usando DateTime. La única diferencia entre esto y la respuesta aceptada ocurre después de la
// IMPORTANT
línea:$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);
Por lo tanto, notará que en lugar de usar
->modify('1 second ago');
, obtenemos la marca de tiempo y restamos una. La respuesta aceptada usandomodify
debería funcionar, pero se rompe debido a un error de php en escenarios muy específicos. Este error ocurre en zonas horarias que cambian el horario de verano a la medianoche, el día del año en que los relojes se adelantan. Aquí hay un ejemplo que puede usar para verificar ese error.código de error de ejemplo
// 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;
salida de código de ejemplo de error
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
fuente
Hoy Fecha de inicio de marca de tiempo. Simple
$stamp = mktime(0, 0, 0); echo date('m-d-Y H:i:s',$stamp);
fuente
Para cualquiera que tenga esta pregunta en el futuro:
Cualquier código de día
<?php $date = "2015-04-12 09:20:00"; $midnight = strtotime("midnight", strtotime($date)); $now = strtotime($date); $diff = $now - $midnight; echo $diff; ?>
Código del día actual
<?php $midnight = strtotime("midnight"); $now = date('U'); $diff = $now - $midnight; echo $diff; ?>
fuente
$start_of_day = floor (time() / 86400) * 86400; $end_of_day = ceil (time() / 86400) * 86400;
Si necesita ambos valores en el mismo script. Es más rápido +/- 86400 segundos para una de las variables que disparar tanto en el piso como en el techo. Por ejemplo:
$start_of_day = floor (time() / 86400) * 86400; $end_of_day = $start_of_day + 86400;
fuente