C Datumskonvertierung

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

  • C Datumskonvertierung

    Ich habe mit C nicht viel am Hut, muß aber ein C Programm knacken um Informationen aus diesem nach MySQL zu bringen. Ich habe es bis auf einen kleinen Punkt geschafft.

    Das C-Programm liefert mir in einem Textfeld einen Timestamp im Format "Sat May 4 12:56:19 2002" und für MySQL muß ich dieses in das MySQL-Format "2002-05-04 12:56:19" bringen.

    Ich habe im Blindflug mit ctime, strftime herumgespielt, aber leider ohne Erfolg. C ist für mich ein spanisches Dorf.

    Wie kann ich o.a. Datum konvertieren? Gibt es eine einfache Funktion dafür? Gibt es sowas ähnliches wie setlocale()?

    In meinem Umfeld kenne ich keinen C-Profi (d.h. ich kenne schon welche, die das von sich behaupten, die mir aber noch nie helfen konnten, die hatten immer Erklärungen parat, warum das oder jenes nicht funktionieren kann, wo ich aber dann als C-Laie im "Hackverfahren" doch Lösungen finden konnte)

    Aufgabenstellung:
    Code:
    char * ApplDatum;
    char * ConvDatum;
    
    ApplDatum = "Sat May  4 12:56:19 2002";
    
    // Jetzt muß was passieren, damit  bei ConvDatum
    
    fprintf(stderr, "Datum   %s   konvertiert:   %s",ApplDatum, ConvDatum);
    
    // als Ergebnis
    // "Datum   Sat May  4 12:56:19 2002   konvertiert:   2002-05-04 12:56:19"
    // ausgegeben wird
    Bitte alle komischen entsprechenden #include und #define Angaben nicht vergessen.

    (Wenns doch nur PHP wäre )

  • #2
    echo date('Y-m-d H:i:s', strtotime($datum))
    (funktioniert seit PHP 3.0.12)

    Sollte die "Intelligenz" von strtotime das wider Erwarten nicht knacken können,
    geht´s auch umständlicher mit sscanf (PHP 4), array_search (PHP 4.0.5) und sprintf:
    PHP-Code:
    $a sscanf($datum'%s %s %d %d:%d:%d %d');
    $m = array('''Jan''Feb''Mar''Apr''May',
      
    'Jun''Jul''Aug''Sep''Oct''Nov''Dec');
    echo 
    sprintf('%04d-%02d-%02d %02d:%02d:%02d',
      
    $a[6], array_search($a[1], $m), $a[2], $a[3], $a[4], $a[5]); 
    mein Sport: mein Frühstück: meine Arbeit:

    Sämtliche Code-Schnipsel sind im Allgemeinen nicht getestet und werden ohne Gewähr auf Fehlerfreiheit und Korrektheit gepostet.

    Kommentar


    • #3
      ups ... in C willst du das ganze haben ... naja, da führt wohl nix um die String-Funktionen rum:
      Code:
      #include <string.h>
      ...
      int datum2sql (const char *datum, char *sqldatum)
      {
        const char[12][4] monat = {'Jan', 'Feb', ...};
        /* Erinnere ich mich korrekt an die Array-Definition in C? */
        char[4] w, m;
        int d, h, i, s, y, n;
        sscanf (datum, '%s %s %d %d:%d:%d %d', w, m, d, h, i, s, y);
        for (n=0; (n<12) && !strcmp(monat[n], m); n++);
        /* ganz recht, diese Schleife hat keinen Körper! */
        return sprintf (sqldatum, '%04d-%02d-%02d %02d:%02d:%02d',
          y, n+1, d, h, i, s);
      }
      mein Sport: mein Frühstück: meine Arbeit:

      Sämtliche Code-Schnipsel sind im Allgemeinen nicht getestet und werden ohne Gewähr auf Fehlerfreiheit und Korrektheit gepostet.

      Kommentar


      • #4
        und in SQL ...

        ... gibt´s die Funktion date_format. Man könnt´s auch mal mit extract versuchen. (beide auf http://www.mysql.com/doc/D/a/Date_an...functions.html).
        Kannst ja mal probieren, ob eine von den beiden das ANSI-Datum als Eingangsparameter frißt - wenn ja, dann prima. ansonsten helfen wieder nur die String-Funktionen. Aber da würd ich dann doch eher auf die C-Lösung ausweichen, da mir momentan keine einfache Lösung für den Monat einfallen will.
        mein Sport: mein Frühstück: meine Arbeit:

        Sämtliche Code-Schnipsel sind im Allgemeinen nicht getestet und werden ohne Gewähr auf Fehlerfreiheit und Korrektheit gepostet.

        Kommentar


        • #5
          Danke Titus. Wollte es einmal mit dem C-Code probieren.

          Ich nehme an ich muß diese Funktion von irgendwo aufrufen. Die Frage ist wie, denn so wie es aussieht benötigt die Funktion zwei Parameter *datum und *sqldatum. Wie ist der Aufruf korrekt?

          datum2sql(ApplDatum); //?
          ConvDatum = datum2sql(ApplDatum); //?
          datum2sql(ApplDatum, ConvDatum); //?

          Was ist eigentlich mit den Tagen? "Sun" "Mon" "Tue" ?
          Beim Kompilieren erhalte ich Errors:
          Code:
          ...
          gcc -g -O2  `sh ./cflags`        -c output.c
          output.c: In function `datum2sql':
          output.c:315: parse error before `['
          output.c:315: warning: multi-character character constant
          output.c:315: warning: multi-character character constant
          output.c:315: warning: multi-character character constant
          output.c:315: warning: multi-character character constant
          output.c:315: warning: multi-character character constant
          output.c:315: warning: multi-character character constant
          output.c:315: warning: multi-character character constant
          output.c:315: warning: multi-character character constant
          output.c:315: warning: multi-character character constant
          output.c:315: warning: multi-character character constant
          output.c:315: warning: multi-character character constant
          output.c:315: warning: multi-character character constant
          output.c:318: character constant too long
          output.c:318: `w' undeclared (first use in this function)
          output.c:318: (Each undeclared identifier is reported only once
          output.c:318: for each function it appears in.)
          output.c:318: `m' undeclared (first use in this function)
          output.c:318: warning: passing arg 2 of `sscanf' makes pointer from integer
          without a cast
          output.c:319: `monat' undeclared (first use in this function)
          output.c:320: character constant too long
          output.c:320: warning: passing arg 2 of `sprintf' makes pointer from integer without a cast
          make[1]: *** [output.o] Error 1
          make[1]: Leaving directory `/usr/local/nessus/nessus-core/nessus'
          make: *** [client] Error 2
          Code:
          Zeile
          313  datum2sql (const char *datum, char *sqldatum)
          314  {
          315    const char[12][4] monat = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
          316    char[4] w, m;
          317    int d, h, i, s, y, n;
          318    sscanf (datum, '%s %s %d %d:%d:%d %d', w, m, d, h, i, s, y);
          319    for (n=0; (n<12) && !strcmp(monat[n], m); n++);
          320    return sprintf (sqldatum, '%04d-%02d-%02d %02d:%02d:%02d', y, n+1, d, h, i, s);
          321  }
          wie Du siehst, habe ich null Plan, aber optisch sieht der Code vielversprechend aus. Kannst Du mir bitte nochmals helfen?

          Kommentar


          • #6
            > char * ConvDatum;
            dem solltest du Speicherplatz reservieren:
            char[19] ConvDatum;

            > Aufruf
            datum2sql(ApplDatum, ConvDatum);

            > Was ist eigentlich mit den Tagen? "Sun" "Mon" "Tue" ?
            Das Datum ist bekannt, da kann der Wochentag ignoriert werden.

            > output.c:315: warning: multi-character character constant
            > output.c:318: character constant too long
            hmpf ... mußt du ein bischen rumprobieren, wie man ein Array aus
            konstanten Strings definiert. Ich weiß da nicht mehr so genau,
            und testen kann ich mangels C-Compilers auch nicht.

            > output.c:320: character constant too long
            Aber eins fällt mir gerad wieder ein:
            Alle Strings müssen in doppelte Anführungszeichen!:

            Zeile
            315 const char[12][4] monat = {"Jan","Feb","Mar","Apr",...};
            Arrays in C mit GESCHWEIFTEN Klammern definieren!
            318 sscanf (datum, "%s %s %d %d:%d:%d %d", w, m, d, h, i, s, y);
            320 return sprintf (sqldatum, "%04d-%02d-%02d %02d:%02d:%02d", y, n+1, d, h, i, s);
            mein Sport: mein Frühstück: meine Arbeit:

            Sämtliche Code-Schnipsel sind im Allgemeinen nicht getestet und werden ohne Gewähr auf Fehlerfreiheit und Korrektheit gepostet.

            Kommentar


            • #7
              Habe die zunächst noch problematischen Statements deaktiviert. Im ersten Schritt soll nur der sscanf() funzen.
              Tut er aber nicht --> Segmentation fault
              Der Display davor "datum2sql 1" ist noch korrekt, inklusive dem übergebenen Datum.
              Dann der "Segmentation fault"
              Der Display "datum2sql 2" kommt nicht mehr.

              Code:
              datum2sql (ApplDatum, ConvDatum)
               char * ApplDatum;
               char * ConvDatum;
              {
                // const char[12][4] monat = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
                // const char[12][4] monat = {"Jan","Feb"};
                // char[4] w, m;
                char w[4];
                char m[4];
                int d, h, i, s, y, n;
              
                printf ("datum2sql 1 --> %s\n",ApplDatum);
                sscanf (ApplDatum, "%s %s %d %d:%d:%d %d", w, m, d, h, i, s, y);  // Segmentation fault
              
                printf ("datum2sql 2\n");
                //for (n=0; (n<12) && !strcmp(monat[n], m); n++);
                //return sprintf (sqldatum, "%04d-%02d-%02d %02d:%02d:%02d", y, n+1, d, h, i, s);
                return sprintf (ConvDatum, "%04d-%02d-%02d %02d:%02d:%02d", y, m, d, h, i, s);
              }
              Ich glaub das wird wohl nix mehr heute. Und ich bin die nächsten Tage auswärts

              Mir würde es schon genügen, wenn es gelänge den string mit einer Funktion wie substr() zerlegen zu können.
              Die Monatsangabe könnte ich über if lösen. Es muß ja kein Schönheitswettbewerb sein.
              Zuletzt geändert von hand; 05.05.2002, 17:25.

              Kommentar


              • #8
                Ursache für den "Segmentation fault" ist das 2. Blank vor dem Tagesdatum. Wenn ich das über %02s übergehe, dann bekomme ich den "Segmentation fault" bei der Uhrzeit, da ist auch mit %s oder %08s nichts zu machen. Mir ist es trotzdem gelungen mit Hilfe strtok() die Felder zu separieren.

                Den Rest (zusammenfügen zu einem String) werde ich auch hinbekommen, denn sprintf() mit den separierten Feldern läuft auch auf einen "Segmentation fault". Aber wie gesagt irgendwie wirds hinhauen, bin zuversichtlich.

                Danke

                Kommentar


                • #9
                  An sich seh ich in dem letzten sscanf keinen Fehler ... aber man kann´s ja noch mal genauer definieren:
                  sscanf (ApplDatum, "%*3s %3s %2d %2d:%02d:%02d %4d", m, d, h, i, s, y);
                  Der * im ersten Parameter sorgt dafür, das der Wochentag schon vom scanf ignoriert wird, dann braucht w auch nicht deklariert zu werden.

                  Zur Not kannst du auch den Monat mit strncpy und nur die Zahlen mit sscanf holen:
                  strncpy (w, ApplDatum, 3);
                  w[3] = '\0';
                  sscanf (&ApplDatum[8], "%2d %2d:%2d:%2d %4d", w, m, d, h, i, s, y);

                  Eins hast du schon korrigiert, aber nicht überall: die Deklarationen des Arrays muß natürlich so aussehen:
                  char monat[12][4] = {"Jan", ...};
                  Wenn das so nicht tut, lass die 4 weg, versuchsweise auch mal die 12.

                  Dein sprintf funktioniert übrigens nicht so, wie du´s gerne hättest, da %d ein Integer erwartet, m aber ein String (bzw. ein Pointer) ist. Da muss schon n+1 hin!
                  mein Sport: mein Frühstück: meine Arbeit:

                  Sämtliche Code-Schnipsel sind im Allgemeinen nicht getestet und werden ohne Gewähr auf Fehlerfreiheit und Korrektheit gepostet.

                  Kommentar

                  Lädt...
                  X