2012-04-17 11 views
52

Tengo una marca de tiempo Unix como esto:Dada una marca de tiempo de Unix, ¿cómo comenzar y finalizar ese día?

$timestamp=1330581600 

¿Cómo consigo el comienzo del día y al final del día para esa marca de tiempo?

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

yo probamos este:

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

Pero no creo que va a trabajar porque la fecha en sí no es el comienzo exacto del día.

+0

Si es GMT, probablemente: $ boundary = floor/ceil ($ timestamp/(60 * 60 * 24)) * (60 * 60 * 24); – hakre

+0

Si su salida esperada es una marca de tiempo como un número entero, hay un simple trazador: $ beginOfDay = mktime (0, 0, 0, date ('n'), date ('j') - 1); $ endOfDay = mktime (0, 0, 0, fecha ('n'), fecha ('j')); – jarederaj

Respuesta

117

strtotime se puede utilizar para cortar rápidamente de las horas/minutos/segundos

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

DateTime también se puede utilizar, aunque requiere algunos pasos adicionales para llegar de un largo marca de tiempo

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

$beginOfDay = clone $dtNow; 

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

$endOfDay = clone $beginOfDay; 
$endOfDay->modify('tomorrow'); 
// adjust from the next day to the end of the day, per original question 
$endOfDay->modify('1 second ago'); 

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'), 
    ) 
); 
+1

¡Funcionó de maravilla! – Talon

+2

¿Por qué menos 1 segundo al final? –

+1

He leído la pregunta original como obtener el último segundo del día, en lugar del primer segundo del día siguiente. 'mañana' dará el primer segundo del día, entonces '-1' para obtener el segundo antes del primer segundo del día. – rrehbein

3

Puede convertir el tiempo a los datos actuales y luego usar la función de tiempo de recorrido para encontrar el comienzo del día y simplemente agregar 24 horas para encontrar el final del día.

También podría usar el operador de resto (%) para encontrar el día más cercano. Por ejemplo:

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

No todos los días duran 86400 segundos, por lo que esto no funcionará como espera – Cal

+0

@Cal oh sí, no pensé en eso – James

+0

gracias thanx tanto .. –

5

Se puede utilizar una combinación de date() y 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() es lo suficientemente inteligente como para envolver meses/años cuando se les da un día fuera del mes especificado (Enero 32 será febrero primero, etc)

0

Para cualquier persona que tiene esta cuestión en el futuro:

Cualquier código días

<?php 
$date = "2015-04-12 09:20:00"; 

$midnight = strtotime("midnight", strtotime($date)); 
$now = strtotime($date); 

$diff = $now - $midnight; 
echo $diff; 
?> 

código de día actual

<?php 
$midnight = strtotime("midnight"); 
$now = date('U'); 

$diff = $now - $midnight; 
echo $diff; 
?> 
5

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(); 

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 comienzo 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 conseguir el final del día, de manera alternativa el uso de 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 se puede configurar así añadiendo un indicador de marca de tiempo para el formato como 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 puede obtener otra información, como el inicio/final del mes o el inicio/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 horas: 'Y-m-d H:00:00' y 'Y-m-d H:59:59'

Utilizando diversos formatos en combinación con add()/sub() y objetos DateInterval, podemos conseguir principio o al final de cualquier período, aunque tendrá que ser tomada para manejar los años bisiestos algún tipo de atención correctamente.

Enlaces relevantes

De la documentación de PHP:

+0

Lo que ha creado es breve y legible. Lamentablemente, fallará en segundos intercalares. Algunos días terminan a las 23:59:58, mientras que otros terminan a las 23:59:60. En particular, esto causará problemas si intenta crear una fecha para un datetime no inexistente, como 23:59:59 en un día que teóricamente podría terminar un segundo antes de eso. La respuesta aceptada, que utiliza el método PHP \ DateTime :: modify, evitaría esto. La lib de PHP integrada es lo suficientemente inteligente como para tener en cuenta todas las rarezas que rodean las fechas y horas, incluidos los segundos intercalares. – Elimn

+0

@Elimm, no sabía que algunos días terminaban un segundo antes o después debido al día bisiesto. Pensé que ese salto solo agregaba un día en los años bisiestos y que nada más se veía afectado. ¿Puedes dar algún ejemplo en el código de cómo falla esto (o puedes compartir un día que tiene uno o un segundo menos)? Además, ¿hay algún artículo que puedas compartir que cuente más sobre esto? Gracias por señalar 'modificar'. No sabía sobre eso antes. –

+0

Seguro. Estos se denominan leap _seconds_ no leap _days_ o _years_. Explican que la rotación de la tierra no es una velocidad constante. Creo que el 30 de junio de 2016 fue nuestro último segundo. La [página de Wikipedia] (https://en.wikipedia.org/wiki/Leap_second) se sumerge en los detalles arenosos. – Elimn

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

Si necesita ambos valores en la misma secuencia de comandos. Es más rápido alcanzar +/- 86400 segundos para una de las variables que disparar tanto piso como techo. Por ejemplo:

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

Hoy Fecha de inicio marca de tiempo. Simple

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