Pytanie przyrost daty o jeden miesiąc


Załóżmy, że mam datę w następującym formacie: 2010-12-11 (rok-dzień-dzień)

W PHP chcę zwiększyć datę o jeden miesiąc i chcę, aby rok był automatycznie zwiększany, jeśli to konieczne (tj. Inkrementacja od grudnia 2012 r. Do stycznia 2013 r.).

Pozdrowienia.


76
2018-05-20 00:15


pochodzenie




Odpowiedzi:


$time = strtotime("2010.12.11");
$final = date("Y-m-d", strtotime("+1 month", $time));

// Finally you will have the date you're looking for.

119
2018-05-20 00:45



To nie działa z całą datą. Na przykład 2013-05-31 wyświetli się lipiec zamiast następnego miesiąca, czyli czerwca. - Patrick Desjardins
Dostaję następujące, 2014-03-03 na lata 2014-01-31 powód? - Manish Goyal
Nie działało z tym ciągiem znaków: "2014-06-19 15:00:19" - Meetai.com
php.net/manual/en/function.strtotime.php Y-M-D to strtotime ("2010.12.11"); * (kropki, nie kreski) - Joeri
To czasami psuje. Odpowiedź @jason jest technicznie bardziej poprawna, ponieważ uwzględnia lata takie jak lata przestępne, długości miesięcy i tak dalej. To powinno być oznaczone jako poprawna odpowiedź. - skift


Potrzebowałem podobnej funkcjonalności, z wyjątkiem miesięcznego cyklu (plus miesiące, minus 1 dzień). Po przeszukaniu S.O. przez jakiś czas udało mi się stworzyć to rozwiązanie typu plug-n-play:

function add_months($months, DateTime $dateObject) 
    {
        $next = new DateTime($dateObject->format('Y-m-d'));
        $next->modify('last day of +'.$months.' month');

        if($dateObject->format('d') > $next->format('d')) {
            return $dateObject->diff($next);
        } else {
            return new DateInterval('P'.$months.'M');
        }
    }

function endCycle($d1, $months)
    {
        $date = new DateTime($d1);

        // call second function to add the months
        $newDate = $date->add(add_months($months, $date));

        // goes back 1 day from date, remove if you want same day of month
        $newDate->sub(new DateInterval('P1D')); 

        //formats final date to Y-m-d form
        $dateReturned = $newDate->format('Y-m-d'); 

        return $dateReturned;
    }

Przykład:

$startDate = '2014-06-03'; // select date in Y-m-d format
$nMonths = 1; // choose how many months you want to move ahead
$final = endCycle($startDate, $nMonths); // output: 2014-07-02

28
2018-06-03 11:55



Doskonale, właśnie tego potrzebowałem. Dziękuję, że oszczędziłeś mi dużo czasu! - Tum
Nie ma problemu, cieszę się, że okazało się to przydatne - Jason
Dzięki Jason, to było bardzo pomocne. Przeformatowałem go i dodałem więcej komentarzy, aby pomóc mi zrozumieć wszystko. W przypadku, który pomaga każdemu, umieściłem go dalej (próbowałem dodać tutaj, ale to było za długie). - ScreenWatcher


Posługiwać się DateTime::add.

$start = new DateTime("2010-12-11", new DateTimeZone("UTC"));
$month_later = clone $start;
$month_later->add(new DateInterval("P1M"));

użyłem klonować ponieważ add modyfikuje oryginalny obiekt, co może nie być pożądane.


23
2018-05-20 00:17



Działa to, ale dodaję metodę zwracania. - Meetai.com


strtotime( "+1 month", strtotime( $time ) );

to zwraca znacznik czasu, który może być użyty z funkcją daty


11
2018-05-20 00:18



@Gelen: to nie działa, podaje niewłaściwą datę .... proszę, powiedz, jak użyć swojej metody, jaka jest wartość czasu $ tutaj? - sqlchild
to nie działa, podaje niewłaściwą datę .... proszę, powiedz, jak użyć swojej metody, jaka jest wartość $ czasu tutaj? - sqlchild
Ten sam problem, co zaakceptowana odpowiedź. Nie działa na wszystkich ciągach. - Meetai.com
to działa dla mnie (oczywiście $time ma wartość początkową). - tatskie


Używam w ten sposób:

 $occDate='2014-01-28';
 $forOdNextMonth= date('m', strtotime("+1 month", strtotime($occDate)));
//Output:- $forOdNextMonth=02


/*****************more example****************/
$occDate='2014-12-28';

$forOdNextMonth= date('m', strtotime("+1 month", strtotime($occDate)));
//Output:- $forOdNextMonth=01

