Differenz zur echten Uhrzeit in Sekunden ermitteln
Hi,
ich versuche mit TIdTime die Differenz zur wirklichen, aktuellen Uhrzeit ermitteln. Dafür will ich TIdTime nutzen: Ich ziehe mir die aktuelle Uhrzeit auf dem Rechner und die aktuelle Uhrzeit von TIdTime. Jetzt habe ich auf einem iOS und einem Android-Device rund 2 Stunden-Unterschied, d.h. läuft noch irgendwas mit den Zeitzonen falsch. Auf einem Rechner, der bei manueller Prüfung auf die Sekunde die gleiche Uhrzeit wie ein anderer hat, bekomme ich 30 Sekunden Unterschied raus. Was mache ich hier falsch? Muss man andere TIdTime-Methoden nutzen? Ich würde ungerne die Systemzeit selbst durch diesen Check anpassen.
Delphi-Quellcode:
Grüße, Philipp
procedure TicTrainerF.syncTime();
var idTime:TIdTime; dtLocal,dtServer:TDateTime; msDiff:Int64; begin idTime:=TIdTime.create(nil); try idTime.Host:='time.nist.gov'; dtServer:=idTime.dateTime; if (dtServer>0) then begin dtLocal:=NOW; msDiff:=MillisecondsBetween(dtServer,dtLocal); if (dtLocal>dtServer) then syncTimeDiff:=msDiff*-1 else syncTimeDiff:=msDiff; mlog.info('syncTime '+FloatToStrF(syncTimeDiff/1000,ffFixed,8,3,myFormatSettings)+'s'); end else begin mlog.info('syncTime not possible²'); syncTimeDiff:=0; end; finally hideHourGlass(); idTime.free; end; except on E: Exception do begin mlog.info('syncTime not possible'); syncTimeDiff:=0; end; end; end; |
AW: Differenz zur echten Uhrzeit in Sekunden ermitteln
Kenne mich mit TimeServern nicht so aus, aber kann es sein das man die Timezone bei der Anfrage mit angeben muss ?
Ich würde normalerweise UTC vermuten, die 2h deuten ja etwas darauf hin. Schau doch mal was TIdTime wirklich macht. |
AW: Differenz zur echten Uhrzeit in Sekunden ermitteln
Rein von der Doku her muss man keine Zeitzone mitgeben und bei meinen beiden Windows-Möhren geht es auch so, nur unter Android und iOS passiert etwas anderes:
TIdTime.DateTime:
TIdTime.SyncTime:
Werde ich wahrscheinlich mal den Indy-Code anschauen müssen. |
AW: Differenz zur echten Uhrzeit in Sekunden ermitteln
Zitat:
Hatte das gleiche Problem letztens mit meinem Video Player. |
AW: Differenz zur echten Uhrzeit in Sekunden ermitteln
Zitat:
|
AW: Differenz zur echten Uhrzeit in Sekunden ermitteln
Ja, die Zeitzone stimmt auf den Geräten. Ich habe auch schon überlegt als Zeitdifferenz nur
Delphi-Quellcode:
zu nehmen, aber wie gesagt, dann kommen bei einem Device 30 Sekunden Differenz raus, obwohl die Uhrzeit ziemlich genau die gleiche ist (maximal +/- 1 Sekunde). Da baue ich mal noch ein paar mehr Loggings ein, vielleicht braucht er auch so lange um den Time-Server abzufragen, dann wäre es eh unbrauchbar für die Differenzen auf Sekundenebene einzustellen.
msDiff:=MillisecondsBetween(dtServer,dtLocal) mod 3600000;
Das es wohl bei 2 Stunden UTC sein sollte, ist mir klar, weiß ich aber ja auch nur, weil ich es hier bei mir in Deutschland aufrufe. Mir ist noch unklar, wie ich daraus eine allgemein gültige Regel machen sollte, da es bei meinen Windows-Geräten stimmt. Einem TDateTime sieht man ja die Zeitzone nicht an. |
AW: Differenz zur echten Uhrzeit in Sekunden ermitteln
Hallo,
falls du hier keine weiterführenden ANtworten bekommnst könntest du mal in der EN DP posten (ich vermute du kannst Englisch), da liest m.w. zumindest einer der Indy Entwickler mit! Grüße TurboMagic |
AW: Differenz zur echten Uhrzeit in Sekunden ermitteln
Vielleicht ist das die Lösung ?
https://stackoverflow.com/questions/...-via-all-hosts |
AW: Differenz zur echten Uhrzeit in Sekunden ermitteln
Danke für den Tipp mit dem englischen DP. Habe ich mal gemacht.
Anbei mal meine aktuellen Testergebnisse (MacOS fehlt noch), wie man sieht springt insbesondere Android auf einem Amazon-Tablet (FireHD 10) komplett aus der Reihe, da stimmt jetzt mal gar nichts. Vorne sieht man immer die Uhrzeit vor und nach der Abfrage und danach das Ergebnis der Abfrage: incorrect (timezone): --------------------- syncTime (Android): 2021-01-18 16:24:50.789-16:24:51.169 vs 2021-01-18 14:24:51.000 syncTime (Android): 2021-01-18 16:24:48.071-16:24:48.428 vs 2021-01-18 14:24:49.000 syncTime (iOS): 2021-01-18 16:24:49.658-16:24:49.996 vs 2021-01-18 14:24:50.000 incorrect (at all): ------------------- syncTime (FireOS/Android): 2021-01-18 16:24:48.606-16:24:49.028 vs 2021-01-18 14:40:02.000 correct: -------- syncTime (Windows): 2021-01-18 16:24:47.612-16:24:48.359 vs 2021-01-18 16:24:48.000 syncTime (Windows): 2021-01-18 16:24:46.014-16:24:46.771 vs 2021-01-18 16:24:47.000 |
AW: Differenz zur echten Uhrzeit in Sekunden ermitteln
Hallo Phillip,
womit hast Du denn vorher Alles getestet, auch hiermit ? (TTimeZone.Local.ToLocalTime, TTimeZone.Local.ToUniversalTime) |
AW: Differenz zur echten Uhrzeit in Sekunden ermitteln
Zitat:
|
AW: Differenz zur echten Uhrzeit in Sekunden ermitteln
Wie gesagt, es wäre auch nicht mein bevorzugter Weg die Uhrzeit auf dem Rechner zu synchronisieren. Ich dachte mir auch schon, dass dies sicherlich aus Berechtigungsgründen nicht geht.
Ich gebe jetzt mal noch zusätzlich in meinem Output TTimeZone.Local.ToUniversalTime(...) aus, damit ich ausschließe, dass es hier ein falsches Setting auf den einzelnen Rechnern/Tablets gibt. |
AW: Differenz zur echten Uhrzeit in Sekunden ermitteln
Man muß auch nicht unbedingt direkt die Uhr ändern.
Bei uns wird die Serverzeit abgefragt und mit der lokalen Zeit die Differenz gebildet. (beim Start und regelmäßig zwischendrin, während der Connectionchecks, wegen der Schaltjahre, Schaltsekunden und sonstwas) Die meisten Operationen laufen in der Datenbank ab, also mit der Serverzeit, wellche sich selbst über einen Timeserver updated (current_time im SELECT/INSERT/UPDATE, anstatt Now über Parameter), aber für Anzeigen im Programm, welche z.B. lokal über Now bestimmt wurden, da wird dann einfach diese Differenz hinzugerechnet, damit das mit der Serverzeit in etwa übereinstimmt, egal was die Uhr im Rechner sagt. |
AW: Differenz zur echten Uhrzeit in Sekunden ermitteln
Ja, genau dies mache ich ja in meiner App genauso. Das Problem ist ja nur, dass ich mich darauf verlassen muss, dass ich auf jedem Device die Differenz zur gleichen Basis bilden kann. Und genau dies scheint bei TIdTime nicht der Fall zu sein, es klappt nur bei Windows so wie beschrieben. Ich würde mich ja auch noch zu Code hinreißen lassen, wo ich dann für MacOS, iOS und Android eine andere Basis (UTC) benutze. Aber wie man am Beispiel meines Amazon FireHD-Tablets sieht, ist die Differenz dort nochmals komplett eine andere.
|
AW: Differenz zur echten Uhrzeit in Sekunden ermitteln
So ich habe mich jetzt mal durch Indy-debuggt, der Fehler passierte inIdGlobalProtocols.TimeZoneBias:
Delphi-Quellcode:
Keine Ahnung, warum die so kompliziert implementiert ist, ich habe es mal mit folgendem Code ersetzt:
function TimeZoneBias: TDateTime;
{$IFNDEF FPC} {$IFDEF UNIX} var T: Time_T; TV: TimeVal; UT: {$IFDEF USE_VCL_POSIX}tm{$ELSE}TUnixTime{$ENDIF}; {$ELSE} {$IFDEF USE_INLINE} inline; {$ENDIF} {$ENDIF} {$ELSE} {$IFDEF USE_INLINE} inline; {$ENDIF} {$ENDIF} begin {$IFNDEF FPC} {$IFDEF UNIX} {from http://edn.embarcadero.com/article/27890 } gettimeofday(TV, nil); T := TV.tv_sec; localtime_r({$IFNDEF USE_VCL_POSIX}@{$ENDIF}T, UT); // __tm_gmtoff is the bias in seconds from the UTC to the current time. // so I multiply by -1 to compensate for this. Result := (UT.{$IFNDEF USE_VCL_POSIX}__tm_gmtoff{$ELSE}tm_gmtoff{$ENDIF} / 60 / 60 / 24); {$ELSE} ...
Delphi-Quellcode:
Zumindest für Google-Android und iOS funktioniert es jetzt. Für Amazon-FireOS-Android scheint es noch ein weiteres Problem zu geben, dies ignoriere ich jetzt mal und setze die Differenz auf 0.0s.
function TimeZoneBias: TDateTime;
{$IFNDEF FPC} {$IFDEF UNIX} var nowDt:TDateTime; {$ELSE} {$IFDEF USE_INLINE} inline; {$ENDIF} {$ENDIF} {$ELSE} {$IFDEF USE_INLINE} inline; {$ENDIF} {$ENDIF} begin {$IFNDEF FPC} {$IFDEF UNIX} nowDt:=NOW; Result := TTimeZone.Local.ToUniversalTime(nowDt)-nowDt; {$ELSE} ... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:54 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz