3

I am trying to retrieve the number of days for a PHP interval. When I run the following piece of code on http://sandbox.onlinephpfunctions.com/:

$duration = new \DateInterval('P1Y');
echo $duration->format('%a');
echo "Done";

I get:

(unknown)Done

What am I doing wrong?

Jérôme Verstrynge
  • 57,710
  • 92
  • 283
  • 453
  • From [docs](http://php.net/manual/en/dateinterval.format.php): "a Total number of days as a result of a DateTime::diff() or (unknown) otherwise" – Álvaro González Feb 20 '17 at 09:57
  • 2
    Practically speaking… You don't need to go through a `DateInterval` to know that 1 year consists of 365 days. *Unless it doesn't*, in which case you need a concrete `DateTime` in the first place to figure out whether you're talking about a leap year or not. Soooo… not quite sure where this would be practically applicable in the first place. – deceze Feb 20 '17 at 10:52

4 Answers4

8

The '%a' will return the number of days only when you take a time difference otherwise it will return unknown.
You can use '%d' to get the days but it will also return 0 in the case of new \DateInterval('P1Y') as it does not convert years to days.
One easy way to get the number of days is to create a DateTime at zero time, add the interval to it, and then get the resulting timestamp:

<?php
$duration = new \DateInterval('P1Y');
$intervalInSeconds = (new DateTime())->setTimeStamp(0)->add($duration)->getTimeStamp();
$intervalInDays = $intervalInSeconds/86400; 
echo $intervalInDays;
echo " Done";
Danial Aftab
  • 129
  • 4
  • This one answers the question -in an alternative way-, but you didn't really point out why `DateInterval->format()` doesn't working... – Gergely Lukacsy Feb 20 '17 at 10:12
  • as the [manual](http://php.net/manual/en/dateinterval.format.php) suggests '%a' will only return number of days when called on the result of a DateTime::diff(). – Danial Aftab Feb 20 '17 at 11:14
8

The problem is here:

$duration->format('%a');

As the manual says, "Total number of days as a result of a DateTime::diff() or (unknown) otherwise".

You need a valid dateInterval object returned by DateTime's diff() method to make the "a" parameter work with DateInterval::format() function:

$now = new DateTime(date('Y-m-d H:i:s'));
$duration = (new DateTime("+1 year"))->diff($now);
echo $duration->format('%a');

Looks like if the DateInterval object is not created by DateTime::diff(), it won't work. Hope it helps.

Gergely Lukacsy
  • 2,881
  • 2
  • 23
  • 28
1

You have to create the interval with real dates:

<?php
$interval = date_diff(new DateTime, new DateTime('+1 year'));
echo $interval->format('%a'), PHP_EOL; // 365
jawira
  • 3,668
  • 2
  • 17
  • 27
0

if you want something aware of the year or month context, use this, february will return 28 days, leap years will have their additional day

function interval2days($day, $interval) {
    $date = clone $day;
    $start = $date->getTimeStamp();
    $end = $date->add($interval)->getTimeStamp();
    return ($end-$start)/86400;
}
Gaby_64
  • 77
  • 7