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粉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.