//***********************wrong way**********************************//
$forOdNextMonth= date('m', strtotime("+1 month", $occDate));
  //Output:- $forOdNextMonth=02; //instead of $forOdNextMonth=01;
//******************************************************************//

5
2018-01-19 05:42



to działa dla mnie dzięki. Ale data ("m", strtotime ("+ 1 miesiąc", strtotime ($ occDate))) i data ("m", strtotime ("+ 1 miesiąc", $ occDate)) działają tak samo.
Nie, obie to różnica @ sah.cyBuzzSc. Rozważ przykład: - $ occDate = '2014-12-28'; $ forOdNextMonth = date ('m', strtotime ("+ 1 miesiąc", $ occDate)); Wartość $ forOdNextMonth to 02. - vineet
dziękuję za wyjaśnienie @chotesah. Twój drugi przykład jest całkiem dobry.


(date('d') > 28) ? date("mdY", strtotime("last day of next month")) : date("mdY", strtotime("+1 month"));

To zrekompensuje luty i pozostałe 31 dni. Oczywiście możesz zrobić o wiele więcej sprawdzeń, aby uzyskać dokładniejsze informacje o "bieżącym dniu następnego miesiąca" względne formaty daty (co nie działa niestety, patrz niżej), a równie dobrze można użyć DateTime.

Obie DateInterval('P1M') i strtotime("+1 month") zasadniczo ślepo dodają 31 dni niezależnie od liczby dni w kolejnym miesiącu.

  • 2010-01-31 => 3 marca
  • 2012-01-31 => 2 marca (rok przestępny)

4
2017-11-10 22:07



"ślepo dodając 31 dni bez względu na liczbę dni w następnym miesiącu", absolutnie dobrze! (+1). - Jose Manuel Abarca Rodríguez


Najpierw ustaw format daty jako 12-12-2012

Po użyciu ta funkcja działa poprawnie;

$date =  date('d-m-Y',strtotime("12-12-2012 +2 Months");

Tutaj 12-12-2012 to Twoja data, a +2 Miesiące to przyrost miesiąca;

Ty także przyrost roku, daty

strtotime("12-12-2012 +1 Year");

Ans to 12-12-2013


3
2017-11-15 09:32





Możesz użyć DateTime::modify lubię to :

$date = new DateTime('2010-12-11');
$date->modify('+1 month');

Zobacz dokumentacje:

http://php.net/manual/fr/datetime.modify.php

http://php.net/manual/fr/class.datetime.php


2
2017-11-01 11:49



skacze od 31 maja do 1 lipca, co jest nieprawidłowe - ckonig
Tak, rzeczywiście ... Będę edytować mój post, aby rozwiązać ten problem - HRoux


Dzięki Jason, twój post był bardzo pomocny. Przeformatowałem go i dodałem więcej komentarzy, aby pomóc mi zrozumieć wszystko. W przypadku, który pomaga każdemu, opublikowałem go tutaj:

function cycle_end_date($cycle_start_date, $months) {
    $cycle_start_date_object = new DateTime($cycle_start_date);

    //Find the date interval that we will need to add to the start date
    $date_interval = find_date_interval($months, $cycle_start_date_object);

    //Add this date interval to the current date (the DateTime class handles remaining complexity like year-ends)
    $cycle_end_date_object = $cycle_start_date_object->add($date_interval);

    //Subtract (sub) 1 day from date
    $cycle_end_date_object->sub(new DateInterval('P1D')); 

    //Format final date to Y-m-d
    $cycle_end_date = $cycle_end_date_object->format('Y-m-d'); 

    return $cycle_end_date;
}

//Find the date interval we need to add to start date to get end date
function find_date_interval($n_months, DateTime $cycle_start_date_object) {
    //Create new datetime object identical to inputted one
    $date_of_last_day_next_month = new DateTime($cycle_start_date_object->format('Y-m-d'));

    //And modify it so it is the date of the last day of the next month
    $date_of_last_day_next_month->modify('last day of +'.$n_months.' month');

    //If the day of inputted date (e.g. 31) is greater than last day of next month (e.g. 28)
    if($cycle_start_date_object->format('d') > $date_of_last_day_next_month->format('d')) {
        //Return a DateInterval object equal to the number of days difference
        return $cycle_start_date_object->diff($date_of_last_day_next_month);
    //Otherwise the date is easy and we can just add a month to it
    } else {
        //Return a DateInterval object equal to a period (P) of 1 month (M)
        return new DateInterval('P'.$n_months.'M');
    }
}

$cycle_start_date = '2014-01-31'; // select date in Y-m-d format
$n_months = 1; // choose how many months you want to move ahead
$cycle_end_date = cycle_end_date($cycle_start_date, $n_months); // output: 2014-07-02

0
2017-11-13 20:14