DateTime::modify

date_modify

(PHP 5 >= 5.2.0)

DateTime::modify -- date_modifyИзменение временной метки

Описание

Объектно-ориентированный стиль

public DateTime DateTime::modify ( string $modify )

Процедурный стиль

DateTime date_modify ( DateTime $object , string $modify )

Изменяет метку времени объекта DateTime путем добавления или вычитания времени в формате, принятом для функции strtotime().

Список параметров

object

Только для процедурного стиля: Объект DateTime, возвращаемый date_create(). Функция изменяет этот объект.

modify

Строка даты/времени. Объяснение корректных форматов дано в Форматы даты и времени.

Возвращаемые значения

Возвращает объект DateTime для применения в цепи методов или FALSE в случае возникновения ошибки.

Список изменений

Версия Описание
5.3.6 Стало возможным применять абсолютные значения объектов даты/времени. Раньше использовались только относительные значения полей даты/времени.
5.3.0Изменено значение успешной работы функции с NULL на DateTime.

Примеры

Пример #1 Пример использования DateTime::modify()

Объектно-ориентированный стиль

<?php
$date 
= new DateTime('2006-12-12');
$date->modify('+1 day');
echo 
$date->format('Y-m-d');
?>

Процедурный стиль

<?php
$date 
date_create('2006-12-12');
date_modify($date'+1 day');
echo 
date_format($date'Y-m-d');
?>

Результат выполнения данных примеров:

2006-12-13

Пример #2 Будьте осторожны при добавлении и вычитании месяцев

<?php
$date 
= new DateTime('2000-12-31');

$date->modify('+1 month');
echo 
$date->format('Y-m-d') . "\n";

$date->modify('+1 month');
echo 
$date->format('Y-m-d') . "\n";
?>

Результат выполнения данного примера:

2001-01-31
2001-03-03

Смотрите также

  • strtotime() - Преобразует текстовое представление даты на английском языке в метку времени Unix
  • DateTime::add() - Добавляет заданное количество дней, месяцев, лет, часов, минут и секунд к объекту DateTime
  • DateTime::sub() - Вычитает заданное количество дней, месяцев, лет, часов, минут и секунд из времени объекта DateTime
  • DateTime::setDate() - Установка даты
  • DateTime::setISODate() - Установка ISO даты
  • DateTime::setTime() - Установка времени
  • DateTime::setTimestamp() - Устанавливает дату и время, основываясь на метке времени Unix

Коментарии

These functions makes sure that adding months or years always ends up in the month you would expect.  Works for positive and negative values

<?php
     
       
    $date
=new DateTime();
   
$date->setDate(2008,2,29);
   
    function 
addMonths($date,$months){
         
       
$init=clone $date;
       
$modifier=$months.' months';
       
$back_modifier =-$months.' months';
       
       
$date->modify($modifier);
       
$back_to_init= clone $date;
       
$back_to_init->modify($back_modifier);
       
        while(
$init->format('m')!=$back_to_init->format('m')){
       
$date->modify('-1 day')    ;
       
$back_to_init= clone $date;
       
$back_to_init->modify($back_modifier);   
        }
       
       
/*
        if($months<0&&$date->format('m')>$init->format('m'))
        while($date->format('m')-12-$init->format('m')!=$months%12)
        $date->modify('-1 day');
        else
        if($months>0&&$date->format('m')<$init->format('m'))
        while($date->format('m')+12-$init->format('m')!=$months%12)
        $date->modify('-1 day');
        else
        while($date->format('m')-$init->format('m')!=$months%12)
        $date->modify('-1 day');
        */
       
   
}
     
    function 
addYears($date,$years){
       
       
$init=clone $date;
       
$modifier=$years.' years';
       
$date->modify($modifier);
       
        while(
$date->format('m')!=$init->format('m'))
       
$date->modify('-1 day');
       
       
    } 
   
   
   
   
addMonths($date,-1);
     
addYears($date,3);
   
   
    echo 
$date->format('F j,Y');
     
 
?>
2012-02-20 16:34:55
http://php5.kiev.ua/manual/ru/datetime.modify.html
Note: This method modifies the object in-place. So if you want to calculate a new date but assign the new value to a different object, this will NOT work:

<?php
$numMinutes 
25;
$oDateA = new DateTime('2012-01-01 12:00:00');

print 
"
Original:<br>
oDateA =  {$oDateA->format('Y-m-d H-i-s')}<br>
"
;

$oDateB $oDateA->modify ("+{$numMinutes} minutes");

print 
"
plus {$numMinutes} minutes:<br>
oDateA =  {$oDateA->format('Y-m-d H-i-s')}<br>
oDateB =  {$oDateB->format('Y-m-d H-i-s')}<br>
"
;
?>
...produces this:
oDateA = 2012-01-01 12-00-00
plus 25 minutes:
oDateA = 2012-01-01 12-25-00
oDateB = 2012-01-01 12-25-00

