Nebula: Unix Timestamp oder doch mysql und alles so Hilfe!

moin, moin!

Bin grad die MySQL Doku date-and-time-functions durch,
und finde diese ganzen ADD_DATE und CURDATE und INTERVAL Sachen recht nett,
aber vor allem sehr verwirrend.

Alle MySQL Geeks versichern mir irgendwie,
dass diese Funktionen angeblich viel besser seien wenn man zum Beispiel
wissen möchte welche Einträge innerhalb der letzten 30 Tage entstanden sind,
und ich mit INTERVAL nur 30 DAYS angeben muss.

Dennoch ist mir das ganze recht unheimlich,
und hat einfach eine viel zu breite Masse an Befehlen
für eine so simple sache wie Daten.

Auch das DATE_FORMAT ist eine nette Sache,
aber auch wieder unnötig kompliziert.

#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-

Ich dachte mir am einfachsten ist immer noch der UNIX Timestamp.
Da kann ich ganz einfach vergleichen zwischen zwei UNIX Timestamps,
die entsprechenden Sekunden abziehen oder dazuzählen,
und das Ausgabeformat bestimmt man auch ganz einfach.
Ich bin und bleibe einfach ein Unix Timestamp Fan,
auch wenn die MySQL Geeks mich dafür schimpfen *g*

Bevor ich nun aber den UNIX Timestamp in einem VARCHAR Feld abspeichere,
dachte ich mir dass es dafür vielleicht ein eigenes Feld gibt in MySQL.

Dann könnte ich vielleicht auch mit NOW()  den aktuellen Timestamp reinbekommen.

Beim auslesen arbeite ich dann wieder mit Timestamp.

Extra noch eine zusätzliche Frage:
Ist Perl langsamer wenn es den UNIX Timestamp aus der DB bekommt,
und den pro Eintrag erst umrechnen muss,
oder ist es langsamer wenn MySQL die Umrechnung macht mit INTERVAL mal abziehen
und dann mit DATE_FORMAT als irgendwas selectieren?

Der Syntax von INTERVAL ist mir nämlich suspekt.
Die verwenden bei der Deutschen Doku einen komplett anderen als bei der Englischen.

MySQL Doku Deutsch:
***********************
Hier ist ein Beispiel, das Datums-Funktionen benutzt. Die unten
stehende Anfrage wählt alle Datensätze mit einem datum_spalte-Wert
innerhalb der letzten 30 Tage aus:

mysql> SELECT etwas FROM tabelle
           WHERE TO_DAYS(NOW()) - TO_DAYS(datum_spalte) <= 30;

MySQL Doku Englisch:
***********************
Here is an example that uses date functions. The following query
selects all records with a date_col value from within the last 30 days:

mysql> SELECT something FROM tbl_name
    -> WHERE DATE_SUB(CURDATE(),INTERVAL 30 DAY) <= date_col;

Also irgendwie weiß ich nicht wie ich mit dem Thema "Zeit" umgehen soll in MySQL.

Wie macht ihr das?

ich trage sorge wenn ich mit localtime(time) alles mache und in Perl
erreichne,  dass das dann viel langsamer ist als in MySQL
mit INTERVAL und DATE_FORMAT zur schönen Ausgabe.

Viel blabla und keiner kennt sich aus, gelle? *hihi*

Danke auf jeden fall mal

