0

I'm solving following task>

I have two dates - $start and $end and target year as $year.

dates are php DateTime objects, year is string.

add:dates comes acutaly from MySql field from this format 2017-02-01 15:00:00 ... add2: if end date is null, I use todays date ...

I need to figure out how many days are between these two dates for specific year.

Also I need to round it for whole days, even if one minute in day should be counted as whole day ...

I can solve it by many many following ifs.

Expected results for values I used in example are 2016 is 0 days 2017 is 31 days 2018 is 32 days 2019 is 0 days

But are there any elegant php functions which can help me with this ? What I did it seems to be wrong way and giving bad results - seems it counts full days only ...

Please see my code here >

<?php
$diff = True;
$start = DateTime::createFromFormat('Y-m-d H:i:s','2017-12-01 23:05:00');
$end = DateTime::createFromFormat('Y-m-d H:i:s','2017-12-03 00:05:00');
$year = '2017';

// start date
if ($start->format('Y')<$year)
{
    $newstart = new DateTime('first day of January '. $year);
}

if ($start->format('Y')==$year)
{
    $newstart = $start;
}

if ($start->format('Y')>$year)
{
    $result = 0;
    $diff = False;
}

// end date
if ($end->format('Y')>$year)
{
    $newend = new DateTime('last day of December '. $year);
}

if ($end->format('Y')==$year)
{
    $newend = $end;
}

if ($end->format('Y')<$year)
{
    $result = 0;
    $diff = False;
}               

// count if diff is applicable
if ($diff)
{
    $result  = $newend->diff($newstart)->format("%a");
}

echo $result;
?>
Jan Alexa
  • 5
  • 3
  • Not exactly a duplicate because of the rounding, but this could get you started https://stackoverflow.com/questions/15688775/php-find-difference-between-two-datetimes – kchason Feb 06 '18 at 11:47
  • *"But are there any elegant php functions which can help me with this ?"* -- read about [`DateTime::diff()`](http://php.net/manual/en/datetime.diff.php). It returns a [`DateInterval`](http://php.net/manual/en/class.dateinterval.php) object that contains the number of days (in `$days`) and by inspecting the values of `$h`, `$i` and `$s` you can tell if you have to increment it to round the result. You can also use [`min()`](http://php.net/manual/en/function.min.php) and [`max()`](http://php.net/manual/en/function.max.php) to crop the time interval to the desired year. – axiac Feb 06 '18 at 12:07
  • Thx a lot for your answer. As you can see I already used `DateTime:diff();` I rounded input so it is just date, ignoring time. What I wonder is it returns always one day less - like 2017-12-01 to 2017-12-05 are 5 days but it returns always 4. Maybe I missunderstood the term 'difference' but i need total number of days between these days include those days. Solution seems to be add +1 at the end of calculation ? – Jan Alexa Feb 06 '18 at 12:14
  • You mention `min()` and `max()`, seems this can avoid my stupid ifs, but I'm not able find out how to crop this interval, could you please please give me short example ? – Jan Alexa Feb 06 '18 at 12:20

2 Answers2

1

But are there any elegant php functions which can help me with this ?

Read about DateTime::diff(). It returns a DateInterval object that contains the number of days (in $days) and by inspecting the values of $h, $i and $s you can tell if you have to increment it to round the result. You can also use min() and max() to crop the time interval to the desired year.

function getDays(DateTimeInterface $start, DateTimeInterface $end, $year)
{
    // Extend the start date and end date to include the entire day
    $s = clone $start;            // Don't modify $start and $end, use duplicates
    $s->setTime(0, 0, 0);
    $e = clone $end;
    $e->setTime(0, 0, 0)->add(new DateInterval('P1D'));  // start of the next day

    // Crop the input interval to the desired year
    $s = min($s, new DateTime("$year-01-01 00:00:00"));
    $year ++;
    $e = max(new DateTime("$year-01-01 00:00:00"), $end);     // start of the next year

    if ($e <= $s) {
        // The input interval does not span across the desired year
        return 0;
    }

    // Compute the difference and return the number of days
    $diff = $e->diff($s);

    return $diff->days;
}
axiac
  • 68,258
  • 9
  • 99
  • 134
0
    $d1 = strtotime('2017-05-15');
    $d2 = strtotime('2017-05-31');
    $div = 24 * 3600;
    echo abs(($d2 - $d1) / $div); // 16 days

Just make sure and ONLY have the date part and you shouldn't have to deal with rounding.

Oliver Williams
  • 5,966
  • 7
  • 36
  • 78
  • Hi, thx for advice. What it doesn't reflect is need to specify year ... so for dates from various years it will not work, better say it will return total number of days between and not number of day in specified year. – Jan Alexa Feb 06 '18 at 12:05
  • Have you tried the code? It will certainly work for different years. I changed `$d1` to '2016-05-15' and got 381 days back - which is 365 + 16. You may have some problems with dates before 1970 though. As far as "number of days in specified year" - WHICH YEAR? That's another calculation. – Oliver Williams Feb 06 '18 at 12:11