DateTime::add

date_add

(PHP 5 >= 5.3.0)

DateTime::add -- date_add Добавляет заданное количество дней, месяцев, лет, часов, минут и секунд к объекту DateTime

Описание

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

public DateTime DateTime::add ( DateInterval $interval )

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

DateTime date_add ( DateTime $object , DateInterval $interval )

Прибавляет заданный объект DateInterval к объекту DateTime.

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

object

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

interval

Объект класса DateInterval

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

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

Примеры

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

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

<?php
$date 
= new DateTime('2000-01-01');
$date->add(new DateInterval('P10D'));
echo 
$date->format('Y-m-d') . "\n";
?>

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

<?php
$date 
date_create('2000-01-01');
date_add($datedate_interval_create_from_date_string('10 days'));
echo 
date_format($date'Y-m-d');
?>

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

2000-01-11

Пример #2 Другие примеры с DateTime::add()

<?php
$date 
= new DateTime('2000-01-01');
$date->add(new DateInterval('PT10H30S'));
echo 
$date->format('Y-m-d H:i:s') . "\n";

$date = new DateTime('2000-01-01');
$date->add(new DateInterval('P7Y5M4DT4H3M2S'));
echo 
$date->format('Y-m-d H:i:s') . "\n";
?>

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

2000-01-01 10:00:30
2007-06-05 04:03:02

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

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

$date->add($interval);
echo 
$date->format('Y-m-d') . "\n";

$date->add($interval);
echo 
$date->format('Y-m-d') . "\n";
?>

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

2001-01-31
2001-03-03

Примечания

При работе с PHP 5.2 в качестве альтернативы можно воспользоваться функцией DateTime::modify().

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

  • DateTime::sub() - Вычитает заданное количество дней, месяцев, лет, часов, минут и секунд из времени объекта DateTime
  • DateTime::diff() - Возвращает разницу между двумя DateTime объектами
  • DateTime::modify() - Изменение временной метки

Коментарии

adding 15 min to a datetime

<?php
$initDate 
= new DateTime("2010/08/24");

$initDate->add(new DateInterval("PT15M"));
echo 
$initDate->format("Y/m/d m:i:s");//result: 2010/08/24 08:15:00
?>

period:
P1Y2M3DT1H2M3S

period time:
PT1H2M3S
2010-08-24 02:00:50
http://php5.kiev.ua/manual/ru/datetime.add.html
Автор:
Note that the add() and sub() methods will modify the value of the object you're calling the method on! This is very untypical for a method that returns a value of its own type. You could misunderstand it that the method would return a new instance with the modified value, but in fact it modifies itself! This is undocumented here. (Only a side note on procedural style mentions it, but it obviously does not apply to object oriented style.)
2011-02-01 16:16:10
http://php5.kiev.ua/manual/ru/datetime.add.html
If you need add() and sub() that don't modify object values, you can create new methods like this:

<?php

class DateTimeEnhanced extends DateTime {

    public function 
returnAdd(DateInterval $interval)
    {
       
$dt = clone $this;
       
$dt->add($interval);
        return 
$dt;
    }
   
    public function 
returnSub(DateInterval $interval)
    {
       
$dt = clone $this;
       
$dt->sub($interval);
        return 
$dt;
    }

}

$interval DateInterval::createfromdatestring('+1 day');

$dt = new DateTimeEnhanced# initialize new object
echo $dt->format(DateTime::W3C) . "\n"# 2013-09-12T15:01:44+02:00

$dt->add($interval); # this modifies the object values
echo $dt->format(DateTime::W3C) . "\n"# 2013-09-13T15:01:44+02:00

$dtNew $dt->returnAdd($interval); # this returns the new modified object and doesn't change original object
echo $dt->format(DateTime::W3C) . "\n"# 2013-09-13T15:01:44+02:00
echo $dtNew->format(DateTime::W3C) . "\n"# 2013-09-14T15:01:44+02:00
2013-09-12 16:06:12
http://php5.kiev.ua/manual/ru/datetime.add.html
Be careful that the internal timer to your DateTime object can be changed drastically when adding even 1 second, during the switch from DST to normal.
Consider the following:
<?php

