Datumsberechnung in c / c++

Hallo. Ich habe folgendes Problem. Ein Datenserver erhält Telegramme, die in Datenbanken geladen werden sollen. Hierzu sind auch Zeitstempel erforderlich. Das normale DateTime Format yyyy-mm-tt HH:MM:SS ist kein Problem. Ich benötige aber auch eine andere Notation yyyymmttHHMMSS.millisec offset. Aus der aktuellen Zeit das Format zu erstellen ist kein Problem: (kleiner Umweg, weil ftime() bei mir die Flags nicht setzt und localtime keine milliSec liefert => man kombiniert

struct ts * wird als Übergbewert der Funktion geliefert
struct tm *timeGR;
struct tm *timeDB;
timeb gmt;
time_t now;
now = time(0);
timeDB = localtime(&now);

if( timeDB->tm_isdst ) // offset 120 Sommerzeit, 60 Winterzeit
ts->offset = SOMMER;
else
ts->offset = WINTER;
ftime(&gmt);
timeGR = gmtime( &gmt.time );

Wie kann ich aus einem aktuellen Zeitstempel
in Form yyyy-mm-tt HH:MM:SS nach
yyyymmttHHMMSS.millisec offset wechseln bzw. neu berechnen? Also keine 100 if-else Abfragen weil ich einfach 2 Stunden subtrahiere und dann anfange Tage- Monats- Jahres- Schaltjahresgenze abzufragen oder so. Die millisec sind wohl verloren, woher sollen sie auch noch zur Verfügung stehen. Rückrechnen auf Sekunden seit 1970 evtl, aber wie?
Hat wer eine Idee? Danke
Gruß
Roland

Siehe gettimeofday(2), da kommen zumindest Mikrosekunden in der struct timeval zurück.

Falls es etwas schneller gehen soll, POSIX kennt auch clock_gettime, da kann man sich sogar die Uhr noch aussuchen und z.B. (unter Linux) CLOCK_REALTIME_COARSE benutzen, um besonders schnell and die Millisekunden zu kommen.

Formatierte Ausgabe mußt Du allerdings in beiden Fällen selbst machen, also erst Datum/Zeit drucken, dann an den String (z.B. mit snprintf) noch die Millisekunden hängen.

Hallo und danke.
Das schau ich mir mal genauer an. Ich vermute aber ich bin falsch verstande worden, was an mir liegen dürfte.
Mir geht es darum aus der (nicht aktuellen !!) Info „2016:05:31 13:25:20“ die Info „2016053120112520123“ 120 zu generieren. Also ein zurückliegendes Datum auf gmt mit offset zu formatieren.
Die 123 Millisekunden wären kein Beinbruch aber von 13 Uhr auf 11 Uhr mit Offset 120 für Sommerzeit gmt sind der Hacken.
Deine Infos werde ich aber ausprobieren. Man will ja lernen , :slight_smile: danke.

struct tm test;
char buf[64];
time_t t;

/* zeitzone laden (aus der TZ environment variable) */
tzset();
/* befuellen */
strptime("2016:05:31 13:25:20", "%Y:%m:%d %H:%M:%S", &test);
/* nach epoch stamp wandeln */
t = mktime(&test);
/* zurueck wandeln */
gmtime_r(&t, &test);
/* drucken */
strftime(buf, sizeof(buf), "%Y%m%d%H%m%S", &test);
puts(buf);

Dann mit gcc -D_GNU_SOURCE bauen und aufrufen so:

$ TZ=Europe/Berlin ./a.out
20160531112520

ABER, das ist sehr unkomfortabel (man muss auf die richtige TZ Variabel achten) und langsam (durch Hin- und Rückwandlung nach Epoch-timestamps). Ich wollte daher die Gelegenheit nutzen, mein Tool dateutils mal anzupreisen (gibt’s für jede gute Distro), dort wäre die ganze Wandelarie ein Klacks:

$ dateconv -i '%Y:%m:%d %H:%M:%S' --from-zone Europe/Berlin --zone UTC -f '%Y%m%d%H%M%S120' "2016:05:31 13:25:20"
20160531112520120

Und der kann auch stapelweise Daten von stdin lesen und umwandeln:

$ echo "2016:05:31 13:25:20" | dateconv -i '%Y:%m:%d %H:%M:%S' --from-zone Europe/Berlin --zone UTC -f '%Y%m%d%H%M%S120'
20160531112520120

Wo die Millisekunden dann herkommen sollen, weiß ich allerdings auch nicht.

Hallo und danke für den Code.
Ist aber leider ein kleiner Fehler drin %H%M%S nicht %H%m%S. Das war leider nicht ganz augenscheinlich, habs aber gefunden.