DateTime::sub

date_sub

(PHP 5 >= 5.3.0, PHP 7)

DateTime::sub -- date_sub Вычитает заданное количество дней, месяцев, лет, часов, минут и секунд из времени объекта DateTime

Описание

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

public DateTime DateTime::sub ( DateInterval $interval )

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

DateTime date_sub ( DateTime $object , DateInterval $interval )

Вычитает из времени объекта DateTime заданный интервал DateInterval.

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

object

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

interval

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

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

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

Примеры

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

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

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

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

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

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

2000-01-10

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

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

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

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

2000-01-19 13:59:30
1992-08-15 19:56:58

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

<?php
$date 
= new DateTime('2001-04-30');
$interval = new DateInterval('P1M');

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

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

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

2001-03-30
2001-03-02

Примечания

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

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

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

Коментарии

If you use diff() after sub(), the effects of the sub() will be repeated on the date object.

It doesn't matter if the object is the one diffed or doing the diffing (i.e. which object you call diff() from).

<?php
$today 
= new DateTime();
$newdate = new DateTime();

print_r($newdate);
$newdate->sub(new DateInterval("PT1S"));
print_r($newdate);
$s $newdate->diff($today);
print_r($newdate);
$s $today->diff($newdate);
print_r($newdate);
$s $today->diff($newdate);
print_r($newdate);
?>

Prints:

DateTime Object
(
    [date] => 2010-11-30 18:43:48
    [timezone_type] => 3
    [timezone] => America/Los_Angeles
)
DateTime Object
(
    [date] => 2010-11-30 18:43:47
    [timezone_type] => 3
    [timezone] => America/Los_Angeles
)
DateTime Object
(
    [date] => 2010-11-30 18:43:46
    [timezone_type] => 3
    [timezone] => America/Los_Angeles
)
DateTime Object
(
    [date] => 2010-11-30 18:43:45
    [timezone_type] => 3
    [timezone] => America/Los_Angeles
)
DateTime Object
(
    [date] => 2010-11-30 18:43:44
    [timezone_type] => 3
    [timezone] => America/Los_Angeles
)

Note that using add() instead of sub() does NOT have the same effect.

This is particularly undesirable -- in this example you make a datetime, use sub() to make it a relative time in the past, and then date->diff() to confirm the difference. But the diff() inadvertendly makes the difference 2x.
2010-11-30 20:53:18
http://php5.kiev.ua/manual/ru/datetime.sub.html
Автор:
Note that the sub() and add() 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:15:05
http://php5.kiev.ua/manual/ru/datetime.sub.html
Автор:
When trying to pass daylight saving state change time, sub() works incorrectly.

$t = new DateTime( '2014-03-30 02:00:00' );
$t->add( new DateInterval('PT1H') );
echo $->format('Y-m-d H:i:s');

output will be: '2014-03-30 04:00:00'.

 Well, it's ok because at 3:00 a.m. daylight saving time begins in my country, so after  02:59:59 must be 04:00:00.

But if I try to subtract time:

$t = new DateTime( '2014-03-30 04:00:00' );
$t->sub( new DateInterval('PT1H') );
echo $->format('Y-m-d H:i:s');

output will be: '2014-03-30 04:00:00'.

Yes, completely the same, not '2014-03-30 02:00:00' as it should be.
2014-04-05 22:25:11
http://php5.kiev.ua/manual/ru/datetime.sub.html
As noted above when subtracting months, results can be suspect. I needed to create an array of end of month dates for 6 months starting at Oct and going back.  Using:
<?php

//Instantiate array
$dateset = [];

//Create new date object
$date = new DateTime('2018-10-31);
//Add to array
$dateset[] = $date->format('
Y-m-d');

//Go back 5 months
$nbr = 6;
for($i = 1; $i < $nbr; $i++){
    $date->sub(new \DateInterval('
P1M'));
    $dateset[] = $date->format('
Y-m-d');
}
?>

Results in:

array:6 [▼
  0 => "2018-10-31"
  1 => "2018-10-01"
  2 => "2018-09-01"
  3 => "2018-08-01"
  4 => "2018-07-01"
  5 => "2018-06-01"
]

However, using ->modify("last day of last month") accurately gives month ending dates:

<?php

//Instantiate array
$dateset = [];

//Create new date object
$date = new \DateTime('
2018-10-31);
//Add to array
$dateset[] = $date->format('Y-m-d');

//Go back 5 months
$nbr 6;
for(
$i 1$i $nbr$i++){
   
$date->modify('last day of last month');
   
$dateset[] = $date->format('Y-m-d');
}
?>

Results in:

array:6 [▼
  0 => "2018-10-31"
  1 => "2018-09-30"
  2 => "2018-08-31"
  3 => "2018-07-31"
  4 => "2018-06-30"
  5 => "2018-05-31"
]
2018-12-26 20:06:13
http://php5.kiev.ua/manual/ru/datetime.sub.html
CAUTION: Never subtract months from the current day, always do so from the 1st of the month. 
Let us imagine that it is May 31, 2019, so 2019-05-31, the function will not give 2019-04-31 because April is not 31 days old but 30, it will create problems.
2019-10-31 17:42:57
http://php5.kiev.ua/manual/ru/datetime.sub.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:58:00
http://php5.kiev.ua/manual/ru/datetime.sub.html

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