Класс DateInterval

(PHP 5 >= 5.3.0)

Введение

Представление интервалов дат.

Интервалы дат хранятся либо определенном фиксированном времени (в годах, месяцах, днях, часах и т.д.) или относительной строке времени, формат который поддерживает DateTime конструктор.

Обзор классов

DateInterval {
/* Свойства */
public integer $y ;
public integer $m ;
public integer $d ;
public integer $h ;
public integer $i ;
public integer $s ;
public integer $invert ;
public mixed $days ;
/* Методы */
public __construct ( string $interval_spec )
public static DateInterval createFromDateString ( string $time )
public string format ( string $format )
}

Свойства

y

Количество лет.

m

Количество месяцев.

d

Количество дней.

h

Количество часов.

i

Количество минут.

s

Количество секунд.

invert

Принимает 1, если интервал представляет отрицательный период времени и 0 в противном случае. См. DateInterval::format().

days

Если объект DateInterval создан методом DateTime::diff(), то это суммрное число дней между начальной и конечной датами. В противном случае days примет значение FALSE.

Содержание

Коментарии

Автор:
If you want to reverse a date interval use array_reverse and iterator_to_array. I've found using invert to be unreliable.

<?php
$start_date 
date_create("2021-01-01");
$end_date   date_create("2021-01-05"); // If you want to include this date, add 1 day

$interval DateInterval::createFromDateString('1 day');
$daterange = new DatePeriod($start_date$interval ,$end_date);

function 
show_dates ($dr) {
    foreach(
$dr as $date1){
        echo 
$date1->format('Y-m-d').'<br>';
    }
}
 
show_dates ($daterange);
   
echo 
'<br>';

// reverse the array

$daterange array_reverse(iterator_to_array($daterange));

show_dates ($daterange);
           
?>

Gives 
 2021-01-01
 2021-01-02
 2021-01-03
 2021-01-04

 2021-01-04
 2021-01-03
 2021-01-02
 2021-01-01
2022-12-04 06:12:17
http://php5.kiev.ua/manual/ru/class.dateinterval.html
More simple example i use to add or subtract.

<?php
$Datetime 
= new Datetime('NOW', new DateTimeZone('America/Bahia'));
$Datetime->add(DateInterval::createFromDateString('2 day'));

echo 
$Datetime->format("Y-m-d H:i:s");
?>
2024-01-18 17:56:00
http://php5.kiev.ua/manual/ru/class.dateinterval.html
There is a handy way to compare intervals by adding them to 0 dates and comparing dates instead

<?php

function compare(DateInterval $firstDateInterval $second): int
{
   
$firstDate = (new DateTime())->setTimestamp(0)->add($first);
   
$secondDate = (new DateTime())->setTimestamp(0)->add($second);

    return 
$firstDate <=> $secondDate;
}

echo 
compare(new DateInterval('P2D'), new DateInterval('PT48H')) . PHP_EOL;
echo 
compare(DateInterval::createFromDateString('2 days'), DateInterval::createFromDateString('48 hours')) . PHP_EOL;
echo 
compare(DateInterval::createFromDateString('2 days'), DateInterval::createFromDateString('49 hours')) . PHP_EOL;
echo 
compare(DateInterval::createFromDateString('2 days'), DateInterval::createFromDateString('47 hours')) . PHP_EOL;

?>

Outputs:
0
0
-1
1
2024-08-01 17:58:35
http://php5.kiev.ua/manual/ru/class.dateinterval.html
Subtracting months may not work as you might expect. 
Code shows how subtracting 2 months from consecutive days produces potentially unexpected results. 

<?php
$origin 
date_create('2025-01-31T00:00:00');
$target date_create('2024-11-26T00:00:00');

$interval date_diff($origin$target);
echo 
"interval total days: ".$interval->format('%a days');

echo 
"interval object years: ".$interval->format('%y years');
echo 
"interval object months: ".$interval->format('%m months');
echo 
"interval object days: ".$interval->format('%d days');

// create 3 dates that are consecutive, but in two months
$d1 date_create('2025-01-31T00:00:00');
$d2 date_create('2025-02-01T00:00:00');
$d3 date_create('2025-02-02T00:00:00');

// add (negative) interval object to each date
$d1->add($interval);
$d2->add($interval);
$d3->add($interval);

echo 
"Add (negative) interval object to each date. Non-consecutive results: ";
echo(
$d1->format("Y-m-d\TH:i:s"));
echo(
$d2->format("Y-m-d\TH:i:s"));
echo(
$d3->format("Y-m-d\TH:i:s"));

// reset dates
$d1 date_create('2025-01-31T00:00:00');
$d2 date_create('2025-02-01T00:00:00');
$d3 date_create('2025-02-02T00:00:00');

// Use same dates, but subtract total number of days instead of adding interval object: ";
$d1->sub(new DateInterval('P'.$interval->format('%a').'D'));
$d2->sub(new DateInterval('P'.$interval->format('%a').'D'));
$d3->sub(new DateInterval('P'.$interval->format('%a').'D'));

echo 
"Use same dates, but subtract total number of days instead of adding interval object. Results (consecutive): ";
echo(
$d1->format("Y-m-d\TH:i:s"));
echo(
$d2->format("Y-m-d\TH:i:s"));
echo(
$d3->format("Y-m-d\TH:i:s"));

$d1 date_create('2025-01-31T00:00:00');
$d2 date_create('2025-02-01T00:00:00');
$d3 date_create('2025-02-02T00:00:00');

// do month separately for 2025-02-01T00:00:00
echo "Do month separately (interesting): ";

echo (
'Subtract '$interval->format('%m').' months (might not expect this):');
echo (
'Jan 31 - 2 months (61 days = Dec, 31 days + Nov, 30 days) ==> Dec 1');
echo (
'Feb 1  - 2 months (62 days = Dec, 31 days + Jan, 31 days) ==> Dec 1');
$d1->sub(new DateInterval('P'.$interval->format('%m').'M'));
echo 
$d1->format("Y-m-d\TH:i:s");
$d2->sub(new DateInterval('P'.$interval->format('%m').'M'));
echo 
$d2->format("Y-m-d\TH:i:s");
$d3->sub(new DateInterval('P'.$interval->format('%m').'M'));
echo 
$d3->format("Y-m-d\TH:i:s");
?>

Output: 

interval total days: 66 days
interval object years: 0 years
interval object months: 2 months
interval object days: 5 days

create 3 dates that are consecutive, but in two months:
$d1 = 2025-01-31T00:00:00
$d2 = 2025-02-01T00:00:00
$d3 = 2025-02-02T00:00:00

Add (negative) interval object to each date. Non-consecutive results:
2024-11-26T00:00:00
2024-11-26T00:00:00
2024-11-27T00:00:00

Use same dates, but subtract total number of days instead of adding interval object. Results (consecutive):
2024-11-26T00:00:00
2024-11-27T00:00:00
2024-11-28T00:00:00

Do month separately (interesting):

Subtract 2 months (might not expect this):
Jan 31 - 2 months (61 days = Dec, 31 days + Nov, 30 days) ==> Dec 1
Feb 1 - 2 months (62 days = Dec, 31 days + Jan, 31 days) ==> Dec 1
2024-12-01T00:00:00
2024-12-01T00:00:00
2024-12-02T00:00:00
2025-02-03 20:19:42
http://php5.kiev.ua/manual/ru/class.dateinterval.html

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