web-dev-qa-db-fra.com

Comment ajouter 1 mois à une date sans sauter en février

Dupliquer possible:
PHP DateTime :: modifier les mois d'addition et de soustraction

J'ai une date de début (c'est-à-dire 2011-01-30) et je veux ajouter 1 mois.

Le problème est de définir ce qu'est un mois. Donc si j'utilise le code suivant:

$d1 = DateTime::createFromFormat('Y-m-d H:i:s', '2011-01-30 15:57:57');
$d1->add(new DateInterval('P1M'));
echo $d1->format('Y-m-d H:i:s');

J'ai le résultat suivant: 2011-03-02 15:57:57

Le problème est que j'en ai besoin pour utiliser les règles suivantes:

  • Si j'ajoute 1 mois, il faudra simplement ajouter 1 sur la partie mois et laisser la partie jour (2011-01-15 deviendra 2011-02-15)
  • Si le jour n’existe pas dans le mois de la fin, nous en prenons le dernier jour existant (Le 2011-01-30 deviendra le 2011-02-28)

Existe-t-il une fonction commune dans php qui peut le faire ou dois-je la coder moi-même? Peut-être que je manque juste un paramètre ou quelque chose!?

20
Kasihasi

Il semble qu’il n’y ait pas de fonction prête pour cela, alors je l’ai écrit moi-même ..__ Cela devrait résoudre mon problème. Merci quand même pour vos réponses et vos commentaires .. Si vous trouvez des erreurs, merci de les indiquer dans les commentaires.

Cette fonction calcule le mois et l’année dans lesquelles je vais finir après avoir ajouté quelques mois. Ensuite, il vérifie si la date est correcte. Si ce n'est pas le cas, nous avons le cas où le jour n'est pas dans le mois cible, nous prenons donc le dernier jour du mois . Testé avec PHP 5.3.10. 

<?php
$monthToAdd = 1;

$d1 = DateTime::createFromFormat('Y-m-d H:i:s', '2011-01-30 15:57:57');

$year = $d1->format('Y');
$month = $d1->format('n');
$day = $d1->format('d');

$year += floor($monthToAdd/12);
$monthToAdd = $monthToAdd%12;
$month += $monthToAdd;
if($month > 12) {
    $year ++;
    $month = $month % 12;
    if($month === 0)
        $month = 12;
}

if(!checkdate($month, $day, $year)) {
    $d2 = DateTime::createFromFormat('Y-n-j', $year.'-'.$month.'-1');
    $d2->modify('last day of');
}else {
    $d2 = DateTime::createFromFormat('Y-n-d', $year.'-'.$month.'-'.$day);
}
$d2->setTime($d1->format('H'), $d1->format('i'), $d1->format('s'));
echo $d2->format('Y-m-d H:i:s');
11
Kasihasi

Vous avez plusieurs alternatives en plus de DateInterval. 

Voici des exemples qui utilisent strtotime():

http://www.brightcherry.co.uk/scribbles/php-adding-and-subtracting-dates/

// Subtracting days from a date
$date = "1998-08-14";
$newdate = strtotime ( '-3 day' , strtotime ( $date ) ) ;
$newdate = date ( 'Y-m-j' , $newdate );

echo $newdate;

...

// Subtracting months from a date
$date = "1998-08-14";
$newdate = strtotime ( '-3 month' , strtotime ( $date ) ) ;
$newdate = date ( 'Y-m-j' , $newdate );

echo $newdate;

Voici quelques liens pour DateInterval:

Q: Exactement comment vous {faites vous définissez un "mois"?

Déf # 1): un "mois" est un "mois" - indépendamment de #/jours

Déf # 2): un "mois" est de 30 jours (par exemple)

Déf # 3): un "mois" est le #/jours entre le 1er lundi de mois suivants

etc

Q: Quelle est exactement votre "définition"?

11
paulsm4

OK - autant que je sache, vous n'avez toujours pas clairement défini ce que vous entendez par "mois".

Mais voici une autre fonction qui pourrait aider:

http://php.net/manual/en/function.getdate.php

/* Function to find the first and last day of the month from the given date.
*
* Author Binu v Pillai            [email protected]
* @Param            String             yyyy-mm-dd
*
*/
function findFirstAndLastDay($anyDate)
{
    //$anyDate            =    '2009-08-25';    // date format should be yyyy-mm-dd
    list($yr,$mn,$dt)    =    split('-',$anyDate);    // separate year, month and date
    $timeStamp            =    mktime(0,0,0,$mn,1,$yr);    //Create time stamp of the first day from the give date.
    $firstDay            =     date('D',$timeStamp);    //get first day of the given month
    list($y,$m,$t)        =     split('-',date('Y-m-t',$timeStamp)); //Find the last date of the month and separating it
    $lastDayTimeStamp    =    mktime(0,0,0,$m,$t,$y);//create time stamp of the last date of the give month
    $lastDay            =    date('D',$lastDayTimeStamp);// Find last day of the month
    $arrDay                =    array("$firstDay","$lastDay"); // return the result in an array format.

    return $arrDay;
}
0
paulsm4