简体   繁体   中英

php DateTime diff - include both dates in range?

I have been using DateTime Diff (in php) to get various settings for pairs of dates - two formatted dates to display, a difference from the date to now (eg "start date was 3 months 2 days ago"), and a length between the two dates ("length is 2 months 3 days").

The problem is that DateTime Diff ignores one of the days so if the start is yesterday and the end is tomorrow, it gives 2 days whereas I want 3 because both dates should be included in the length. If it was just days, I could simply add 1 to the result, but I wanted to use the years/months/days results from the Diff and these are determined at construct.

The only way I have found to get the desired results is to create a DateTime for start and end (to get the formatted dates and the differences). Then take the end DateTime, add 1 day to it, then work out the length.

It's a bit clunky but there seems to be no way to tell DateTime Diff to include both start and end dates in the result.

DateTime encapsulates a specific moment in time. "yesterday" is not a moment but a time range. The same for "tomorrow" .

DateTime::diff() doesn't ignore anything; it just provides you the exact difference (in day, hours, minutes aso) between two moments in time.

If you want to get the diff between "tomorrow" and "yesterday" as "3 days" you can subtract the first second of "yesterday" from (one second after the last second of "tomorrow").

Like this:

// Always set the timezone of your DateTime objects to avoid troubles
$tz = new DateTimeZone('Europe/Bucharest');
// Some random time yesterday
$date1 = new DateTime('2016-07-08 21:30:15', $tz);
// Other random time tomorrow
$date2 = new DateTime('2016-07-10 12:34:56', $tz);

// Don't mess with $date1 and $date2;
// clone them and do whatever you want with the clones
$yesterday = clone $date1;
$yesterday->setTime(0, 0, 0);         // first second of yesterday (the midnight)
$tomorrow = clone $date2;
$tomorrow->setTime(23, 59, 59)               // last second of tomorrow
         ->add(new DateInterval('PT1S'));    // one second

// Get the difference; it is the number of days between and including $date1 and $date2
$diff = $tomorrow->diff($yesterday);

printf("There are %d days between %s and %s (including the start and end date).\n",
     $diff->days, $date1->format('Y-m-d'), $date2->format('Y-m-d')
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM