search

Home  >  Q&A  >  body text

How to calculate date difference (function used to calculate shifts) during daylight saving time adjustment?

I have the following function for determining which shift is working on a given date.

public static function getShift($date, $startDate, $sequence)
    {
        $daysDiff = floor((strtotime($date) - strtotime($startDate)) / (60 * 60 * 24));
        $sequenceArray = explode(',', $sequence);
        $key = ($daysDiff % count($sequenceArray)) + 1;
        return $sequenceArray[$key - 1];
    }

It is called as follows:

$shift = ShiftHelper::getShift($date, '3/14/2023', '1,2,3,4');

If I use two dates that don't span daylight saving time, it seems to work fine. For example, 3/14/2023 and 6/22/23 return 1 (correct). But if I span days where daylight saving time occurs, like 3/10/23 and 6/22/23, it returns 4, which is the wrong shift.

How do I make it work without worrying about daylight saving time?

P粉919464207P粉919464207444 days ago519

reply all(1)I'll reply

  • P粉323224129

    P粉3232241292023-09-16 12:53:26

    This is because your calculation is based on the number of seconds in a day rather than the "number of days". I'd bet that in most time zones, but not all, this would shift the times so slightly that it would cross the boundary and change the conversion numbers. I'd also bet that @aaronfc's timezone doesn't work like this, or his default timezone is set to UTC or some other static offset.

    DateTime library can reliably calculate:

    function getShift($date, $startDate, $sequence) {
        $epoch = DateTime::createFromFormat('m/d/Y', $startDate)->setTime(0,0,0);
        $cur   = DateTime::createFromFormat('m/d/Y', $date)->setTime(0,0,0);
        $daysDiff = date_diff($epoch, $cur)->days;
        
        $sequenceArray = explode(',', $sequence);
        $key = ($daysDiff % count($sequenceArray)) + 1;
        return $sequenceArray[$key - 1];
    }
    
    var_dump(
        getShift('6/22/2023', '3/14/2023', '1,2,3,4'),
        getShift('6/22/2023', '3/10/2023', '1,2,3,4')
    );
    

    Output:

    string(1) "1"
    string(1) "1"

    I also recommend moving explode(',', $sequence) out of the function so that the function doesn't need to know how to decode the arbitrary string.

    reply
    0
  • Cancelreply