Ankündigung

Einklappen
Keine Ankündigung bisher.

Zeitzonenvergleich DateTime

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • #16
    Eine Menge an Informationen und interssanter Ansätze fireweasel .
    Achtung: kleine Textwand als echo -

    Festzustellen, ob zwei Zeitzonen mit unterschiedlichen Bezeichnern (z.B. America/Havana und Cuba) praktisch für PHP die selbe Zeitzone sind, soweit wollte ich gar nicht gehen.
    Praktisch die selbe Zeitzone bedeutet für mich das alle erdenklichen Rechenoperationen mit DateTime zu allen möglichen Zeiten für beide Zeitzonen immer identische Ergebnisse liefern.
    Ich stimme dir zu, das geht wohl nur mit Hilfe der Transitions-Liste. Hier mein Versuch:
    PHP-Code:
    function isSameTimeZone(DateTimeZone $tz1,DateTimeZone $tz2){
      
    $wTime date_create("2000-1-1");
      if(
    $tz1->getOffset($wTime) !== $tz2->getOffset($wTime)) return false;
      
    $sTime date_create("2000-6-1");
      if(
    $tz1->getOffset($sTime) !== $tz2->getOffset($sTime)) return false;
      return (
    $tz1->getTransitions() === $tz2->getTransitions());
    }

    $data = [
      [
    "Europe/Berlin","Europe/Amsterdam"],
      [
    "Europe/Berlin","Europe/Paris"],
      [
    "Europe/Monaco","Europe/Paris"],

      [
    "Europe/Berlin","Europe/Berlin"],
      [
    "Europe/San_Marino","Europe/Rome"],
      [
    "Europe/Vatican","Europe/Rome"],
      [
    "America/Havana","Cuba"],

    ];
    foreach(
    $data as $cmpData){
      
    $tz0 = new DateTimeZone($cmpData[0]);
      
    $tz1 = new DateTimeZone($cmpData[1]);
      
    $cmp isSameTimeZone($tz0$tz1);
      echo 
    $cmpData[0].($cmp " == " " <> "). $cmpData[1]."<br>\n";

    Ergebnis:
    Europe/Berlin <> Europe/Amsterdam
    Europe/Berlin <> Europe/Paris
    Europe/Monaco <> Europe/Paris
    Europe/Berlin == Europe/Berlin
    Europe/San_Marino == Europe/Rome
    Europe/Vatican == Europe/Rome
    America/Havana == Cuba

    Nun nochmal zurück zur Problematik bei einem Unit-Test.
    Bei einen solchen Test kenne ich den Wert der als Resultat erwartet wird. Wenn das Resultat ein Objekt oder gar ein Array aus Objekten ist, kann nicht mit === verglichen werden. Die Empfehlung
    Deswegen vergleicht der vorsichtige PHP-Schrauber niemals mit zu wenigen Gleichheitszeichen!
    gilt für skalare Variablen, nicht aber für Objekte. Variablen die Objekte enhalten mit === zu vergleichen führt nur zum Erfolg wenn die Variablen die selbe Instanz des Objektes enthalten. Den Erwartungswert welchen ich mit dem Resultat vergleichen möchte kann aber nur eine andere Instanz des Objektes sein. Dafür ist json_encode oder besser noch serialisize für einen Unit-test genau das was ich brauche.
    Meine Überlegung geht in die Richtung für Objekte eine speziellen Vergleich in die Testklasse zu implementieren, um ein Zerpflücken der Objekte und ein Vergleich der Komponenten zu umgehen.

    Kommentar


    • #17
      Zitat von jspit Beitrag anzeigen
      Praktisch die selbe Zeitzone bedeutet für mich das alle erdenklichen Rechenoperationen mit DateTime zu allen möglichen Zeiten für beide Zeitzonen immer identische Ergebnisse liefern.
      Geht nicht, da sich Zeitzonen ändern. Beispiel https://www.zeitzonen.de/artikel/14/...zeitzonen.html

      Kommentar


      • #18
        Zitat von Blar Beitrag anzeigen
        Geht nicht, da sich Zeitzonen ändern. Beispiel https://www.zeitzonen.de/artikel/14/...zeitzonen.html
        Verstehe den Einwand nicht ganz.
        Wenn von Zeitzonen in Zusammenhang mit PHP die Rede ist ist eine solche Zeitzonendefinition wie z.B. "Europe/Moscow" eindeutig.
        Und selbstverständlich können neue Zeitzonendefinitionen notwendig werden und sich auch der Zeitzonenoffset (die Differenz zur UTC-Zeit) sich im Verlauf der Zeit für eine PHP-Zeitzone ändern.
        Die Zeitzonenproblematik für PHP umzusetzen ist keine triviale Aufgabe. Größtenteils funktioniert das jedoch recht gut:

        Bediene mich dazu mal des verlinkten Zitates für ein Beispiel:
        - bis zum Herbst 2011 gibt es Sommer/Winterzeit in Russland
        - ab Herbst 2011 wird die Sommerzeit in Russland abgeschafft und die bleiben die Uhren permanent auf "Sommerzeit" (UTC +4 Stunden)
        - ab dem 26.10.2014 bleiben die Uhren permanent (UTC +3 Stunden)

        PHP-Code:
        $tz=new DateTimeZone("Europe/Moscow");
        $start = new DateTime("2010-01-01");
        $end = new DateTime("2017-01-01");
        for(; 
        $start<=$end$start->modify("+ 6 Month")){

          
        $offset $tz->getOffset($start)/60/60;
          echo 
        $start->format("Y-m-d"), " Offset: ",$offset,"<br>\n";

        Resultat:
        2010-01-01 Offset: 3
        2010-07-01 Offset: 4
        2011-01-01 Offset: 3
        2011-07-01 Offset: 4
        2012-01-01 Offset: 4
        2012-07-01 Offset: 4
        2013-01-01 Offset: 4
        2013-07-01 Offset: 4
        2014-01-01 Offset: 4
        2014-07-01 Offset: 4
        2015-01-01 Offset: 3
        2015-07-01 Offset: 3
        2016-01-01 Offset: 3
        2016-07-01 Offset: 3
        2017-01-01 Offset: 3

        LG jspit


        Kommentar


        • #19
          Da sich z.B. das Offset der Zeitzone Europe/Moscow ändert, kommt vor der Festlegung eine andere Zeit raus, als nach der Festlegung.

          Wenn im Jahr 2012 eine Zeitpunkt aus dem Jahr 2019 von der Zeitzone UTC in Europe/Moscow umgerechnet wurde, so wurde die ganzjährige Sommerzeit für die Umrechnung verwendet, da aber im Jahr 2014 die ganzjährige Winterzeit eingeführt wurde, würde die gleiche Umrechnung für den selben Zeitpunkt im Jahr 2019 der im Jahr 2015 berechnet zu einem anderen Ergebnis führen, da zwar die Zeitzone den selben Namen, aber ein anderes Offset verwendet.

          Darum nehme ich an, dass die Namen der Zeitzonen nicht unbedingt vergleichbar sind, da diese nicht für jeden Zeitpunkt in der Zukunft zum gleichen Ergebnis führen, je nachdem wann die Berechnung durchgeführt wird und welche Änderungen vorgenommen werden, die nicht absehbar sind.

          Evtl. kann mich jemand der mehr Ahnung von Zeitzonen hat, hier korrigieren, ob ich hier etwas falsches annehme.

          Kommentar


          • #20
            Ich habe versucht ein Beispiel für meine Aussage zu erstellen, die nachvollziehbar ist:

            Code:
            docker run -it --rm debian:8
            apt update
            apt install --yes php5-cli
            
            php -r '$dateTime = new DateTime("2019-03-24 13:37:42", new DateTimeZone("Asia/Gaza")); $dateTime->setTimeZone(new DateTimeZone("UTC")); var_dump($dateTime->format("Y-m-d H:i:s"));'
            
            string(19) "2019-03-24 11:37:42"
            Code:
            apt install --yes --force-yes tzdata=2018e-0+deb8u1
            php -r '$dateTime = new DateTime("2019-03-24 13:37:42", new DateTimeZone("Asia/Gaza")); $dateTime->setTimeZone(new DateTimeZone("UTC")); var_dump($dateTime->format("Y-m-d H:i:s"));'
            
            string(19) "2019-03-24 10:37:42"
            Unter https://metadata.ftp-master.debian.o...b9u1_changelog ist nachzulesen, dass sich dass sich durch das Paket tzdata in Version 2019a-0+* die Änderung des Offsets von Palestina von 2019-03-23 auf 2019-03-30 verschoben wurde.

            Ist die Zeitzone somit anhand des Namens vergleichbar? Es werden ja andere Ergebnisse geliefert.

            Kommentar


            • #21
              Das ist die Frage, ob man Zeitzonen oder Offsets vergleichen möchte. Eine Zeitzone kann unterschiedliche Offsets liefern. Und zu einem Offset können unterschiedliche Zeitzonen gehören.

              Das ist etwa so wie eine Wettervorhersage. Nehmen wir an es gibt die Funktion wettervorhersage($ort, $datum). wettervorhersage(berlin, 2. august) liefert „sonnig“. wettervorhersage(paris, 2. august) liefert „regen“. morgen ruft man das gleiche nochmal auf und plötzlich erhält man in beiden Fällen „wolkig“. Ist das Wetter gleich? Im Moment, ja. Ist das Ergebnis am nächsten Tag immer noch gleich? Man weiß es nicht. Kann sein, kann auch nicht sein. Was man aber definitiv sagen kann „sonnig“ ist immer „sonnig“ und „wolkig“ ist immer „wolkig“, sowie Berlin immer Berlin ist.

              Bei Zeitzonen kann man nicht sagen, ob sie in 10 Jahren den gleichen Offset liefern wie heute. Was man aber definitiv sagen kann, ein Offset +2 Stunden ist immer Offset +2 Stunden. Und die Zeitzone Europe/Berlin ist immer die Zeitzone Europe/Berlin, mit welchem Offset auch immer.

              Kommentar


              • #22
                Ja, in die Zukunft kann niemand schauen. Auch PHP nicht .
                Lasse ich obiges Skript mit der Zeitzone "Europe/Berlin" von 2019 bis 2023 laufen erhalte ich auch für Juni 2022 einen Offset von 2 Stunden (Sommerzeit!).
                Vermutlich falsch geraten, denn das EU-Parlament hat ja schon ein Ende der Zeitumstellung im Jahr 2021 befürwortet. Das wird noch lustig, denn wenn man den Medienberichten trauen kann:
                Nach dem Willen des Europaparlaments soll jeder Mitgliedsstaat selbst entscheiden können, ob er in zwei Jahren eine dauerhafte Winter- oder Sommerzeit einführen will. Für diejenigen Staaten, die sich für die Winterzeit entscheiden, stünde die letzte Zeitumstellung demnach im Oktober 2021 an.
                Theoretisch denkbar, das die Deutschen wenn sie 2022 dann nach Amsterdam oder Wien fahren ihre Uhren umstellen müssen. Umgekehrt ebenso.

                Was bedeutet das für PHP?
                Wenn der Beschluss feststeht, schnellstmöglich PHP bzw. die betreffenden Komponenten aktualisieren, sonst wird mit falschen Zeiten nach der Umstellung gearbeitet.
                Und kontrollieren, ob auch überall die richtige PHP-Zeitzoneneinstellung benutzt wird.

                Kommentar

                Lädt...
                X