搜索

首页  >  问答  >  正文

如何在夏令时调整期间计算日期差异(用于计算班次的函数)?

我有以下的函数用于确定给定日期上的哪个班次在工作。

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];
    }

它的调用方式如下:

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

如果我使用两个不跨越夏令时的日期,它似乎工作正常。例如,3/14/2023和6/22/23返回1(正确的)。但是如果我跨越夏令时发生的那一天,比如3/10/23和6/22/23,它返回4,这是错误的班次。

我该如何使它在不担心夏令时的情况下工作?

P粉919464207P粉919464207444 天前520

全部回复(1)我来回复

  • P粉323224129

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

    这是因为您的计算是基于一天有一定秒数而不是“天数”。我敢打赌,在大多数时区中,但不是所有时区,这会使时间稍微变动,以至于越过边界并改变转换数字。我还敢打赌,@aaronfc所在的时区不会这样,或者他的默认时区设置为UTC或其他静态偏移量。

    DateTime库可以可靠地计算:

    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')
    );
    

    输出:

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

    我还建议将explode(',', $sequence)移出函数,这样函数就不需要知道如何解码任意字符串。

    回复
    0
  • 取消回复