Ankündigung

Einklappen
Keine Ankündigung bisher.

DateTime Timestamp falsche Uhrzeit

Einklappen

Neue Werbung 2019

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

  • DateTime Timestamp falsche Uhrzeit

    Hallo Leute,

    habe heute was merkwürdiges gefunden: Wenn man ein neues DateTime Objekt von einem Timestamp anlegt, welcher selber von einem DateTime Objekt kommt, dann zeigt es mir die falsche Uhrzeit an. Hab das schon mit verschiedenen PHP Versionen getestet. Kommt in etwa immer das selbe dabei heraus.

    Gegeben sei folgendes einfaches Code-Beispiel, welches das Problem gut beschreibt / zeigt:
    PHP-Code:
    $dt = new \DateTime();
    $dt2 = \DateTime::createFromFormat('U'$dt->getTimestamp());
    echo 
    '<p>dt2=' $dt2->format('d.m.Y H:i:s') . '</p>' . \PHP_EOL
    Wie ich das umgehen kann, weiß ich. Würde mich aber trotzdem mal interessieren, warum mit einem Timestamp plötzlich so eine Differenz aufkommen kann. Liegt das vielleicht an Schaltjahren oder der Zeitzoen? In meinen Fall ist immer dieselbe Zeitzone. Das kann man also erstmal als Ursache ausschließen, oder?!
    In der Doku zu DateTime::getTimestamp() steht, dass es der UNIX Timestamp ist, also die Zeit in Sekunden seit irgendwann um 1970, also seitdem Jahr 0 in der Linux Zeitrechnung.
    Umgehen kann ich das mit einer formatierten Ausgabe des ISO Zeitstrings.

    Über Aufklärung diesbezüglich würde ich mich freuen

    Falls es im falschen Board ist, dann bitte dementsprechend verschieben. Als Anfänger Frage hätte ich das nicht unbedingt eingeordnet...


    MFG

    derwunner

  • #2
    Bei createFromFormat() nimmt er als Zeitzone UTC.

    PHP-Code:
    var_dump($dt->format('c')); // string(25) "2018-06-21T13:45:01+02:00"
    var_dump($dt2->format('c')); // string(25) "2018-06-21T11:45:01+00:00" 
    PHP-Code:
    $dt2->setTimezone(new \DateTimeZone('Europe/Berlin'));
    var_dump($dt2->format('c')); // string(25) "2018-06-21T13:45:01+02:00" 

    Kommentar


    • #3
      Hat nix mit createFromFormat() zu tun. DateTime liefert es immer als UTC wenn es einen Timestamp angeboten bekommt. So z.B. auch bei
      PHP-Code:
      $dt3 = new DateTime("@".$dt->getTimestamp()); 
      So zu verfahren finde ich blöd. Mache die Korrektur in meiner DateTime-Erweiterungsklasse automatisch.

      Kommentar


      • #4
        Ein Timestamp ist von der Definition aus auch immer UTC. Man muss es also in UTC Parsen und kann dann die Zeitzone dazu addieren oder abziehen.

        Kommentar


        • #5
          Klar ist ein Timestamp immer UTC. Das gute alte Date nimmt doch auch einen Timestamp und liefert die richtige Zeit entsprechend der Zeitzone.
          PHP-Code:
          date_default_timezone_set('Europe/Berlin');

          $timestamp time();
          $date date("Y-m-d H:i:s",$timestamp);

          $datetime = new DateTime("@".$timestamp);

          $dt dt::create($timestamp);

          debug::write($date$datetime,$dt); 
          Ausgabe:
          0 string(19) ASCII "2018-06-21 22:21:35"
          1 object(DateTime)(3) DateTime::__set_state(array( 'date' => "2018-06-21 20:21:35.000000", 'timezone_type' => 1, 'timezone' => "+00:00", ))
          2 object(dt)(5) dt::__set_state(array( 'errorInfo' => '', 'lastMatchRegEx' => false, 'date' => "2018-06-21 22:21:35.000000", 'timezone_type' => 3, 'timezone' => "Europe/Berlin", ))
          Nur DateTime liefert die Zeit in der falschen Zeitzone. Dies muss für diesen speziellen Fall mit ->setTimezone(new \DateTimeZone('Europe/Berlin')); korrigiert werden (wie es hellbringer #2 schon gezeigt hat).
          dt::create erkennt im obigen Beispiel am Datentyp (integer oder float) das hier ein Timestamp vorliegt.

          Kommentar


          • #6
            Zitat von derwunner Beitrag anzeigen
            Hallo Leute,

            ...
            PHP-Code:
            $dt = new \DateTime();
            $dt2 = \DateTime::..... 
            ..
            Scheibe niemals Klassen mit so einen Käse wie \ <- dafür kommst Du in die Hölle!
            Das kannst du alles voher wegdeklarieren.
            1. ist das vollkommen unnötig.
            2. bringt das nur Probleme.

            Dann noch eine Frage. Warum zur Hölle rufst Du eine Klassenmethode statisch auf?
            bitcoin.de <- Meine Freelancerwährung

            Kommentar


            • #7
              Zitat von Alpha Beitrag anzeigen
              Scheibe niemals Klassen mit so einen Käse wie \ <- dafür kommst Du in die Hölle!
              Das kannst du alles voher wegdeklarieren.
              1. ist das vollkommen unnötig.
              2. bringt das nur Probleme.
              1. Nicht, wenn er sich an der Stelle in einem benutzerdefinierten Namespace befindet
              2. In welcher Form?

              Competence-Center -> Enjoy the Informatrix
              PHProcks!Einsteiger freundliche TutorialsPreComposed Packages

              Kommentar


              • #8
                PHP-Code:
                \DateTime::createFromFormat
                Zitat von Alpha Beitrag anzeigen
                Dann noch eine Frage. Warum zur Hölle rufst Du eine Klassenmethode statisch auf?
                http://php.net/manual/de/datetime.cr...ormat-examples
                Das hat er vermutlich aus der Doku

                The string "()()" is not palindrom but the String "())(" is.

                Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
                PHP.de Wissenssammlung | Kein Support per PN

                Kommentar


                • #9
                  Zitat von Alpha Beitrag anzeigen

                  Scheibe niemals Klassen mit so einen Käse wie \ <- dafür kommst Du in die Hölle!
                  Das kannst du alles voher wegdeklarieren.
                  1. ist das vollkommen unnötig.
                  2. bringt das nur Probleme.
                  Der \ sagt doch nichts weiter als das sich die Klasse im globalen Namespace befindet. Eine Klasse aus dem globalen Namespace kann so immer aufgerufen werden und ist sogar besser und das macht auch keine Probleme.

                  Zitat von Alpha Beitrag anzeigen
                  Dann noch eine Frage. Warum zur Hölle rufst Du eine Klassenmethode statisch auf?
                  Weil noch kein Objekt da ist und die Methode \DateTime::createFromFormat erst eine Objektinstanz erstellt !

                  Kommentar


                  • #10
                    Zitat von Arne Drews Beitrag anzeigen
                    1. Nicht, wenn er sich an der Stelle in einem benutzerdefinierten Namespace befindet
                    2. In welcher Form?
                    use
                    oder
                    use as
                    bitcoin.de <- Meine Freelancerwährung

                    Kommentar


                    • #11
                      Ja, in Bezug auf "vorher definieren". Trotzdem bleibt de Frage, warum man für die genutzte Variante in de Hölle kommt und welche Probleme das bringt?!
                      Competence-Center -> Enjoy the Informatrix
                      PHProcks!Einsteiger freundliche TutorialsPreComposed Packages

                      Kommentar


                      • #12
                        Meiner Auffassung nach beschleunigt der Backslash den OP-Code, da so nicht erst überprüft werden muss, ob sich die Klasse im aktuellen Namespace befindet, vgl. auch https://veewee.github.io/blog/optimi...unction-calls/

                        Kommentar


                        • #13
                          Zitat von michga93 Beitrag anzeigen
                          Meiner Auffassung nach beschleunigt der Backslash den OP-Code, da so nicht erst überprüft werden muss, ob sich die Klasse im aktuellen Namespace befindet, vgl. auch https://veewee.github.io/blog/optimi...unction-calls/
                          Klingt nach Mikrooptimierung. Außerdem kann sich das bei zukünftigen PHP-Versionen ändern (so wie früher mal Single-Quotes schneller waren als Double-Quotes, sich das aber irgendwann mal umgekehrt hat). Wer in sowas Zeit und Energie steckt, der hat offenbar keine andere Arbeit zu tun. Oder er setzt die falschen Prioritäten.

                          Kommentar


                          • #14
                            Zitat von hellbringer Beitrag anzeigen

                            Klingt nach Mikrooptimierung. Außerdem kann sich das bei zukünftigen PHP-Versionen ändern (so wie früher mal Single-Quotes schneller waren als Double-Quotes, sich das aber irgendwann mal umgekehrt hat). Wer in sowas Zeit und Energie steckt, der hat offenbar keine andere Arbeit zu tun. Oder er setzt die falschen Prioritäten.
                            Bzgl. Der Mikrooptimierung gebe ich dir in jedem Fall recht. Ich bin auch selbst nur durch das Plugin PHP Inspections für PHPstorm darauf hingewiesen worden. Aber deshalb würde ich jetzt nicht meinen ganzen Code darauf anpassen, um Gottes Willen:P Allerdings achte ich bei neuen Projekten auf den Backslash, da es mMn. best practice ist und eben keine Nachteile mit sich bringt

                            Kommentar


                            • #15
                              Zitat von michga93 Beitrag anzeigen

                              Bzgl. Der Mikrooptimierung gebe ich dir in jedem Fall recht. Ich bin auch selbst nur durch das Plugin PHP Inspections für PHPstorm darauf hingewiesen worden. Aber deshalb würde ich jetzt nicht meinen ganzen Code darauf anpassen, um Gottes Willen:P Allerdings achte ich bei neuen Projekten auf den Backslash, da es mMn. best practice ist und eben keine Nachteile mit sich bringt
                              Jop, geht mir bzw. mache ich auch so. Bei neuen Projekten immer Backslash davor oder als use aus dem globalen Namespace einbinden. Letzteres habe ich aber wenn ich ehrlich bin noch nie gebraucht, einfach weil ich es mit Backslash davor schöner finde, so sieht man gleich an Codestelle XY, dass es sich hier um eine globale Klasse handelt.
                              Natürlich auch bei Verbesserungen / Updates in bestehenden Projekten schreibe ich dann den Backslash davor. Denn wenn man eh schon dabei ist, kann man das auch gleich machen, kostet außerdem nicht viel Zeit.

                              Ok danke für die Tipps, ich hab's jetzt verstanden

                              In der Zwischenzeit hatte ich einen Workaround mittels ISO Zeitstring gemacht. Mir ging es darum in der Session ein DateTime abspeichern zu können. Zeitzonen waren dabei egal, da auf das Skript eh nur deutsche Nutzer Zugriff haben.

                              Kommentar

                              Lädt...
                              X