$ts 
1383458399/* 2013-11-03 01:59:59 in Eastern Saving Time */
$dst DateTime::createFromFormat('U',$ts, new DateTimeZone('GMT')); /* timezone is ignored for a unix timestamp, but if we don't put it, php throws warnings */
$dst->setTimeZone(new DateTimeZone('EST5EDT')); /* a timezone effectuating the change */
$second = new DateInterval('PT1S'); /* one second */

echo $ts "\t" $dst->format("U\tY-m-d H:i:s T") . "\n";

$dst->add($second);
$ts++;

echo 
$ts "\t" $dst->format("U\tY-m-d H:i:s T") . "\n";

/* results:
1383458399    1383458399    2013-11-03 01:59:59 EDT
1383458400    1383462000    2013-11-03 02:00:00 EST

noticed how the second column went from 1383458399 to 1383462000 even though only 1 second was added?
*/

?>
2013-09-18 22:28:33
http://php5.kiev.ua/manual/ru/datetime.add.html
Here is a solution to adding months when you want 2014-10-31 to become 2014-11-30 instead of 2014-12-01.

<?php

/**
 * Class MyDateTime
 *
 * Extends DateTime to include a sensible addMonth method.
 *
 * This class provides a method that will increment the month, and
 * if the day is greater than the last day in the new month, it
 * changes the day to the last day of that month. For example,
 * If you add one month to 2014-10-31 using DateTime::add, the
 * result is 2014-12-01. Using MyDateTime::addMonth the result is
 * 2014-11-30.
 */
class MyDateTime extends DateTime
{

    public function 
addMonth($num 1)
    {
       
$date $this->format('Y-n-j');
        list(
$y$m$d) = explode('-'$date);

       
$m += $num;
        while (
$m 12)
        {
           
$m -= 12;
           
$y++;
        }

       
$last_day date('t'strtotime("$y-$m-1"));
        if (
$d $last_day)
        {
           
$d $last_day;
        }

       
$this->setDate($y$m$d);
    }

}

?>
2014-11-25 18:34:33
http://php5.kiev.ua/manual/ru/datetime.add.html
Автор:
If you're using PHP >= 5.5, instead of using "glavic at gmail dot com"'s DateTimeEnhanced class, use the built in DateTimeImmutable type. When you call DateTimeImmutable::add() it will return a new object, rather than modifying the original
2015-07-01 13:55:53
http://php5.kiev.ua/manual/ru/datetime.add.html
Автор:
Another simple solution to adding a month but not autocorrecting days to the next month is this.
(Also works for substracting months)

$dt = new DateTime("2016-01-31");

$oldDay = $dt->format("d");
$dt->add(new DateInterval("P1M")); // 2016-03-02
$newDay = $dt->format("d");

if($oldDay != $newDay) {
    // Check if the day is changed, if so we skipped to the next month.
    // Substract days to go back to the last day of previous month.
    $dt->sub(new DateInterval("P" . $newDay . "D"));
}

echo $dt->format("Y-m-d"); // 2016-02-29

Hope this helps someone.
2015-11-19 14:28:28
http://php5.kiev.ua/manual/ru/datetime.add.html
Be careful when using this function, I may have happened upon a bug in PHP7.

My code is as follows

//get date from post or else fill with today's date
if (isset($_POST["from"]))
{
$from = date_create($_POST["from"]);
}else{
$from = date_create(date("Y-m-d"));
}

//get date from post if there isn't one just take the same date as what is in the $from variable and add one day to it
if (isset($_POST["to"]))
{
$to = date_create($_POST["to"]);
}else{
    $to = $from;
date_modify($to, '+1 day');
}
echo(date_format($from, 'Y-m-d') . " " . date_format($to, 'Y-m-d'));

The resultant output is
$from = 2015-12-11
$to = 2015-12-11

In actuality the result should be
$from = 2015-12-10
$to = 2015-12-11

For some reason the code above modifies the $from variable in the line date_modify($to, '+1 day'); even though it shouldn't as the $from variable isn't being modified.

to fix this i needed to change the code to

//get date from post or else fill with today's date
if (isset($_POST["from"]))
{
$from = date_create($_POST["from"]);
}else{
$from = date_create(date("Y-m-d"));
}

