I want to create a DatePeriod object with a negative DateInterval.
This creates a DatePeriod with the year increasing from today to 2016.
$this->S
This took a little digging. The only way I was able to get a negative DateInterval
was by doing this:
$interval = DateInterval::createFromDateString('-1 day');
However, there is a catch. DatePeriod
seems to not work for negative intervals. If you set the start date to be before the end date then it doesn't contain any dates at all and if you flip so that the start date is after the end date then it looks backwards indefinitely.
You're probably going to have to restructure your code to loop through the dates using DateTime::sub
with a positive DateInterval
or DateTime::add
with the negative one.
EDIT: note that this was inspired by khany's code above.
Here's a fully working script for my use-case, which is to display year+month strings from the current month going back N number of months. It should work with days or years as intervals and is tested with PHP version 5.3.3.
<?php
date_default_timezone_set('America/Los_Angeles');
$monthsBack=16;
$monthDateList = array();
$previousMonthDate = new DateTime();
for($monthInterval = 0; $monthInterval < $monthsBack; $monthInterval++) {
array_push($monthDateList, $previousMonthDate->format('Ym'));
$previousMonthDate->sub(new DateInterval("P1M"));
}
print_r($monthDateList) . "\n";
?>
The output is:
Array
(
[0] => 201705
[1] => 201704
[2] => 201703
[3] => 201702
[4] => 201701
[5] => 201612
[6] => 201611
[7] => 201610
[8] => 201609
[9] => 201608
[10] => 201607
[11] => 201606
[12] => 201605
[13] => 201604
[14] => 201603
[15] => 201602
)
According to comment by kevinpeno at 17-Mar-2011 07:47 on php.net's page about DateInterval::__construct(), you cannot directly create negative DateIntervals through the constructor:
new DateInterval('-P1Y'); // Exception "Unknown or bad format (-P1Y)"
Instead of this you are required to create a positive interval and explicitly set it's invert
property to 1
:
$di = new DateInterval('P1Y');
$di->invert = 1; // Proper negative date interval
Just checked the above code by myself, it's working exactly in this way.
I tried it myself and it isn't possible with DatePeriod
alone, but I think that makes sense: It just reflects the periods, that usually doesn't have any specific order and therefore cannot get reordered (it can be treated as a set).
The only way to retrieve the dates and sort it in reversed order, as far as I can see, is something like this
$result = array();
forech ($dateperiod as $date) {
array_push ($result, $data);
}
Update
$date = new DateTime('2016-06-06');
$i = new DateInterval('P1Y');
$now = new DateTime;
while ($date >= $now) {
echo $date->format('c') . PHP_EOL;
$date = $date->sub($i);
}
This extract worked for me:
$iDate = $endDate;
while($iDate >= $startDate) {
$dates[] = new DateTime($iDate->format('Y-m-d'));
$iDate->sub(new DateInterval("P1D"));
}
You can used sub http://php.net/manual/en/datetime.sub.php
Here is example
$startDate = new \DateTime('2018-01-08 13:54:06');
$startDate->sub(new \DateInterval('P1D'));