2009-06-05 17 views
11

Ho un "evento" che deve essere pianificato lo stesso giorno di ogni mese.Il mese prossimo, lo stesso giorno in PHP

Supponiamo che tu abbia impostato la data di inizio il 1 ° maggio per ottenere gli eventi successivi il 1 ° giugno, 1 ° luglio ecc. Il problema si presenta con una data di inizio il 31 (i prossimi potrebbero essere 30 o 28 in base nel mese).

Considerando che ci sono mesi con diversi numeri di giorni (28, 30, 31) a seconda del mese stesso e dell'anno ... quale sarebbe un modo semplice per configurarlo?

Si consideri il seguente (e imperfetta) Funzione nextmonth:

$events = array() 

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

A cura di aggiungere: Il problema per me è, abbastanza semplicemente, come risolvere quello che il numero di giorni di un determinato mese è e ottenere in tal modo la prossima data corrispondente.

+0

per favore formattare meglio il codice, grazie! – JasonV

+0

sto lottando !! – Guillermo

+1

Non sono uno sviluppatore PHP, quindi aggiungo solo un contesto, Outlook usa l'ultimo giorno del mese se la data specificata non è una data valida per quel mese. Hai bisogno di prendere in considerazione i fine settimana e le vacanze? – Venr

risposta

1

Poiché i mesi sono di dimensioni così diverse, il modo migliore per impostare il mese successivo non sarebbe il seguente: questo giorno, il mese prossimo, eccetto se questo giorno non esiste il mese prossimo.

Esempio:

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

o semplicemente, strtotime("+1 month")

+0

sì, eccola .. ma il problema per me, semplicemente, è quello di risolvere il numero di giorni di un determinato mese. – Guillermo

+0

@ Guillermo, non devi preoccuparti di questo. Lo strtotime ("+ 1 mese"), letteralmente quello, si prende cura di esso. –

+0

questo è quello che penso però: data di eco ("Y-m-d", strtotime ("30-01-2009 +1 mese")); risolve come 2009.03.02 – Guillermo

2

Mi raccomando di leggere il seguente commento su php.net. strtotime() (php.net)

Modifica: la risposta successiva fornisce il "riepilogo" del collegamento che ho postato per coloro che non sono in grado di decifrare il contenuto mostrato lì.

+0

Sembra interessante .. se vuoi pubblicare questo qui, qualcun altro avrà la possibilità di ottenere la sua risposta qui guardando qui .. – Guillermo

7

Aggiornamento:

Questo vi darà il numero di giorni in un dato mese:

echo date('t', $timestamp); 

See: date()

Vecchia risposta:

Sono non sono sicuro dell'algoritmo a cui stai pensando, ma credo che questo ci aiuterà p si:

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

+1 Questo è quello che farei in questa situazione. – karim79

+2

strtotime ("30-01-2009 +1 mese"); risolve come 2009.03.02 non utile nel mio caso – Guillermo

+0

@Guillermo, se si desidera mappare dal 31 gennaio al 28 febbraio, allora che giorno corrisponde al 28 gennaio? Ancora il 28 febbraio? –

4

Ciò restituirà corretta timestamp per $ X mesi a venire: mktime(0,0,0,date("m")+$X,date('d'),date("Y"));

+0

+1 Questo sembra più naturale: spezza la data e aggiungi elementi ai componenti per ottenere ciò che desideri. – Kekoa

+0

+1, l'ho provato e funziona bene quando il mese corrente più x è uguale a un numero maggiore di 12. Aumenta l'anno correttamente.Inoltre, se il numero del giorno non esiste nel mese, si sposterà al mese successivo con i giorni aggiuntivi. – gradbot

+1

appena testato il tuo test case "2009-01-30" +1 mese e questo restituisce anche il 2009-3-2 – gradbot

0

Che ne dite di questa funzione:

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; 
    } 

C'è un'altra soluzione sul sito manuale php.net sotto la voce strtotime nel comments.

1

provato questo come un fringuello, e in realtà funziona

strtotime('last day next month') 

Quindi:

$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

Devo dire che non mi aspettavo che funzionasse affatto. Ma è successo! –

0

Nessuno è menzionato questa alternativa, anche se il risultato è lo stesso come gli altri, e probabilmente non quello l'OP sta cercando:

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

Perché non memorizzare solo mese e giorno separatamente e incrementare il mese di e, quindi utilizzare la funzione di PHP checkdate per convalidare la data, diminuendo il giorno di uno fino a quando la data è valida?

0

So che questo è un vecchio post ma pensato per dare un approccio diverso.

Così, invece di cercare di capire i giorni in un mese (che è un po 'complicato), si può scoprire il prossimo mese con il mese corrente con facilità, ad esempio:

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

quindi ottenere il giorno della il mese corrente utilizzando date("d") e concat con il mese successivo dal codice sopra.

3

Prova questo. reday è il giorno di ricarica (int - giorno del mese). Se inferiore a oggi, darà reday di questo mese, ma non molto di no. di questo mese Se più di oggi danno lo reday del prossimo mese, la stessa condizione. Lo uso per calcolare "Next refill" del punto di ricarica mensile.ritorno è 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; 
     } 
    } 
} 

per più diretto al punto (Edit)

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

Non sono sicuro di aver compreso la spiegazione –

1

semplice

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

Ho anche avuto lo stesso problema, ma quando ho provato in precedenza soluzioni non potevano funzionare perfettamente per me, ho provato sulla mia estremità e si avvicinò con la nuova soluzione che è:

$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

Datetime OOP Stile

<?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

Questo è quello che uso

Questo è un timestamp di data mese corrente giorno

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

attuale

$current_day = date('d'); 

E questo è il mese prossimo giorno stesso in formato "Ymd"

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

Nessuno dei precedenti prese cura di giorni non esistenti (30 febbraio, ovvero il 31 aprile per esempio), ecco la mia funzione:

<?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 
*/ 
Problemi correlati