Use something like this instead:
<?php
$numMinutes 
25;
$oDateA = new DateTime('2012-01-01 12:00:00');

print 
"
<p>
Original:<br>
oDateA =  {$oDateA->format('Y-m-d H-i-s')}<br>
"
;

$oDateB = clone $oDateA;
$oDateB->modify ("+{$numMinutes} minutes");

print 
"
plus {$numMinutes} minutes:<br>
oDateA =  {$oDateA->format('Y-m-d H-i-s')}<br>
oDateB =  {$oDateB->format('Y-m-d H-i-s')}<br>
"
;
?>

... produces this:
oDateA = 2012-01-01 12-00-00
plus 25 minutes:
oDateA = 2012-01-01 12-00-00
oDateB = 2012-01-01 12-25-00
2012-04-16 00:04:34
http://php5.kiev.ua/manual/ru/datetime.modify.html
modify() ignores any timezone information in the data while the DateTime constructor does not.

$dt = new DateTime( '2013-10-26T11:00:00+11:00' ) 
will create a +11 timezone while
$dt->modify( '2013-10-26T11:00:00+02:00' )
does not change the timezone or the time.

<?php
$dt 
= new DateTime'2013-10-26T15:00:00Australia/Melbourne' ) ;
echo 
"\n"$dt->format"c" ) ;
echo 
"\nTimezone '"$dt->getTimezone()->getName() . "'." ;
// modify $dt to 1 am new york which is 3 pm melbourne
$dt->modify'2013-10-26T01:00:00America/New_York' ) ;
// result is 1 am melbourne time, not 3 pm
echo "\n"$dt->format"c" ) ;
echo 
"\nTimezone '"$dt->getTimezone()->getName() . "'." ;
?>
Output
2013-10-26T15:00:00+11:00
Timezone 'Australia/Melbourne'.
2013-10-26T01:00:00+11:00
Timezone 'Australia/Melbourne'.
2013-10-26 09:50:21
http://php5.kiev.ua/manual/ru/datetime.modify.html
Due to DST and the way DateTime internally handles dates, it's possible to get stuck in a time loop.

For example:

<?php
$dt 
= new DateTime('2012-03-11 3:00AM');
echo 
$dt->format('YmdH') . "\n";
$dt->modify("-1 hour");
echo 
$dt->format('YmdH') . "\n";
$dt->modify("-1 hour");
echo 
$dt->format('YmdH') . "\n";
?>

prints out:

2012031103
2012031103
2012031103

if your timezone is set to America/New_York.
2013-10-29 07:46:44
http://php5.kiev.ua/manual/ru/datetime.modify.html
The changelog says: "5.3.0 - Changed the return value on success from NULL to DateTime".

That means that you can't do a Fluid Interface design with it in PHP 5.2.

In other words, this will not work in 5.2:

<?php
$DateTime
=new DateTime();
echo 
$DateTime->modify('+1 day')->format('d');
?>
2014-04-08 23:22:00
http://php5.kiev.ua/manual/ru/datetime.modify.html
Автор:
Extension for DateTime class which solves problem of adding or subtracting months

https://gist.github.com/66Ton99/60571ee49bf1906aaa1c
2014-05-13 18:31:46
http://php5.kiev.ua/manual/ru/datetime.modify.html
This is an improvement of @jenspj's answer

<?php

$d 
= new DateTime('2007-12-31');

function 
addMonths($date$months)
{
   
$years floor(abs($months 12));
   
$leap 29 <= $date->format('d');
   
$m 12 * (<= $months?1:-1);
    for (
$a 1;$a $years;++$a) {
       
$date addMonths($date$m);
    }
   
$months -= ($a 1) * $m;
   
   
$init = clone $date;
    if (
!= $months) {
       
$modifier $months ' months';
       
       
$date->modify($modifier);
        if (
$date->format('m') % 12 != (12 $months $init->format('m')) % 12) {
           
$day $date->format('d');
           
$init->modify("-{$day} days");
        }
       
$init->modify($modifier);
    }
   
   
$y $init->format('Y');
    if (
$leap && ($y 4) == && ($y 100) != && 28 == $init->format('d')) {
       
$init->modify('+1 day');
    }
    return 
$init;
}

function 
addYears($date$years)
{
    return 
addMonths($date12 $years);
}

echo 
$d->format('F j,Y') . ' N<br />';
$d addMonths($d, +1);
echo 
$d->format('F j,Y') . ' +1M<br />';
$d addMonths($d, +1);
echo 
$d->format('F j,Y') . ' +1M<br />';
$d addYears($d, +60);
echo 
$d->format('F j,Y') . ' +60Y<br />';
$d addYears($d, -59);
echo 
$d->format('F j,Y') . ' -59Y<br />';
2015-07-04 23:31:31
http://php5.kiev.ua/manual/ru/datetime.modify.html
Автор:
I cant believe this is in official PHPDOC, such an incredible retarded bug, and, best of all, No explanation at all... this is the kind of things that make PHPCore developers look like fools.

