Forum: PC-Programmierung C- Unix Zeitstempel immer um 1h falsch


von Borislav B. (boris_b)


Lesenswert?

Hallo,
ich versuche aus der aktuellen UTC-Zeit einen UNIX-Zeitstempel zu 
generieren. Der liegt aber leider immer um eine Stunde daneben.

Hier der Code:
1
  // Liefert aktuelle UTC Zeit (z.B.  05 / 16 / 14 @ 7:25:26am UTC)
2
  time_t timeNow = time(0);
3
  tm* utcTime = gmtime(&timeNow);
4
5
  // Liefert um 1h falschen UNIX Timestamp (z.B.  05 / 16 / 14 @ 6:25:26am UTC)
6
  DWORD unixTimestamp = (DWORD)mktime(utcTime);

Vermutlich ist der Fehler ganz trivial, aber ich komm einfach nicht 
drauf...

: Bearbeitet durch User
von Operator S. (smkr)


Lesenswert?

Sommerzeit?

von (prx) A. K. (prx)


Lesenswert?

Sommerzeit?

von Ste N. (steno)


Lesenswert?


von Borislav B. (boris_b)


Lesenswert?

A. K. schrieb:
> Sommerzeit?

Operator S. schrieb:
> Sommerzeit?

UTC-Zeiten kennen doch gar keine Sommerzeit?

von Konrad S. (maybee)


Lesenswert?

Normalerweise nimmt man localtime().

von Borislav B. (boris_b)


Lesenswert?

Konrad S. schrieb:
> Normalerweise nimmt man localtime().

Tut man das? Ich brauche aber die UTC-Zeit, nicht die lokale Zeit ;-)

von Konrad S. (maybee)


Lesenswert?

Dann stell deine HW-Clock auf UTC, nicht localtime.

von Konrad S. (maybee)


Lesenswert?

... oder stell die Zeitzone auf UTC.

von Borislav B. (boris_b)


Lesenswert?

Konrad S. schrieb:
> Dann stell deine HW-Clock auf UTC, nicht localtime.

Häää? Das abfragen der UTC-Zeit ist doch überhaupt nicht mein Problem.
1
tm* utcTime = gmtime(&timeNow);
funktioniert ja wunderbar.

Das Problem ist das Generieren des Unix-Zeitstempels.

von Dirk B. (dirkb2)


Lesenswert?

Und stell die Zeitzone von deinem System richtig ein.

von Borislav B. (boris_b)


Lesenswert?

Dirk B. schrieb:
> Und stell die Zeitzone von deinem System richtig ein.

Was hat das mit meinem Problem zu tun?

von Rene H. (Gast)


Lesenswert?

Hi Boris,

ich mache da so:
1
    setenv("TZ", "UTC", 1);
2
    time (&t);

UTC wechselt im Sommer oder Winter die Zeitzone nicht.

Aber Achtung: setzte danach wieder auf CET resp. CEST um.

Grüsse,
René

von Johann L. (radiostar)


Lesenswert?

time_t timeNow = time(0);

liefert doch schon den UNIX Zeitstempel.

von Rene H. (Gast)


Lesenswert?

Was dennoch komisch ist, dass Deine Zeit um eine Stunde abweicht. Wir 
haben jetzt CEST, d.h. Deine Zeit müsste dann um zwei Stunden abweichen.

Ist die Systemzeit und Zeitzone richtig eingestellt?

Grüsse,
René

von old man (Gast)


Lesenswert?

Sie dir mal die variable tm_isdst in struct tm an. Die ist für die 
Sommerzeit zuständig.

von Konrad S. (maybee)


Lesenswert?

time(0) liefert den Unix-Zeitstempel. Wenn er nicht stimmt, dann hast du 
deine Uhr nicht richtig auf UTC eingestellt.

von Ste N. (steno)


Lesenswert?

Laut diesem Link

http://www.cplusplus.com/reference/ctime/mktime/

benötigt mktime() als Parameter die Lokale Zeit? Versuchs doch mal 
damit.

  time_t timeNow = time(0);
  tm* localTime = localtime(&timeNow);
  DWORD unixTimestamp = (DWORD)mktime(localTime);

Gruß, Steffen

von Borislav B. (boris_b)


Lesenswert?

Steffen N. schrieb:
> benötigt mktime() als Parameter die Lokale Zeit? Versuchs doch mal
> damit.

