Warnung: file_put_contents(/home/www/web1/html/php_dev/test.txt) [function.file-put-contents]: failed to open stream: Permission denied in /home/www/web1/html/php_dev/sys/lib.activity.php (Zeile 58)
C Datumskonvertierung [Archiv] - PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr
ebiz-webhosting
- Ad -
php-resource




Archiv verlassen und diese Seite im Standarddesign anzeigen :
C Datumskonvertierung


 
hand
05-05-2002, 09:40 
 
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:

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 :()

 
Titus
05-05-2002, 11:02 
 
echo date (http://www.php3.de/de/date)('Y-m-d H:i:s', strtotime (http://www.php3.de/de/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 (http://www.php3.de/de/sscanf) (PHP 4), array_search (http://www.php3.de/de/array_search) (PHP 4.0.5) und sprintf (http://www.php3.de/de/sprintf):
$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]);

 
Titus
05-05-2002, 11:17 
 
ups ... in C willst du das ganze haben ... naja, da führt wohl nix um die String-Funktionen rum:
#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);
}

 
Titus
05-05-2002, 11:37 
 
... 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_and_time_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.

 
hand
05-05-2002, 14:57 
 
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:

...
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


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?

 
Titus
05-05-2002, 15:23 
 
> 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);

 
hand
05-05-2002, 18:16 
 
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.


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.

 
hand
05-05-2002, 21:14 
 
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

 
Titus
06-05-2002, 12:12 
 
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!


Alle Zeitangaben in WEZ +2. Es ist jetzt 17:58 Uhr.