time_t

Thomasio

Erfahrenes Mitglied
Es hat mich einiges an Arbeit gekostet, bis ich mal kapiert hatte, wie man mit time_t und tm* passende Uhrzeiten ausgeben kann, vor allem, wenn es noch GMT time sein soll, unabhängig von der Zeitzone des Users, aber irgendwann habe ich es doch begriffen.

Code:
time_t rawtime;
struct tm * timeinfo;
time(&rawtime);
timeinfo = gmtime(&rawtime);
char MyGMTime [80];
strftime(MyGMTime,80,"GMT Time: %H:%M:%S",timeinfo);

Jetzt brauche ich das Ganze aber etwas extremer, weiss nicht mal genau wie ich es erklären soll.
Vielleicht am praktischen Beispiel:
Der Server steht in Australien, da soll ein Countdown über mehrere Wochen laufen.
Gestartet wird der Countdown von einem User, der in ein paar Eingabefeldern Datum und Uhrzeit eingeben soll.

Erstes Problem, mal angenommen der User sitzt in USA, und soll eine GMT Uhrzeit angeben, z.B. 1.1.2009 18::00.
Dann passt die Angabe erstmal nicht zur Zeitzone des Users, muss ich also umrechnen, und keine Ahnung wie.
Dann muss die Info an den Server gesendet und von da aus an sämtliche anderen Clients verteilt werden, so dass alle Clients unabhängig von ihrer Zeitzone die GMT time anzeigen, wann der Countdown abläuft, und wie lange noch bis dahin ist.
Mein Problem ist nur, über Socket sende ich char* also muss ich irgrendwie das Ganze zu einem string konvertieren.
Sende ich aber einem Client einen amerikanischen timestamp via einem australischen server, dann versagen meine Künste, oder kurz gesagt, ich stehe im Wald.
Versuche ich es andersrum, und verteile den fertigen GMT string, ohne irgendwas umzurechnen, dann habe ich zwar ein korrektes Ablaufatum samt Uhrzeit zum anzeigen, aber dann weiss ich nicht, wie ich aus dem string errechnen soll, wie lange noch bis dahin ist.
Obendrein weiss der Server dann nicht, wann die Zeit um ist und er eine bestimmte Funktion ausführen soll.
Ausgehend von meinem Code oben, kann ich zwar anzeigen, es ist jetzt GMT Zeit sowieso, der Countdown läuft ab zu GMT Zeit sowieso, aber wie errechne ich daraus die Differenz?

Hat jemand eine Idee, wie man das lösen kann?
Vermutlich mache ich es mir nur selber viel zu kompliziert.
 
Wozu die GMT bzw. UTC da ist, ist mir schon klar, genau darum will ich sie ja auch verwenden.

Mir ist nur nicht klar, wie ich in C++ aus der localtime des Users die GMT time errechne.
Alles was ich dazu finde ist mein Code von oben, wobei gmtime() nun mal time_t in tm* konvertiert.
Ich bräuchte das aber irgendwie anders.
Wenn der Server oder einer der Clients den string "1.1.2009 18:00" empfängt, von mir aus auch als "2009-01-01T18:00:00" oder in welchem Format auch immer, dann ist das schon GMT time, gmtime() oder mktime() oder difftime() nutzen mir da nicht viel.

Ich kann ja noch die localtime des Users errechnen und zu GMT time konvertieren, dann hätte ich 2 strings

string time1 = "2009-01-01T18:00:00";
string time2 = "2008-11-19T12:50:00";

aber wie errechne ich aus den beiden die Differenz?
 
Hallo,

wenn ich dein Szenario richtig verstanden habe, ist es dein Anliegen einen Countdown auf einem australischen Server zu starten der von einer x-beliebigen anderen Zeitzone aus konfiguriert wird. Dieser Server verteilt dann sein Ablaufdatum auf andere Clients die ebenfalls in x-beliebigen Zeitzonen liegen können. Und du willst die verbleibende Zeit dann richtig anzeigen? Sehe ich das richtig?

