2009-06-05 10 views
11

Tengo un "evento" que debe programarse el mismo día de cada mes.El próximo mes, el mismo día en PHP

Supongamos que establece la fecha de inicio el 1 de mayo, debería recibir los próximos eventos el 1 de junio, 1 de julio, etc. El problema viene con una fecha de inicio el día 31 (los siguientes podrían ser 30 o 28 dependiendo en el mes).

Considerando que hay meses con diferentes números de días (28, 30, 31) dependiendo del mes en sí y del año ... ¿cuál sería una manera fácil de configurar esto?

Considere lo siguiente (y errónea) Función NextMonth:

$events = array() 

function nextmonth($date) { 
    return $date+(60*60*24*30); 
} 
$curr = $start; 
while($curr < $end) { 
    $events[ = $curr; 
    $curr = nextmonth($curr); 
} 

Editado para agregar: El problema para mí es, simplemente lo suficiente, la forma de resolver lo que el número de días de un mes determinado es y así conseguir la próxima fecha correspondiente.

+0

por favor formatee el código mejor, gracias! – JasonV

+0

¡Estoy luchando! – Guillermo

+1

No soy un desarrollador de PHP, solo agrego un poco de contexto, Outlook usa de manera predeterminada el último día del mes si la fecha especificada no es válida para ese mes. ¿Necesitas tener en cuenta los fines de semana y días festivos? – Venr

Respuesta

1

Dado que los meses son muy variados, ¿no sería la mejor manera de establecer el próximo mes algo así como: este día, el próximo mes, excepto si este día no existe el próximo mes.

Ejemplo:

June 5, 2009, next month would be July 5, 2009 
August 31, 2009, next month would be September 30, 2009 

o, simplemente, strtotime("+1 month")

+0

sí, ahí va ... pero el problema para mí, simplemente suficiente, es resolver cuál es el número de días de un mes determinado. – Guillermo

+0

@ Guillermo, no tiene que preocuparse por eso. El strtotime ("+ 1 mes"), literalmente eso, se encarga de eso. –

+0

esto es lo que pensé pero: echo date ("Y-m-d", strtotime ("2009-01-30 +1 mes")); se resuelve en 2009.03.02 – Guillermo

2

Recomiendo leer el siguiente comentario en php.net. strtotime() (php.net)

Editar: La siguiente respuesta ofrece el "resumen" del enlace que publiqué para aquellos que no lograron descifrar el contenido que allí se muestra.

+0

Parece interesante ... si publicara esto aquí, alguien más tendrá la oportunidad de obtener su respuesta aquí mirando aquí ... – Guillermo

7

Actualización:

Esto le dará el número de días en un mes determinado:

echo date('t', $timestamp); 

Ver: date()

vieja respuesta:

estoy no estoy seguro sobre el algoritmo que está pensando, pero creo que esto va a ayudar p que:

echo date('d-M-y', strtotime('next month')); 
+0

+1 Eso es lo que haría en esta situación. – karim79

+2

strtotime ("2009-01-30 +1 mes"); resuelve como 2009.03.02 no es útil en mi caso – Guillermo

+0

@ Guillermo, si desea mapear del 31 de enero al 28 de febrero, ¿qué día corresponde al 28 de enero? ¿Todavía el 28 de febrero? –

4

Esto devolverá marca de tiempo adecuado para los próximos meses $ X: mktime(0,0,0,date("m")+$X,date('d'),date("Y"));

+0

+1 Esto parece más natural-- divide la fecha y agrega cosas a los componentes para obtener lo que deseas. – Kekoa

+0

+1, probé esto y funciona bien cuando el mes actual más x es igual a un número mayor que 12. Incrementa el año correctamente.Además, si el número del día no existe en el mes, pasará al mes siguiente con los días adicionales. – gradbot

+1

acaba de probar su caso de prueba "2009-01-30" +1 mes y esto también devuelve 2009-3-2 – gradbot

0

¿Qué hay de esta función:

function getNextMonthN($date, $n = 1) { 
     $newDate = strtotime('+' . $n . ' months', $date); 
     if (date('j', $date) !== (date('j', $newDate))) { 
     $newDate = mktime(0, 0, 0, date('n', $newDate), 0, date('Y', $newDate)); 
     } 
     return $newDate; 
    } 

Hay otra solución en el sitio de manual de php.net bajo la entrada strtotime en el comments.

1

intentado esto como una broma, y ​​que en realidad funciona

strtotime('last day next month') 

Así:

$today_next_month = strtotime('this day next month'); 
$last_day_next_month = strtotime('last day next month'); 
if (date('d', $today_next_month) < date('d', $last_day_next_month)){ 
    $date = date('m-d-Y', $last_day_next_month); 
} else { 
    $date = date('m-d-Y', $today_next_month); 
} 
echo "And the winner is : $date<br/>"; 
+0

Debo decir que no esperaba que esto funcionara. Pero, lo hizo! –

0

Nadie ha mencionado esta alternativa, aunque el resultado es el mismo que los demás, y probablemente no lo el PO está buscando:

$today = new DateTime(); 
$today->modify("+1 month"); 
echo $today->format("d.m.Y"); 

por qué no, entonces apenas el mes tienda y día por separado y el mes de la subasta por el e, y luego use la función checkdate de PHP para validar la fecha, disminuyendo el día en uno hasta que la fecha sea válida?

0

Sé que esta es una publicación anterior, pero se pensó que daba un enfoque diferente.

Así que en lugar de tratar de averiguar los días en un mes (que es algo complicado), se puede averiguar el próximo mes con el mes actual con facilidad, por ejemplo:

date("m", strtotime($current."+1 month")); 

a continuación, obtener el día de el mes actual usando date("d"), y concat con el mes siguiente del código anterior.

3

Pruebe esto. reday es el día para rellenar (int - día del mes). Si es menor que hoy, dará reday de este mes pero no mucho más que no. de este mes días. Si es más de hoy, dé el reday del próximo mes la misma condición. Utilizo esto para calcular "Siguiente recarga" del punto de recarga mensual.retorno es dd/mm/yyyy

function nextrefill($reday) { 
    if (date("j") < $reday) { 
     $numd = date("t"); 
     if ($reday > $numd) { 
      return str_pad($numd, 2, "0", STR_PAD_LEFT).date("/m/Y"); 
     } else { 
      return str_pad($reday, 2, "0", STR_PAD_LEFT).date("/m/Y"); 
     } 
    } else { 
     $nextm = date('m', strtotime('first day of next month')); 
     $nextmy = date('Y', strtotime('first day of next month')); 
     $numd = cal_days_in_month(CAL_GREGORIAN, $nextm, $nextmy); 
     if ($reday > $numd) { 
      return str_pad($numd, 2, "0", STR_PAD_LEFT)."/".$nextm."/".$nextmy; 
     } else { 
      return str_pad($reday, 2, "0", STR_PAD_LEFT)."/".$nextm."/".$nextmy; 
     } 
    } 
} 

para más directo al punto (Editar)

function nextmonthday($day) { 
     $next_month = date('m', strtotime('first day of next month')); 
     $year_of_next_month = date('Y', strtotime('first day of next month')); 
     $no_of_day_in_next_month = cal_days_in_month(CAL_GREGORIAN, $nextm, $nextmy); 
     if ($day > $no_of_day_in_next_month){ 
      return str_pad($no_of_day_in_next_month, 2, "0", STR_PAD_LEFT)."/".$next_month."/".$year_of_next_month; 
     } else { 
      return str_pad($day, 2, "0", STR_PAD_LEFT)."/".$next_month."/".$year_of_next_month; 
     } 
} 
+0

No estoy seguro de entender la explicación –

1

simple

public function adicionarMesMantendoDia($date, $months, $format = "Y-m-d"){ 
     $date = \DateTime::createFromFormat($format, $date); 

     for($i=0;$i < $months; $i++){ 
      $date->modify('+ ' . date("t", $date->getTimestamp()) . ' day'); 
     } 
     return $date; 
} 
0

También tuve el mismo problema, pero cuando he intentado por encima de soluciones que no podía trabajar perfectamente para yo, traté de mi lado y se me ocurrió una nueva solución que es:

$startDate = date("Y-m-d"); 
$month = date("m",strtotime($startDate)); 
$nextmonth = date("m",strtotime("$startDate +1 month")); 
if((($nextmonth-$month) > 1) || ($month == 12 && $nextmonth != 1)) 
{ 
    $nextDate = date('t.m.Y',strtotime("$startDate +1 week")); 
}else 
{ 
    $nextDate = date("Y-m-d",strtotime("$startDate +1 month")); 
} 
echo $nextSameDate = date("Y",$nextDate).'-'.date("m",$nextDate).'-'.date("d",$startDate); 
0

de fecha y hora POO Estilo

<?php 
//Start Date -> 18-09-2015 
$expiry = new DateTime(); 
for($i=1;$i<5;$i++){ 
    $expiry->modify('+1 Month'); 
    echo $expiry->format('d-m-Y'); 
    echo '<br>'; 
} 
?> 

//18-10-2015 
//18-11-2015 
//18-12-2015 
//18-01-2016 
0

Esto es lo que yo uso

Esta es una marca de tiempo de fecha mes en curso

$month_timestamp = strtotime(date('Y-m', $create_timestamp)); 

actual días

$current_day = date('d'); 

Y este es el mes que viene mismo día en formato "Ymd"

$next_month_first = date('Y-m-' . $current_day, strtotime('next month', $month_timestamp)); 
0

Ninguna de las anteriores se hizo cargo de los días no existentes (30 de febrero o el 31 de abril por ejemplo), por lo que aquí está mi función:

<?php 
function getSameDayNextMonth($time, $numberMonthsToAdd = 1) 
{ 
    list($year, $month, $day) = explode('-', date("Y-m-d", $time)); 

    // replace the day by one temporarily (just to make sure it exists for any month 
    $numberOfYearsToAdd = floor($numberMonthsToAdd/12); 
    $year += $numberOfYearsToAdd; 
    $month = ($month + $numberMonthsToAdd) % 12; 
    if (0 === $month) { 
     $month = 12; 
    } 
    $monthFormatted = sprintf('%02s', $month); 
    $nbDaysInThisMonth = date("t", strtotime("$year-$monthFormatted-01")); 

    if ((int)$day > $nbDaysInThisMonth) { 
     $day = $nbDaysInThisMonth; 
    } 
    $day = sprintf('%02s', $day); 
    return strtotime("$year-$monthFormatted-$day"); 
} 


$time = strtotime("2017-10-31"); 
for ($i = 0; $i <= 15; $i++) { 
    $_time = getSameDayNextMonth($time, $i); 
    echo date("Y-m-d", $_time) . '<br>'; 
} 

/** 
* 2017-10-31 
* 2017-11-30 
* 2017-12-31 
* 2017-01-31 
* 2017-02-28 
* 2017-03-31 
* 2017-04-30 
* 2017-05-31 
* 2017-06-30 
* 2017-07-31 
* 2017-08-31 
* 2017-09-30 
* 2018-10-31 
* 2018-11-30 
* 2018-12-31 
* 2018-01-31 
*/ 
Cuestiones relacionadas