Progress28.ru

IT Новости
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Php datetime add 1 day

DateTime::add

(PHP 5 >= 5.3.0, PHP 7)

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

Описание

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

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

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

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

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

Примеры

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

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

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

= 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» ;
?>

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

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

= 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» ;
?>

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

Примечания

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

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

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

User Contributed Notes 10 notes

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.

Here is a solution to adding months when you want 2014-10-31 to become 2014-11-30 instead of 2014-12-01.

/**
* 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 );

$last_day = date ( ‘t’ , strtotime ( » $y — $m -1″ ));
if ( $d > $last_day )
<
$d = $last_day ;
>

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

If you need add() and sub() that don’t modify object values, you can create new methods like this:

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

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:
= 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 ( «UtY-m-d H:i:s T» ) . «n» ;

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

echo $ts . «t» . $dst -> format ( «UtY-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?
*/

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:

= date_create ( «2017-12-31T23:59:59.300» );
$objIntervalo = new DateInterval ( «PT0S» );
$objIntervalo -> f = 0.600 ;
$objDataHora = date_add ( $objDataHora , $objIntervalo );
$strDataHora = date_format ( $objDataHora , «Y-m-dTH:i:s.v» );
?>

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

= date_create ( «2017-12-31T23:59:59.300» );
$objIntervalo = new DateInterval ( «PT0S» );
$objIntervalo -> f = 0.800 ;
$objDataHora = date_add ( $objDataHora , $objIntervalo );
$strDataHora = date_format ( $objDataHora , «Y-m-dTH:i:s.v» );
?>

$strDataHora is correct: «2018-01-01T00:00:00.100»

= date_create ( «2017-12-31T23:59:59.300» );
$objIntervalo = new DateInterval ( «PT0S» );
$objIntervalo -> f = 0.700 ;
$objDataHora = date_add ( $objDataHora , $objIntervalo );
$strDataHora = date_format ( $objDataHora , «Y-m-dTH: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):

= date_create ( «2017-12-31T23:59:59.300» );
$objIntervalo = new DateInterval ( «PT1S» );
$objIntervalo -> f = — 0.300 ; // = -1.0 + 0.700
$objDataHora = date_add ( $objDataHora , $objIntervalo );
$strDataHora = date_format ( $objDataHora , «Y-m-dTH:i:s.v» );
?>

$strDataHora is correct: «2018-01-01T00:00:00.000»

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.

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.

**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.

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?

Читать еще:  Powered by php link manager

DateTime::add

(PHP 5 >= 5.3.0, PHP 7)

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

Описание

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

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

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

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

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

Примеры

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

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

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

= 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» ;
?>

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

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

= 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» ;
?>

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

Примечания

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

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

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

Коментарии

adding 15 min to a datetime

= 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

If you need add() and sub() that don’t modify object values, you can create new methods like this:

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

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:
= 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 ( «UtY-m-d H:i:s T» ) . «n» ;

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

echo $ts . «t» . $dst -> format ( «UtY-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?
*/

Here is a solution to adding months when you want 2014-10-31 to become 2014-11-30 instead of 2014-12-01.

/**
* 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 );

$last_day = date ( ‘t’ , strtotime ( «$y-$m-1» ));
if ( $d > $last_day )
<
$d = $last_day ;
>

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

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»);

Читать еще:  Php datetime сравнение

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.

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?

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.

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.

**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.

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:

= date_create ( «2017-12-31T23:59:59.300» );
$objIntervalo = new DateInterval ( «PT0S» );
$objIntervalo -> f = 0.600 ;
$objDataHora = date_add ( $objDataHora , $objIntervalo );
$strDataHora = date_format ( $objDataHora , «Y-m-dTH:i:s.v» );
?>

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

= date_create ( «2017-12-31T23:59:59.300» );
$objIntervalo = new DateInterval ( «PT0S» );
$objIntervalo -> f = 0.800 ;
$objDataHora = date_add ( $objDataHora , $objIntervalo );
$strDataHora = date_format ( $objDataHora , «Y-m-dTH:i:s.v» );
?>

$strDataHora is correct: «2018-01-01T00:00:00.100»

= date_create ( «2017-12-31T23:59:59.300» );
$objIntervalo = new DateInterval ( «PT0S» );
$objIntervalo -> f = 0.700 ;
$objDataHora = date_add ( $objDataHora , $objIntervalo );
$strDataHora = date_format ( $objDataHora , «Y-m-dTH: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):

Ссылка на основную публикацию
Adblock
detector