Wenn ja wieso machst dus nicht einfach so das nehmen wir mal an der Nutzer in der USA den australischen Server nach seiner Zeitzone konfiguriert. Diese Zeitangabe (in welchem Format auch immer) rechnest du in einen absoluten Wert (der Unixzeitstempel bietet sich da an) mittels mktime um, und schickst den raw Zeitstempel über das Netzwerk zum Server, welcher sich konfiguriert und diesen dann ebenfalls wieder als raw Zeitstempel an die anderen Clients verteilt bzw weiterleitet. Die Clients können dann intern mit dem Zeitstempel mit simpler Arithmetik rechnen und dem Benutzer die Ablaufzeit in seiner Zeitzone als GMT-Zeit anzeigen.

HTH,
RedWing
 
Ja, so in etwa habe ich das schon versucht.
Dummerweise verschiebt sich dabei die Zeit, je nach Server-Auslastung um ein paar Sekunden.
Angenommen ich sende dem Server die Anzahl Sekunden bis zum 1.1.2009 18:00, dann bekomme ich als Ablaufdatum auf dem Server schon 1.1.2009 18:00:01 und bei den Clients noch etwas später.
 
Ehrlich gesagt habe ich das Gefühl das Du das Konzept von gmtime noch nciht verstanden hast. gmtime liefert immer die aktuelle UTC und zwar EGAL wo auf der Welt Du das aufrufst. Localtime liefert immer die lokale Zeit des Users.

Du kannst problemlos zwischen UTC und localtime umrechnen, dazu musst Du nur wissen in welcher Zeitzone der User sich gerafe befindet. (localtime = utc + offset der Zeitzone).

Für Deinen amerikanishen Client ist 10:00 UTC genau der gleiche Zeitpunkt wie für den australischen. Um 10:00 UTC mag es ja in USA (MST) 3:00am sein während es in australien ca 19:00 ist. Wenn aber zum gleichen Zeitpunkt beide die UTC berrechnen lassen, dann kriegen beide als Ergebnis 10:00 UTC.

Für die Kommunikation zwischen Server und CLient sowie die Datenhaltung auf dem Server muss halt alles in UTC laufen. Lokal auf den Clients rechnet mann dann aber immer von UTC nach localtime um so das die User immer die Zeitangaben in ihrere eigenen localtime sehen.
 
Ich weiss, dass gmtime() die GMT oder UTC Zeit ausgibt und somit überall gleich ist, darum will ich sie ja verwenden.
Allerdings habe ich selber auch das Gefühl, dass ich etwas Grundlegendes übersehe, wenn ich nur wüsste was?

Ich kann an beliebiger Stelle jede beliebige time_t variable zu tm* konvertieren und mit gmtime() daraus einen string generieren, aber rückwärts gehts nicht mehr.
Egal was ich mit tm* oder meinem string anstelle, ich bekomme in keinem Fall einen int oder long Wert raus, mit dem ich irgendwas ausrechnen könnte.

Dazu kommt noch, dass PC Uhren in den seltensten Fällen genau gehen, wenn ich also difftime() von der localtime des Users und der des Servers nehme, bekomme ich so gut wie nie eine volle Stunde raus.

Wenn du sagst, localtime = utc + offset der Zeitzone dann liest sich das ja prima, fürs menschliche Hirn ist das leicht zu verstehen, aber wenn am Server ein char* mit dem Inhalt: "2009-01-01T18:00:00" ankommt, dann ist das Einzige was ich zuerst mal damit anstellen kann eine string operation, wie substr() oder getline(), von time_t oder int oder long, mit dem man rechnen könnte bin ich da weit entfernt.

Noch genauer gesagt, wenn ich mich nicht auf ungenaue PC Uhren verlassen will, darf ich keinerlei localtime verwenden, sondern muss die aktuelle Uhrzeit des Servers zu GMT konvertieren und das als Richtwert für alle nehmen, egal wieviel die von der genauen Zeit abweicht.
Ich muss vom einem User dessen localtime ich nicht berücksichtigen darf eine GMT time eingeben lassen, die von Anfang bis Ende GMT time bleibt.

Ich habe also eine aktuelle GMT time und eine Countdown GMT time, die zuerst als char* über einen socket geht, und muss dann aus den beiden strings den Zeitunterschied berechnen.
 
Zurück