<?php
$date 
= new DateTime('2000-12-31');

$date->modify('+1 month');
echo 
$date->format('Y-m-d') . "\n";

$date->modify('+1 month');
echo 
$date->format('Y-m-d') . "\n";
?>

Result:

2001-01-31
2001-03-03
2016-03-30 18:14:24
http://php5.kiev.ua/manual/ru/datetime.modify.html
A very simple way to ensure we do not cross over month boundaries when adding months is to just go back a few days if the day number got reset:

<?php
function addMonths($date,$months) {
 
$orig_day $date->format("d");
 
$date->modify("+".$months." months");
  while (
$date->format("d")<$orig_day && $date->format("d")<5) {
   
$date->modify("-1 day");
  }
}

for (
$i=0;$i<5;$i++) {
 
$d = new DateTime("2000-01-10");
 
addmonths($d,$i);
  echo 
$d->format("Y-m-d")."<br>";
}
for (
$i=0;$i<5;$i++) {
 
$d = new DateTime("2000-01-31");
 
addmonths($d,$i);
  echo 
$d->format("Y-m-d")."<br>";
}
?>

prints:
2000-01-10
2000-02-10
2000-03-10
2000-04-10
2000-05-10
2000-01-31
2000-02-29
2000-03-31
2000-04-30
2000-05-31
2016-11-30 00:54:10
http://php5.kiev.ua/manual/ru/datetime.modify.html
a slightly more compact way of getting the month shift

<?php

     
/**
     * correctly calculates end of months when we shift to a shorter or longer month
     * workaround for datetime.add#example-2489 
     * 
     * Makes the assumption that shifting from the 28th Feb +1 month is 31st March
     * Makes the assumption that shifting from the 28th Feb -1 month is 31st Jan
     * Makes the assumption that shifting from the 29,30,31 Jan +1 month is 28th (or 29th) Feb
     *
     * 
     * @param DateTime $aDate
     * @param int $months positive or negative
     * 
     * @return DateTime new instance - original parameter is unchanged
     */

   
function MonthShifter (DateTime $aDate,$months){
       
$dateA = clone($aDate);
       
$dateB = clone($aDate);
       
$plusMonths = clone($dateA->modify($months ' Month'));
       
//check whether reversing the month addition gives us the original day back
       
if($dateB != $dateA->modify($months*-' Month')){ 
           
$result $plusMonths->modify('last day of last month');
        } elseif(
$aDate == $dateB->modify('last day of this month')){
           
$result $plusMonths->modify('last day of this month');
        } else {
           
$result $plusMonths;
        }
        return 
$result;
    }

//TEST

$x = new DateTime('2017-01-30');
echo( 
$x->format('Y-m-d')." past end of feb, but not dec<br>");
echo(
'b ' MonthShifter($x,1)->format(('Y-m-d'))."<br>");
echo(
'c ' MonthShifter($x,-1)->format(('Y-m-d'))."<br>");

$x = new DateTime('2017-01-15');
echo(
"<br>" $x->format('Y-m-d')." middle of the month <br>");
echo(
'd ' MonthShifter($x,1)->format(('Y-m-d'))."<br>");
echo(
'e ' MonthShifter($x,-1)->format(('Y-m-d'))."<br>");

$x = new DateTime('2017-02-28');
echo(
"<br>" $x->format('Y-m-d')." end of Feb<br>");
echo(
'f ' MonthShifter($x,1)->format(('Y-m-d'))."<br>");
echo(
'g ' MonthShifter($x,-1)->format(('Y-m-d'))."<br>");

$x = new DateTime('2017-01-31');
echo(
"<br>" $x->format('Y-m-d')." end of Jan<br>");
echo(
'h ' MonthShifter($x,1)->format(('Y-m-d'))."<br>");
echo(
'i ' MonthShifter($x,-1)->format(('Y-m-d'))."<br>");

$x = new DateTime('2017-01-31');
echo(
"<br>" $x->format('Y-m-d')." end of Jan +/- 1 years diff, leap year respected<br>");
echo(
'j ' MonthShifter($x,13)->format(('Y-m-d'))."<br>");
echo(
'k ' MonthShifter($x,-11)->format(('Y-m-d'))."<br>");

//returns

2017-01-30 past end of febbut not dec
b 2017
-02-28
c 2016
-12-30

2017
-01-15 middle of the month 
d 2017
-02-15
e 2016
-12-15

2017
-02-28end of Feb
f 2017
-03-31
g 2017
-01-31

2017
-01-31end of Jan
h 2017
-02-28
i 2016
-12-31

2017
-01-31end of Jan +/- 1 years diffleap year respected
j 2018
-02-28
k 2016
-02-29
2017-01-24 07:55:03
http://php5.kiev.ua/manual/ru/datetime.modify.html

    Поддержать сайт на родительском проекте КГБ