Eigentlich kann man mktime als Parameter jede beliebige Zeit übergeben, 
nicht zwangsläufig die lokale Zeit.

old man schrieb:
> Sie dir mal die variable tm_isdst in struct tm an. Die ist für die
> Sommerzeit zuständig.

Jo, die hab ich auf 0 gesetzt (keine DST), weil ich ja mit UTC Zeiten 
arbeite.

Die Zeit kommt übrigens NICHT von meinem lokalen PC, sondern von einem 
GPS Empfänger. Was ich also machen möchte ist Folgendes (pseudo-Code):

var CurUtcTime = GpsGetCurrentUtcTime();
var UnixTimestamp = mktime(CurUtcTime );

Da liegt aber der Wert immer eine Stunde neben der echten UTC Zeit...

von (prx) A. K. (prx)


Lesenswert?

Boris P. schrieb:
> Eigentlich kann man mktime als Parameter jede beliebige Zeit übergeben,
> nicht zwangsläufig die lokale Zeit.

Klar. Nur ist mktime per Definition die Umkehrung von localtime, nicht 
von gmtime. Folglich kann time => gmtime => mktime nur dann die gleiche 
Timestamp liefern, wenn man sich in der UTC Zeitzone befindet.

: Bearbeitet durch User
von Ste N. (steno)


Lesenswert?

Boris P. schrieb:
> Eigentlich kann man mktime als Parameter jede beliebige Zeit übergeben,
> nicht zwangsläufig die lokale Zeit.

Naja, die Frage ist ja, wandelt mktime stur die Zeitstruktur, oder 
schaut er vorher im System nach und korrigiert selbstständig je nach 
eingestellter Zeitzone?

von Borislav B. (boris_b)


Lesenswert?

A. K. schrieb:
> Klar. Nur ist mktime per Definition der Gegenspieler von localtime,
> nicht von gmtime.

Dann habe ich mktime vielleicht falsch verstanden?

Was ich von der Funktion erwarte ist, dass sie die Anzahl der Sekunden 
vom 1. januar 1970 bis zum übergebenen Zeitpunkt zurückgibt (also den 
UNIX-Timestamp).

Wo soll denn da die lokale Zeit ins Spiel kommen?

Steffen N. schrieb:
> Naja, die Frage ist ja, wandelt mktime stur die Zeitstruktur, oder
> schaut er vorher im System nach und korrigiert selbstständig je nach
> eingestellter Zeitzone?

Dafür gibt es ja eigentlich das Flag "tm_isdst". Wenn man das auf 0 
stellt, sollte nicht korrigiert werden. (?)

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

http://www.cplusplus.com/reference/ctime/mktime/

"Returns the value of type time_t that represents the local time 
described by the tm structure pointed by timeptr (which may be 
modified).

This function performs the reverse translation that localtime does."

Du fütterst mktime aber nicht mit der lokalen Zeit, sondern mit UTC.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Boris P. schrieb:
> Dafür gibt es ja eigentlich das Flag "tm_isdst". Wenn man das auf 0
> stellt, sollte nicht korrigiert werden. (?)

tm_isdst bestimmt die Berücksichtigung der Sommerzeit, nicht der 
Zeitzone.

von Borislav B. (boris_b)


Lesenswert?

A. K. schrieb:
> Du fütterst mktime aber nicht mit der lokalen Zeit, sondern mit UTC.

OK, das ist dann wohl die Erklärung für das seltsame Verhalten. Danke!
In der Doku die ich zu der Funktion herangezogen habe war das leider 
NICHT erwähnt. Oder ich habs überlesen ;-)

Gibt es denn eine Alternative der ich auch eine UTC Zeit übergeben 
könnte?
Also eine Funktion: UTC-Zeit -> UTC-UNIX-Timestamp?

von (prx) A. K. (prx)


Lesenswert?


von Georg A. (georga)


Lesenswert?

Wobei ich 'mktime(&tm)-timezone' einfacher finde, und threadsafe ist es 
auch (vs. timegm). timezone ist übrigens in time.h definiert...

von Amateur (Gast)


Lesenswert?

Meist liegt das am persönlichen Standpunkt.

Also tatsächlicher Position auf dem Globus bzw. der Zeitzone.

Da Computer sehr leichtgläubig sind, kann man auch dort einiges 
falschmachen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.