//get date from post if there isn't one just take the same date as what is in the $from variable and add one day to it
if (isset($_POST["to"]))
{
$to = date_create($_POST["to"]);
}else{
    $to = date_create(date("Y-m-d"));
date_modify($to, '+1 day');
}
echo(date_format($from, 'Y-m-d') . " " . date_format($to, 'Y-m-d'));

This isn't strictly the code I wanted. Possible bug?
2015-12-10 18:22:11
http://php5.kiev.ua/manual/ru/datetime.add.html
What you can do with this function/method is a great example of the philosophy: "just because you can do it doesn't mean you should". I'm talking about two issues: (1) the number of days in the month which varies from months 1-12 as well as for month 2 which could be leap year (or not); and then issue (2): what if there is the need to specify a large quantity of an interval such that it needs to be re-characterized into broader-scoped intervals (i.e. 184 seconds ==> 3 minutes-4 seconds). Examples in notes elsewhere in the docs for this function illustrate both issues and their undesired effects so I won't focus on them further. But how did I decide to handle? I've gone with four "public" functions and a single "private" function, and without giving you a bunch of code to study, here are their summaries...

1. function adjustYear(int $yearsAdj){ //you can pass in +/- value and I adjust year value by that value but then I also call PHP's 'cal_days_in_month' function to ensure the day number I have in my date does not exceed days in the month for the new year/month combo--if it does, I adjust the day value downward.

2. function adjustMonth(int $monthsAdj){ //same notes as above apply; but also, I allow any number to be passed in for $monthsAdj. I use the 'int' function (int($monthsAdj/12)) and modulus % operator to determine how to adjust both year and month. And again, I use 'cal_days_in_month' function to tweak the day number as needed.

3. function addTime(int $days, int $hours, int $minutes, int $seconds){
// I use date_add and create a DateInterval object from the corresponding string spec (created from the args passed to this function). Note that months and years are excluded due to the bad side-effects already mentioned elsewhere.

4. function subtractTime(int $days, int $hours, int $minutes, int $seconds){
//notes for "addTime" also apply to this function but note that I like separate add and subtract functions because setting the DateInterval property flag to indicate add/subtract is not as intuitive for future coding.

5. function recharacterizeIntervals(int $days, int $hours, int $minutes, int $seconds){ // I convert excessively large quantities of any one interval into the next largest interval using the 'int' function and modulus (%) operator. I then use the result of this function when creating the string interval specification that gets passed when generating the DateInterval object for calling the date_add function (or object-method equivalent).

**Results/goals...
--any number of days/hours/minutes/seconds can be passed in to add/subtractTime and all of "Y/M/D/H/M/S" values get adjusted as you would expect.
--using adjustYear/Month lets you pass +/- values and only "Y/M" values get modified without having undesirable effects on day values.
--a call to the "recharacterize" function helps ensure proper and desired values are in the intervals prior to calling date_add to let it do its work.
2017-05-19 18:43:32
http://php5.kiev.ua/manual/ru/datetime.add.html
Автор:
If you use fraction of seconds, you may have surprises. It only occurs when the sum of the floating point parts results in exactly 1 second (0.5 + 0.5 ou 0.3 + 0.7, for example). See these cases at intervals slightly bigger than 1 second:

<?php
$objDataHora 
date_create("2017-12-31T23:59:59.300");
$objIntervalo = new DateInterval("PT0S");
$objIntervalo->0.600;
$objDataHora date_add($objDataHora$objIntervalo);
$strDataHora date_format($objDataHora"Y-m-d\TH:i:s.v");
?>

$strDataHora is correct: "2017-12-31T23:59:59.900"

<?php
$objDataHora 
date_create("2017-12-31T23:59:59.300");
$objIntervalo = new DateInterval("PT0S");
$objIntervalo->0.800;
$objDataHora date_add($objDataHora$objIntervalo);
$strDataHora date_format($objDataHora"Y-m-d\TH:i:s.v");
?>

$strDataHora is correct: "2018-01-01T00:00:00.100"

But...

<?php
$objDataHora 
date_create("2017-12-31T23:59:59.300");
$objIntervalo = new DateInterval("PT0S");
$objIntervalo->0.700;
$objDataHora date_add($objDataHora$objIntervalo);
$strDataHora date_format($objDataHora"Y-m-d\TH:i:s.v");
?>

$strDataHora has "2017-12-31T23:59:59.1000"

To resolve, add 1 second to the interval and f property must be negative (-1.0 plus original value):

<?php
$objDataHora 
date_create("2017-12-31T23:59:59.300");
$objIntervalo = new DateInterval("PT1S");
$objIntervalo->= -0.300// = -1.0 + 0.700
$objDataHora date_add($objDataHora$objIntervalo);
$strDataHora date_format($objDataHora"Y-m-d\TH:i:s.v");
?>

$strDataHora is correct: "2018-01-01T00:00:00.000"
2018-10-11 19:56:37
http://php5.kiev.ua/manual/ru/datetime.add.html
Remark, that calculations on date are not defined as bijective operations.  The Summertime is integrated by mixing two concepts. You should test it beforehead.

Datetime will correct a date after each summation, if a date (29.2.2021 => 1.3.2021) or a datetime (29.3.2020 2:30 am (Europe/Berlin) => 29.3.2020 3:30 or 29.3.2020 1:30)

Example 
<?php

$expectEaster 
date_create_from_format('Y-m-d H:i:s''2020-04-12 12:00:00', new DateTimeZone('Europe/Berlin'));
$interval = new DateInterval('PT20761M');
$expectEaster->sub($interval);
echo(
'recalc '.$expectEaster->format('Y-m-d H:i:s')."\n");
$expectEaster->add($interval);
echo(
'easter '.$expectEaster->format('Y-m-d H:i:s')."\n" );

$expectEaster date_create_from_format('Y-m-d H:i:s''2020-04-12 12:00:00', new DateTimeZone('Europe/Berlin'));
$interval = new DateInterval('PT20760M');
$expectEaster->sub($interval);
echo(
'recalc '.$expectEaster->format('Y-m-d H:i:s')."\n");
$expectEaster->add($interval);
echo(
'easter '.$expectEaster->format('Y-m-d H:i:s')."\n");

$expectEaster date_create_from_format('Y-m-d H:i:s''2020-04-12 12:00:00', new DateTimeZone('Europe/Berlin'));
$interval = new DateInterval('PT20701M');
$expectEaster->sub($interval);
echo(
'recalc '.$expectEaster->format('Y-m-d H:i:s')."\n");
$expectEaster->add($interval);
echo(
'easter '.$expectEaster->format('Y-m-d H:i:s')."\n");

$expectEaster date_create_from_format('Y-m-d H:i:s''2020-04-12 12:00:00', new DateTimeZone('Europe/Berlin'));
$interval = new DateInterval('PT20700M');
$expectEaster->sub($interval);
echo(
'recalc '.$expectEaster->format('Y-m-d H:i:s')."\n");
$expectEaster->add($interval);
echo(
'easter '.$expectEaster->format('Y-m-d H:i:s')."\n");

// Result
// recalc 2020-03-29 00:59:00  // reduce the missing hour before you calcuclate the datetime
// easter 2020-04-12 11:00:00  // recalcultate the date and remove the missing hour
// recalc 2020-03-29 03:00:00  //because 2020-03-29 3:00:00 [it means 2020-03-29 2:00:00] does not exist add 60 min) 
// easter 2020-04-12 13:00:00 
// recalc 2020-03-29 03:59:00 // -(12*60+(11+2)*1440+21*60) = -(20701 min) =  = 29.3.2020 2:59(not exist => no-equivalent add of one hour) =>  29.3.2020 3:59 
// easter 2020-04-12 13:00:00 // Recalc add 60 minutes, because the hour does not exist.)
// recalc 2020-03-29 03:00:00 // -(12*60+(11+2)*1440+21*60 min)= -(20700 min) = 29.3.2020 3:00
// easter 2020-04-12 12:00:00 // +(12*60+(11+2)*1440+21*60 min)= +(20700 min) = 29.3.2020
2021-01-10 00:57:06
http://php5.kiev.ua/manual/ru/datetime.add.html
Автор:
$TodaySQL = substr(date(DATE_ISO8601 ),0,10)
$LastYearSQL = date('Y.m.d',strtotime("-1 years"))
$NextMonthEndSQL = date('Y.m.d',strtotime("+1 months"))

// handy little SQL date formats 

//Today
2021-03-24 
//Last year
2020.03.24
//Next month
2021.04.24
2021-03-24 16:45:10
http://php5.kiev.ua/manual/ru/datetime.add.html

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