Masipulami: Datum in long Format konvertieren

Hallo zusammen,

ich bräuchte mal kurz eure fachkundige Hilfe.

Für die dynamische Erzeugung von Dateinamen muss ich einen Timestamp erzeugen.

Bisher war mein Ansatz folgender:

sub time_stamp {
  my $self = shift;
  my ($d,$t,$ts);
  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);

$year += 1900;
  $mon++;
  $d = sprintf("%4d-%2.2d-%2.2d",$year,$mon,$mday);
  $t = sprintf("%2.2d:%2.2d:%2.2d",$hour,$min,$sec);
  $ts = $d . "-" . $t . "\n";

$self->_print("generated timestamp: " . $ts . "\n");
  return($ts);
}

Mein Chef meinte gerade allerdings, dass er den Timestamp gerne im "long" Format haben möchte. Also als Ergebnis quasi nur ne lange Zahl, die aus dem Datum generiert wird.

Habe allerdings leider keine Ahnung wie ich das machen soll.

Hoffe mir kann da jmd. weiterhelfen.

Vielen Dank schon mal und

viele Grüße,
Masipulami

  1. Hallo Masipulami!

    Mein Chef meinte gerade allerdings, dass er den Timestamp gerne im "long" Format haben möchte. Also als Ergebnis quasi nur ne lange Zahl, die aus dem Datum generiert wird.

    Was meint Dein Chef mit »long format«? time(); liefert den Unix-Timestamp, das ist eine lange Zahl, nämlich die der Sekunden seit 1.1.70:

    my $zeit = time;
    print $zeit;

    Ausgabe:
    1195468520

    Viele Grüße aus Frankfurt/Main,
    Patrick

    --

    _ - jenseits vom delirium - _
    [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
    Nichts ist unmöglich? Doch!
    Heute schon gegökt?
    1. Hallo und danke schon mal für die schnelle Hilfe.

      Ich weiß, dass das nette Tierchen eigenlich Marsupilami geschrieben wird.
      Hab den Nick so halt schon seit Jahren im Netz. ;-)

      Dein Ansatz ansich geht schon in die richtige Richtung.
      Ich bräuchte das ganze aber am besten noch genauer. Es kann nämlich sein, dass in meinem Fall innerhalb einer Sekunde mehrere
      Dateien erstellt werden müssen. Von daher bräuchte ich am besten einen Timestamp im „long“-Format auf Millisekundenbasis.

      1. Hallo Masipulami!

        Dateien erstellt werden müssen. Von daher bräuchte ich am besten einen Timestamp im „long“-Format auf Millisekundenbasis.

        Da gibt es ein Modul, dessen Namen mir leider entgangen ist und das Dir sicher weiter helfen könnte. Struppi, unser Modul-Freak, wird es sicher kennen ;)

        Hm, Date::Calc?

        Viele Grüße aus Frankfurt/Main,
        Patrick

        --

        _ - jenseits vom delirium - _
        [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
        Nichts ist unmöglich? Doch!
        Heute schon gegökt?
        1. Da gibt es ein Modul...

          Time::HiRes

          1. Da gibt es ein Modul...
            Time::HiRes

            Und damit man nicht lange suchen muss:
            http://perldoc.perl.org/Time/HiRes.html

            Siechfred

            --
            Hinter den Kulissen passiert viel mehr, als man denkt, aber meistens nicht das, was man denkt.
            1. Danke dir für den Link!
              Da seh ich jetzt aber auch nur wie ich sleep etc. verwende.
              Was muss ich denn eingeben, um einfach nur die Zeit von heute in Millisekunden zurück zu bekommen?

              1. Was muss ich denn eingeben, um einfach nur die Zeit von heute in Millisekunden zurück zu bekommen?

                Doku lesen:

                --- schnipp ---
                time ()

                Returns a floating seconds since the epoch. This function can be imported, resulting in a nice drop-in replacement for the time provided with core Perl; see the "EXAMPLES" below.
                --- schnapp ---

                Siechfred

                --
                Hinter den Kulissen passiert viel mehr, als man denkt, aber meistens nicht das, was man denkt.
                1. Hallo Siechfred!

                  --- schnipp ---
                  time ()

                  Returns a floating seconds since the epoch. This function can be imported, resulting in a nice drop-in replacement for the time provided with core Perl; see the "EXAMPLES" below.
                  --- schnapp ---

                  Das Problem ist dabei, dass die _Mikro_sekunden (nicht _Milli_) ungleich ausgegeben werden (mal 3, mal 4 mal 5 mal 6stellig - getestet auf Windows). Bei time() wird noch ein floating Point ausgegeben:

                  C:>perl
                  use Time::HiRes;
                  print Time::HiRes::time();
                  print $/;
                  print time();
                  ^Z
                  1195474867.60938
                  1195474867

                  Ich habe deswegen auch mit gettimeofday() 'rumprobiert - und lasse die Perl-time() zum Vergleich ausgeben:

                  C:>perl -w
                  use Time::HiRes;
                  print Time::HiRes::gettimeofday();
                  print $/, time();
                  ^Z
                  1195474686718750
                  1195474686
                  C:>perl -w
                  use Time::HiRes;
                  print Time::HiRes::gettimeofday();
                  print $/, time();
                  ^Z
                  119547476793750
                  1195474767

                  Schreibt man beide Zahlen der Ausgabe von gettimeeofday() untereinander, sieht man's:

                  1195474686718750
                  119547476793750

                  Viele Grüße aus Frankfurt/Main,
                  Patrick

                  --

                  _ - jenseits vom delirium - _
                  [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
                  Nichts ist unmöglich? Doch!
                  Heute schon gegökt?
                  1. Hallo noch mal an euch alle und noch mal danke für die schon mal echt hilfreichen Hinweise.

                    Muss mich da wirklich selbst mit auseinander setzen. Das stimmt.
                    Fällt mir momentan halt nicht ganz leicht, weil ich bisher nur sehr wenig mit Perl zu tun hatte.

                    Aber das, was ihr geschrieben habt, bringt mich schon mal ein gutes Stück weiter.

                    Mal sehen wie ich das Problem mit den unterschiedlich angeziegten Millisekundem lösen werde, das Patrick so wunderbar veranschaulicht hat.

                  2. Re!

                    1195474686718750
                    119547476793750

                    Sagt niemand mehr was dazu? Wie soll man wissen ob

                    119547476793750 für
                    1195474767937500 oder für
                    1195474767093750

                    steht?

                    Ich meine, mir liegt es fern, den Modulautoren zu kritisieren, aber warum ist das Modul nicht in der Lage, eine Zahl festgelegter Länge auszuliefern?

                    Viele Grüße aus Frankfurt/Main,
                    Patrick

                    --

                    _ - jenseits vom delirium - _
                    [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
                    Nichts ist unmöglich? Doch!
                    Heute schon gegökt?
                    1. Re!

                      1195474686718750
                      119547476793750

                      Sagt niemand mehr was dazu? Wie soll man wissen ob

                      119547476793750 für
                      1195474767937500 oder für
                      1195474767093750

                      steht?

                      Ich hab mich mit dem Modul noch nicht großartig auseinandergesetzt, für das was ich es gebraucht habe hat es funktioniert.

                      Aber na gut. Die Funktion gettimeofday scheint ein Array zurückzugeben, in der Doku steht sowas:
                      ($seconds, $microseconds) = gettimeofday;
                      Vermutlich werden bei deiner Ausgabe einfach die Vor- und Nachstellenkommastellen ohne Komma ausgegeben, daher die unterschiedliche Länge.

                      Ich meine, mir liegt es fern, den Modulautoren zu kritisieren, aber warum ist das Modul nicht in der Lage, eine Zahl festgelegter Länge auszuliefern?

                      Das müßtest du dann schon selber machen

                      Struppi.

                      1. Hallo Struppi!

                        Ich hab mich mit dem Modul noch nicht großartig auseinandergesetzt, für das was ich es gebraucht habe hat es funktioniert.

                        Du brauchst dazu nur 10mn und auf der Konsole und immer wieder Time::HiRes::gettimeofday() und danach noch mal 10mn lang Time::HiRes::time() »printen« zu lassen.

                        Das müßtest du dann schon selber machen

                        Dann brauch ich auch kein Fremdmodul, wenn ich soweit bin, eigene zu schreiben ;)

                        Viele Grüße aus Frankfurt/Main,
                        Patrick

                        --

                        _ - jenseits vom delirium - _
                        [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
                        Nichts ist unmöglich? Doch!
                        Heute schon gegökt?
                        1. Du brauchst dazu nur 10mn und auf der Konsole und immer wieder Time::HiRes::gettimeofday() und danach noch mal 10mn lang Time::HiRes::time() »printen« zu lassen.

                          Wer macht denn sowas ;-)

                          Das müßtest du dann schon selber machen

                          Dann brauch ich auch kein Fremdmodul, wenn ich soweit bin, eigene zu schreiben ;)

                          du hast gesehen, dass Time::HiRes kein reines Perl Modul ist?

                          Struppi.

                          1. Hallo Struppi!

                            Du brauchst dazu nur 10mn und auf der Konsole und immer wieder Time::HiRes::gettimeofday() und danach noch mal 10mn lang Time::HiRes::time() »printen« zu lassen.
                            Wer macht denn sowas ;-)

                            Ich. Weil die zwei ersten Tests zufällig bereits unterschiedliche Zahlenlängen ergaben.

                            du hast gesehen, dass Time::HiRes kein reines Perl Modul ist?

                            Ja. Ändert IMHO aber nichts, wenn es auf CPAN angeboten wird. Da sollte es schon funzen(TM). Wie soll man als OP, den ich hier nicht unterstellen will, dass er keine Ahnung hat, aber wie soll man so eine Ausgabe auswerten oder weiterbearbeiten, wenn man nicht weiß, warum nach dem »normalen« Timestamp 3,4,5 oder 6 Zahlen noch kommen?

                            Viele Grüße aus Frankfurt/Main,
                            Patrick

                            --

                            _ - jenseits vom delirium - _
                            [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
                            Nichts ist unmöglich? Doch!
                            Heute schon gegökt?
                            1. du hast gesehen, dass Time::HiRes kein reines Perl Modul ist?

                              Ja. Ändert IMHO aber nichts, wenn es auf CPAN angeboten wird. Da sollte es schon funzen(TM). Wie soll man als OP, den ich hier nicht unterstellen will, dass er keine Ahnung hat, aber wie soll man so eine Ausgabe auswerten oder weiterbearbeiten, wenn man nicht weiß, warum nach dem »normalen« Timestamp 3,4,5 oder 6 Zahlen noch kommen?

                              Das sind die Nachkommastellen, die sind bei einer Fließkommazahl immmer unterschiedlich lang.
                              use Time::HiRes qw(gettimeofday);
                              my ($seconds, $microseconds) = gettimeofday;
                              print ($seconds, '-',$microseconds);

                              Struppi.

                              1. Hallo Struppi!

                                Das sind die Nachkommastellen, die sind bei einer Fließkommazahl immmer unterschiedlich lang.
                                use Time::HiRes qw(gettimeofday);
                                my ($seconds, $microseconds) = gettimeofday;
                                print ($seconds, '-',$microseconds);

                                Hm... ich habe zuerst gedacht, $microseconds gibt immer eine sechstellige Zahl aus, da in den Tests auch die hinteren Nullen ausgegeben wurden, bis ich eines besseren belehrt wurde:

                                  
                                use Time::HiRes qw(gettimeofday);  
                                my ($seconds, $microseconds) = gettimeofday;  
                                print "Normale Funktion time.................: ", time(), $/;  
                                print "Time::HiRes-Funktion time.............: ", Time::HiRes::time(), $/;  
                                print "gettimeofday getrennt (Struppi).......: ", $seconds, "-", $microseconds, $/;  
                                print "gettimeofday als Zahl.................: ", gettimeofday();  
                                
                                

                                Und hier verschiedene Ausgaben:

                                1.
                                Normale Funktion time.................: 1195545512
                                Time::HiRes-Funktion time.............: 1195545512.85951
                                gettimeofday getrennt (Struppi).......: 1195545512-859375
                                gettimeofday als Zahl.................: 1195545512859643

                                2.
                                Normale Funktion time.................: 1195545541
                                Time::HiRes-Funktion time.............: 1195545541.9376
                                gettimeofday getrennt (Struppi).......: 1195545541-937500
                                gettimeofday als Zahl.................: 1195545541937713

                                3.
                                Normale Funktion time.................: 1195545616
                                Time::HiRes-Funktion time.............: 1195545616.0001
                                gettimeofday getrennt (Struppi).......: 1195545616-0
                                gettimeofday als Zahl.................: 1195545616199

                                Im zweiten Test sieht man, dass sehr wohl die hinteren Nullen ausgegeben werden. Ferner sieht man in den zwei ersten Tests die Zeitabweichung bei den Ausgaben, diese beträgt weniger als 200 Mikrosekunden. Nun aber fällt der dritte Test aus der Reihe! Vor allem die Ausgabe von gettimeofday als Zahl... Wenn zwischen gettimeofday getrennt (Struppi) - wird zeitlich anscheinend zuerst ausgegeben - und Time::HiRes-Funktion time hier 100 Mikrosekunden liegen, was bedeutet dann die letzte Zahl? 199000 Mikrosekunden? Passt doch nicht mit den 2 ersten Tests zusammen, wo nur ca. 200 Mikrosekunden Zeitunterschied zwischen den Ausgaben liegen.

                                Viele Grüße aus Frankfurt/Main,
                                Patrick

                                --

                                _ - jenseits vom delirium - _
                                [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
                                Nichts ist unmöglich? Doch!
                                Heute schon gegökt?
                                1. [ ... Tests ... ]

                                  Hast Du die Doku gelesen, die ich verlinkt habe? Da ist Dein Problem beschrieben und eine Lösung genannt. Die Nachkommastellen sind nicht verschwunden, sie werden nur nicht angezeigt, wenn Du Perl nicht dazu zwingst. Zum Vergleich:

                                  use Time::HiRes;  
                                  print Time::HiRes::time(), "\n";  
                                  printf "%.6f", Time::HiRes::time();
                                  

                                  Siechfred

                                  --
                                  Hinter den Kulissen passiert viel mehr, als man denkt, aber meistens nicht das, was man denkt.
                                  1. Hallo Siechfred!

                                    Hast Du die Doku gelesen, die ich verlinkt habe?

                                    Ja, hatte das aber:

                                    »To see the microseconds you can use either printf/sprintf with "%.6f" , or the gettimeofday() function in list context, which will give you the seconds and microseconds as two separate values.«

                                    zu schnell überflogen.

                                    Damit ist es klar, und erklärt warum in Struppis Beispiel mit der Liste immer die volle Zahl vorhanden war. Thanks again!

                                    Viele Grüße aus Frankfurt/Main,
                                    Patrick

                                    --

                                    _ - jenseits vom delirium - _
                                    [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
                                    Nichts ist unmöglich? Doch!
                                    Heute schon gegökt?
                                2. Hm... ich habe zuerst gedacht, $microseconds gibt immer eine sechstellige Zahl aus, da in den Tests auch die hinteren Nullen ausgegeben wurden, bis ich eines besseren belehrt wurde:

                                  Nein, einfach die Nachkommastellen.

                                  Und hier verschiedene Ausgaben:

                                  sieht bei mir so aus:

                                  Normale Funktion time.................: 1195551627
                                  Time::HiRes-Funktion time.............: 1195551627.37511
                                  gettimeofday getrennt (Struppi).......: 1195551627-375000
                                  gettimeofday als Zahl.................: 1195551627375182

                                  Normale Funktion time.................: 1195551629
                                  Time::HiRes-Funktion time.............: 1195551629.92198
                                  gettimeofday getrennt (Struppi).......: 1195551629-921875
                                  gettimeofday als Zahl.................: 1195551629922057

                                  Normale Funktion time.................: 1195551630
                                  Time::HiRes-Funktion time.............: 1195551630.9845
                                  gettimeofday getrennt (Struppi).......: 1195551630-984375
                                  gettimeofday als Zahl.................: 1195551630984587

                                  Im zweiten Test sieht man, dass sehr wohl die hinteren Nullen ausgegeben werden. Ferner sieht man in den zwei ersten Tests die Zeitabweichung bei den Ausgaben, diese beträgt weniger als 200 Mikrosekunden.

                                  Überrascht dich, dass der Rechner Zeit braucht zum Rechnen?

                                  Wenn zwischen gettimeofday getrennt (Struppi)

                                  Es wird nichts getrennt, setzt mal den output separator: $, = "|"; dann siehst du die zwei Werte, die gettimeofday zurück gibt.

                                  was bedeutet dann die letzte Zahl? 199000 Mikrosekunden? Passt doch nicht mit den 2 ersten Tests zusammen, wo nur ca. 200 Mikrosekunden Zeitunterschied zwischen den Ausgaben liegen.

                                  Die Nachkommastelle bedeutet 0,199 Sekunden, das entspricht ungefähr 200 Mikrosekunden.

                                  Und über Abweichungen im Nanosekunden Bereich würde ich mir nicht den Kopf zerbrechen, der interne Timer im Rechner ist dafür mit Sicheheit nicht ausgelegt.

                                  Struppi.

                                  1. Hallo Struppi!

                                    Überrascht dich, dass der Rechner Zeit braucht zum Rechnen?

                                    Keineswegs, eine CPU hat schon etwas zu tun :)

                                    Es wird nichts getrennt, setzt mal den output separator: $, = "|"; dann siehst du die zwei Werte, die gettimeofday zurück gibt.

                                    Ja, irgendwie musste ich zum Ausdruck bringen, wie Du Deine Ausgabe machst: zwei voneinander durch "-" getrennte Werte... nämlich die von gettimeoftheday() im Listenkontext.

                                    Die Nachkommastelle bedeutet 0,199 Sekunden, das entspricht ungefähr 200 Mikrosekunden.

                                    Hm, 0,1 = 1 Zehntel, 0,01 ein Hunderstel, 0,001 eine Millisekunde ;)
                                    0,000199 wären etwa 200 Mikrosekunden ;)

                                    Aber auch wenn die Tests Spaß gemacht haben , wollen wir hier keine Sekunden spalten, der Tipp von Siechfred mit printf ist die Lösung für time() und Deine mit dem Listenkontext für gettimeoftheday(). Jetzt kann sich Masipulami den String zusammenbauen, den er für seinen Dateinamen braucht - falls noch...

                                    Viele Grüße aus Frankfurt/Main,
                                    Patrick

                                    --

                                    _ - jenseits vom delirium - _
                                    [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
                                    Nichts ist unmöglich? Doch!
                                    Heute schon gegökt?
              2. Hallo,

                Was muss ich denn eingeben, um einfach nur die Zeit von heute in Millisekunden zurück zu bekommen?

                ne also sorry, du musst dein Essen schon selber kauen. Aber statt mit Syntax kann ich dir vielleicht noch mit ein bisschen Erfahrung helfen.

                Falls du unter Windows arbeitest, wird sich der mikrosekunden genaue Timestamp voraussichtlich trotzdem nur alle 10 Millisekunden ändern. (Wie kannst du das testen?) Jedenfalls ist es in C so und Perl wird warscheinlich auch nur auf die C Library zurückgreifen. Sollten also in deinem Fall die Dateien schneller, als im 10 ms Takt angelegt werden, kann es durchaus sein, dass zwei Dateien den selben Namen bekommen.

                Und noch als genereller Hinweis, nur weil dein Chef die Schnapsidee hatte einen Zeitstempel als Dateinamen zu verwenden, heisst das noch lange nicht, dass du es auch unbedingt so umsetzen musst. Wenn einzig und alleine die Eindeutigkeit der Dateinamen gewährleistet werden muss, dann würde ich an deiner Stelle einfach nur durchzählen. Das ist einfacher zu coden und auch noch viel robuster. Die Dateien haben afu jedem OS einen "created" Zeitstempel, an der man den Zeitpunkt der Erstellung ablesen kann, falls diese Funktionalität tatsächlich für irgendeinen Zweck gewünscht ist.

                Gruß,
                Cruz

          2. Danke für den HInweis zu dem Modul.
            Das hatte ich eben durch Zufall auch schon vor mir.

            Nur wie wende ich das jetzt auf meinen Fall an (also im Code)? *blödfrag*

            Sorry, aber ich bin in Perl noch nicht sonderlich bewandert.

            Könntest du mir evtl. kurz meinen Code ergänzen, damit ich einmal sehe wie das richtig angewendet wird?

  2. Re Masipulami!

    Meintest Du Marsupilami mit R? Geniales Tierchen! Von Franquin gefällt mir aber Gaston Lagaffe besser!

    Viele Grüße aus Frankfurt/Main,
    Patrick

    --

    _ - jenseits vom delirium - _
    [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
    Nichts ist unmöglich? Doch!
    Heute schon gegökt?