Es grüßt
Nebula

  1. hi,

    Ich dachte mir am einfachsten ist immer noch der UNIX Timestamp.
    Da kann ich ganz einfach vergleichen zwischen zwei UNIX Timestamps,
    die entsprechenden Sekunden abziehen oder dazuzählen,
    und das Ausgabeformat bestimmt man auch ganz einfach.

    und man fällt auch so herrlich leicht beim wechsel zwischen sommer-/winterzeit und umgekehrt auf die nase, wenn man einfach nur stumpf 86400 sekunden für einen tag addiert/subtrahiert :-)

    Bevor ich nun aber den UNIX Timestamp in einem VARCHAR Feld abspeichere,

    du wolltest doch damit rechnen ...?
    dann sollte doch wohl klar sein, dass varchar absolut _nicht_ in frage kommt, sondern eher INT.

    dachte ich mir dass es dafür vielleicht ein eigenes Feld gibt in MySQL.

    nope.

    Dann könnte ich vielleicht auch mit NOW()  den aktuellen Timestamp reinbekommen.

    nope.

    bei allen aktionen, die einen mysql-timestamp erfordern/erzeugen, musst du jetzt erst mit FROM_UNIXTIME/UNIX_TIMESTAMP hin- und herwandeln; oftmals auch in andere funktionen verschachtelt.

    gruß,
    wahsaga

    --
    "Look, that's why there's rules, understand? So that you _think_ before you break 'em."
    1. moin wahsaga

      und man fällt auch so herrlich leicht beim wechsel zwischen sommer-/winterzeit und umgekehrt auf die nase, wenn man einfach nur stumpf 86400 sekunden für einen tag addiert/subtrahiert :-)

      Bitte erkläre mir das,  ich dachte wenn ich  localtime($timestamp) mache,
      kommt immer ein richtiges Datum zum Timestamp heraus,
      wo ich nichts mehr umrechnen muss?

      [script lang=perl]

      my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);

      $year += 1900;
      $mon++;

      print "Heute ist der ".$mday.".".$mon.".".$year." um ".$hour.":".$min.":".$sec."\n\n";

      [/script]

      Ausgabe:
      Heute ist 21.2.2005 um 16:44:53

      Wenn ich da statt localtime(time)  einfach mit localtime($timestamp) aufrufe,
      dann sollte das doch auch mit Winterzeit und Sommerzeit passen?

      Dankend grüßt
      Nebula

      1. hi,

        und man fällt auch so herrlich leicht beim wechsel zwischen sommer-/winterzeit und umgekehrt auf die nase, wenn man einfach nur stumpf 86400 sekunden für einen tag addiert/subtrahiert :-)

        Bitte erkläre mir das

        $tag_x = strtotime('30 October 2005 23:05:01 CET');
        echo date('r', $tag_x).'<br>';

        $tag_davor = $tag_x - 86400;
        echo date('r', $tag_davor);

        gruß,
        wahsaga

        --
        "Look, that's why there's rules, understand? So that you _think_ before you break 'em."
        1. moin wahsaga

          Was ist das für ein Script?
          Ist das PHP ?

          Mir ist unklar was Dein Script im Hintergrund macht,
          ist dein Sommerzeit/Winterzeit Problem auch in Perl da,
          oder nur in PHP?

          Für mich ist es nur relevant wenn es in Perl auch das Problem macht.

          Und ich rechne die Timestamps untereinander minus oder plus,
          und erst dann rechne ich das ergebnis in normale Zeit um.

          Es grüßt
          Nebula

          1. hi,

            Was ist das für ein Script?
            Ist das PHP ?

            ja.
            sorry, hatte übersehen, dass es dir nicht vorrangig im PHP geht.

            Mir ist unklar was Dein Script im Hintergrund macht,

            es erzeugt einen unix timestamp für das datum "30 October 2005 23:05:01 CET", als 30. oktober diesen jahres um 23:05:01 uhr CET.

            dieses datum wird dann wird dann wieder ausgegeben, was
            Sun, 30 Oct 2005 23:05:01 +0100
            ergibt.
            also 23:05:01 uhr, zeitverschiebung gegenüber GMT +1 stunde.

            anschließend zieht es 86400 sekunden, die man gemeinhin für die länge eines tages halten _könnte_ (24 * 60 * 60 sekunden), vom timestamp ab - und gibt ihn wiederum als datum formatiert aus.

            und was erhalten wir? nicht etwa den vorhergehenden samstag, 23:05:01 uhr, sondern
            Sun, 30 Oct 2005 00:05:01 +0200

            • wie du siehst, hat das mit dem simplen abziehen von 86400 sekunden also nicht so ganz das erwünschte ergebnis gebracht ...

            ist dein Sommerzeit/Winterzeit Problem auch in Perl da,
            oder nur in PHP?

            bei gleichem vorgehen ist es natürlich auch analog in Perl existent.

            Und ich rechne die Timestamps untereinander minus oder plus,
            und erst dann rechne ich das ergebnis in normale Zeit um.

            mein beispiel berechnet auch nur timestamp minus eine gewisse anzahl an sekunden - und fällt damit, wie man sieht, bei solchen sonderfällen auf die nase.

            gruß,
            wahsaga

            --
            "Look, that's why there's rules, understand? So that you _think_ before you break 'em."
  2. Also irgendwie weiß ich nicht wie ich mit dem Thema "Zeit" umgehen soll in MySQL.

    Mal als Anregung eine kleine Aufgabe: Wie lautet der Unix-Timestamp von 26.12.1955 14:02:20?

    Wie macht ihr das?

    Das kommt immer auf die Anforderungen des konkreten Einzelfalls an, bevorzugt nehme ich das MySQL-Format.

  3. Moin!

    Ich dachte mir am einfachsten ist immer noch der UNIX Timestamp.
    Da kann ich ganz einfach vergleichen zwischen zwei UNIX Timestamps,
    die entsprechenden Sekunden abziehen oder dazuzählen,
    und das Ausgabeformat bestimmt man auch ganz einfach.
    Ich bin und bleibe einfach ein Unix Timestamp Fan,
    auch wenn die MySQL Geeks mich dafür schimpfen *g*

    Das Problem der Unix-Timestamp:
    Es ist derzeit auf den allermeisten Plattformen nur eine vorzeichenbehaftete 32-Bit Integerzahl, das bedeutet, dass ihr Wertebereich im Jahre 2038 endet. Und unter Windows gibt es (jedenfalls behauptet PHP das in der Dokumentation) Fehler in internen Bibliotheken mit der Umwandlung von Timestamps vor "0" (also dem 1.1.1970). Das bedeutet: Du hast mit der Unix Timestamp den recht eingeschränkten Wertebereich von 1970 bis 2038, also grob 68 Jahre, zur Verfügung, mehr nicht. Außerdem vergeudest du einen erheblichen Anteil der Bits für Sekundengenauigkeit, die man doch in manchen Fällen gar nicht wirklich benötigt, beispielsweise wenn es um Geburtstage geht.

    Dass die Unix-Timestamp dich komplett in die Irre führt, wenn du standardmäßig mit 24-Stunden-Tagen rechnest und dabei Sommerzeitumstellungen nicht bedenkst (schließlich hat ein Tag des Jahres immer 25 Stunden, ein anderer hingegen nur 23 Stunden - von der Möglichkeit von Schaltsekunden mal ganz zu schweigen...), hat wahsaga ja schon dargelegt.

    Selbstverständlich ist das Rechnen mit Timestamps ganz nett. Aber in diesen ganz netten Umgang dann zeitzonenkorrektes Handling von Sommerzeit oder abstrusen Kalenderabnormitäten (es wurde bekanntlich mal ein Zeitraum von über zwei Wochen im Kalender übersprungen, um die nicht mitgemachten Schaltjahre zu kompensieren) einzubauen dürfte die ganze Sache dann doch wesentlich komplizierter machen.

    Dann vertraue ich doch lieber auf die in MySQL implementierten Funktionen. Die anzuwenden ist mindestens genauso einfach, zumal es sich bei SQL um eine Abfragesprache handelt, die sich durchaus an menschlichen Sprachen orientiert, und der Mensch rechnet nun mal lieber mit "30 Tagen", als mit 2592000 ± 3600 Sekunden.

    • Sven Rautenberg
    1. hi,

      [...] abstrusen Kalenderabnormitäten (es wurde bekanntlich mal ein Zeitraum von über zwei Wochen im Kalender übersprungen, um die nicht mitgemachten Schaltjahre zu kompensieren)

      interessant - das war mir zumindest bisher noch nicht bekannt.
      hast du einen kleinen linktipp, wo man nachlesen kann wer das gemacht hat und wann?

      ergooglen kann ich mir auf die schnelle nur http://www.seefunknetz.de/gregor.htm (wikipedia, die auch noch ein vielversprechendes resultat zu versprechen scheint, hat ja derzeit probleme).
      und da wird im rahmen von papst gregors kalenderreform ein sprung vom 4. auf den 15. oktober 1582 erwähnt, wodurch 10 tage "hops" gingen.
      und einige regionen sind wohl erst mit verzögerung nachgezogen,

      So fällt im flämischen, katholisch geführten Brügge 1582 Weihnachten aus. Auf den 21. Dezember folgt unmittelbar der 1. Januar um die 10 Tage einzuholen, die der alte Kalender falsch ging.

      auf jeden fall ein interessanter geschichtlicher aspekt, mit dem ich mich bisher noch gar nicht befasst hatte :-)

      gruß,
      wahsaga

      --
      "Look, that's why there's rules, understand? So that you _think_ before you break 'em."