2010-12-22 15 views
7

Entonces, uh, está bien. Esto podría llegar matemática, así que espero que trajo a su calculadora científica con usted;)PHP Encontrar la fecha más cercana a un período de línea de tiempo

Este es mi problema:

alt text

Dada una fecha inicial (fecha y hora), el período de período de tiempo (segundos) y hoy date (timestamp), necesito encontrar la fecha más cercana que coincida con el período * n más la fecha original/inicial.

Hasta ahora, tengo algunas cosas que trabaja muy bien, tales como la cantidad de "períodos" entre la fecha inicial y final (de hoy), lo que sería "2" en la demo anterior:

$initial=strtotime('2 April 1991'); 
$time=time(); 
$period=strtotime('+10 years',0); 

$periods=round(($time-$initial)/$period); 

lo siguiente que hice fue:

$range=$periods*$period; 

Y, por último:

echo date('d M Y',$initial+$range); 

Qué escribió '03 de abril de 2011' . ¿Cómo llegó a 3? (¿Sospecho que es un problema del año bisiesto?) ¿Conoces esa sensación cuando te falta algo pequeño? Voy a tener todo de mí en este momento ....

+0

A diferencia de ti, yo estoy probando su código y obtener '01 Abr 2011'! – ncuesta

+0

¿Qué? Quizás deberías mirar tus falsas acusaciones. Tal como está, el 1 de abril de 1991 también está mal ... – Christian

+0

¿Se establecen los períodos? ¿Siempre serán años o también dinámicos? Si solo trabaja con años, puede trabajar en el segmento del año y estar seguro en su hogar. Si necesita trabajar con días, obtendrá este número de año bisiesto. – Knubo

Respuesta

1

Trate de hacer esto:

$current = $initial = strtotime('2 April 1991'); 
$time_span = '+10 years'; 

while ($current < time()) 
{ 
    $current = strtotime($time_span, $current); 
} 

echo date('d M Y', $current); 
+0

Recibí '2 de abril de 1991'. Estaba haciendo un enfoque más matemático que a través de bucles (que tienden a ser costosos en rangos más altos). Se supone que debo hacerlo funcionar en cheques mensuales y semanales también, lo que lo hace bastante lento. – Christian

+0

Bien, no importa entonces :-) – ncuesta

2

Ok por lo que si he entendido lo que están pidiendo, desea saber la próxima fecha en la que se produce en un período de tiempo determinado (en su caso, cada 10 años a partir del 2 de abril de 1991, cuando será la próxima fecha: 2 de abril de 2011).

Por lo tanto, debería echar un vistazo más profundo a la clase DateTime en PHP que es muchísimo mejor usar para las fechas porque es más preciso. Se mezcla con DateInterval que coinciden exactamente lo que necesita:

<?php 
$interval = new DateInterval('P10Y'); // 10 years 
$initial = new DateTime('1991-04-02'); 
$now = new DateTime('now'); 

while ($now->getTimestamp() > $initial->getTimestamp()) { 
    $initial = $initial->add($interval); 
} 

echo $initial->format('d M Y'); // should return April 2, 2011 ! 
?> 
+0

Mismo problema con la pregunta del otro tipo, implementación matemática vs bucle. – Christian

+1

Funciona muy bien para mí. Solo una cosa: en la última línea, debe ser 'echo $ initial-> format ('d M Y');'. – ncuesta

+0

@Christian Sciberras: puedes intentar hacer tu sistema matemático en el objeto Date: 'round (($ now- $ initial)/$ interval) * $ interval'. No puedo probarlo ahora mismo, así que no puedo confirmar que funcionará. O bien, tendrá que agregar '-> getTimestamp()' en cada vars para su forma matemática. (Probar). Dime si funciona, voy a editar mi respuesta. –

1

Lo que pasó:

+10 yearsdel Año 0 (1970) incluirá 3 años bisiestos '72, '76 y '80, pero desde '91 hasta '11 solo hay cinco años bisiestos '92, '96, '00, '04 y '08. Agregaste ese período dos veces, así que debido a que no hubo 6 años bisiestos, tienes un día más.

Lo que hay que hacer:

anuncio el periodo con strtotime un paso a la vez.

$period = "+10 years"; 
$newTime = $startingTime; 
while(<condition>){ 
    $newTime = strtotime($period, $newTime); 
} 
+0

AH! Lo entiendo. Debería haber sido: strtotime ('+ 1 years', 0) * 10 – Christian

+0

@Christian Sciberras ¡NO! :) Haz un rato y agrega usando 'strtotime'. Publiqué un código de maqueta. Si haces 'strtotime ('+ 1 years', 0) * 3', obtendrás 5 días menos de lo que necesitas. (28 de marzo, probablemente). –

+0

Ese 'while' es exactamente lo que escribí, pero Christian está buscando un enfoque matemático sobre este problema. – ncuesta

0

Como una solución a cx42net's answer:

<?php 

$initial = new DateTime('2 April 1991'); 
$now = new DateTime('now'); 
$interval = new DateInterval('P10Y'); 

$curDate = $initial; 

while (true) { 
    $curDate = $curDate->add($interval); 

    $curDiff = $curDate->diff($now)->days; 

    if (isset($lastDiff) && ($curDiff > $lastDiff)) { 
     echo $lastDate->format('d M Y'); 
     break; 
    } else { 
     $lastDate = clone $curDate; 
     $lastDiff = $curDiff; 
    } 
} 
Cuestiones relacionadas