Heim  >  Fragen und Antworten  >  Hauptteil

Wie berechnet man die Datumsdifferenz (Funktion zur Berechnung von Schichten) während der Sommerzeitumstellung?

Ich habe die folgende Funktion, um festzustellen, welche Schicht an einem bestimmten Datum arbeitet.

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

Es heißt wie folgt:

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

Wenn ich zwei Daten verwende, die nicht auf die Sommerzeit fallen, scheint es gut zu funktionieren. Beispielsweise geben 14.03.2023 und 22.06.23 1 zurück (richtig). Wenn ich jedoch Tage überspanne, an denen Sommerzeit ist, wie z. B. den 10.03.23 und den 22.06.23, wird 4 zurückgegeben, was die falsche Verschiebung ist.

Wie sorge ich dafür, dass es funktioniert, ohne mir Gedanken über die Sommerzeit machen zu müssen?

P粉919464207P粉919464207370 Tage vor471

Antworte allen(1)Ich werde antworten

  • 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)移出函数,这样函数就不需要知道如何解码任意字符串。

    Antwort
    0
  • StornierenAntwort