Unix zeiten unterschiedlich

Gast #6630250
Lesenswert?

Guten abend,
ich rufe mit einem ESP32 die UNIX zeit via ntp ab und rechne diese dann 
in unserer Lokaler UTC-Zeit um.
1
static void initialize_sntp(void)
2
{
3
    static const char *TAG = "initizalize_sntp";
4
    ESP_LOGI(TAG, "Initializing SNTP");
5
    sntp_setoperatingmode(SNTP_OPMODE_POLL);
6
    sntp_setservername(0, "de.pool.ntp.org");
7
    //sntp_set_sync_interval(3600000);
8
    sntp_set_sync_interval(20000);
9
    sntp_set_time_sync_notification_cb(timeSyncNotificationCb);
10
    sntp_init();
11
    ntpState_e = NTP_INITIATING;
12
}
13

14
static void timeSyncNotificationCb(struct timeval *tv)
15
{
16
    static const char *TAG = "time sync cb";
17
    unixTime = tv->tv_sec; /* copy unix seconds to global variable */
18
    ESP_LOGI(TAG, "Notification of a time synchronization event: %ld", tv->tv_sec); /* unix time seconds */
19
    ntpState_e = NTP_VALID;
20
}
1
...
2
    while(1)
3
    {
4
        vTaskDelayUntil(&xLastWakeTime, CYCLE_RATE_MS);
5

6
        if(1 == getWifiState())
7
        {
8
            switch(ntpState_e)
9
            {
10
                case NTP_UNINITIATED: initialize_sntp(); break;
11
                case NTP_INITIATING: ntpState_e = NTP_INITIATED; break;
12
                case NTP_INITIATED:
13
                case NTP_VALID:
14
                {
15
                    time(&unixTime);
16
                    localtime_r(&unixTime, &utcTime);
17
                    convertUtcToLocalTimeDate(&utcTime);
18
                    ESP_LOGI(TAG, "time: %d:%d:%d  %d.%d.%d", utcTime.tm_hour, utcTime.tm_min, utcTime.tm_sec, utcTime.tm_mday, utcTime.tm_mon + 1, utcTime.tm_year + 1900);
19
                    break;
20
                }
21
            }
22
        }
23
        else
24
        {
25
            ntpState_e = 0;
26
        }
27
 ...
In der funktion "convertUtcToLocalTimeDate" berechne ich die lokale Zeit 
hier in Deutschland.
Das berechnen passt auch alles.

Was mir aber aufgefallen ist, dass wenn ich nebenbei noch meine Uhr am 
PC offen habe, dass diese ~3 Sekunden weiter ist.
Und wenn ich mir die Unix zeit auf https://www.unixtimestamp.com/ 
ansehe, ist diese ~3 sekunden zurück.

Woher kommt dieser doch etwas größere Zeitunterschied?

Welche ist die richtige?
Gast #6630257
Lesenswert?

Vielleicht gleicht die NTP Implementierung auf dem µC die Laufzeit des 
Signals nicht aus. Dann wäre es allerdings nur eine sehr billigen halbe 
Implementierung.

Was ist mit den unregelmäßigen Schaltsekunden, werden die 
berücksichtigt? Ist die Liste dieser amtlich angeordneten Schaltsekunden 
auf aktuellem Stand?
#6630323
Lesenswert?

Was läuft denn eigentlich auf dem PC? Normalerweise zeigt ein ntp-client 
doch den Fehler der PC-Uhr relativ zur NTP-Zeit an (z.B. ntpq -pn)?
Und woher stammen time() und localtime_r()? Bei den POSIX-Funktionen ist 
ganz klar geregelt, wo Schaltsekunden verarbeitet werden; nämlich 
garnicht, weil die in der Unix-Zeit sozusagen eingebaut sind.

Eine amtliche Liste der Schaltsekunden braucht man (nur), wenn man die 
Rechneruhr (also die Unix-Zeit) auf TAI statt auf UTC synchronisiert. 
Aber wer macht das schon freiwillig ;)

Johannes schrieb:
> Aber wenn nicht, müssten es doch mehr als 3 Sekunden sein oder?

Nein. Um UTC aus TAI oder GPS-Zeit abzuleiten, brauchst du eine Liste. 
Wenn die ca. 5 Jahre alt ist, fehlen in der Liste die letzten 3 
Schaltsekunden. Das passiert gerne mit alten GPS-Empfängern, aber nicht 
mit NTP.

Johannes schrieb:
1
> unixTime = tv->tv_sec; /* copy unix seconds to global variable */
da bekommst du doch die NTP-Zeit. Aber dann überschreibst du sie wieder 
mit der Rechner-Zeit. Muss ich das verstehen?
1
>                     time(&unixTime);
2
>                     localtime_r(&unixTime, &utcTime);
3
>                     convertUtcToLocalTimeDate(&utcTime);
was macht eigentlich dieses convert? localtime_r() liefert doch schon 
unsere lokale Zeit? Was geht da vor?
Gast #6630710
Lesenswert?

Bauform B. schrieb:
> Johannes schrieb:> unixTime = tv->tv_sec; /* copy unix seconds to global
> variable */
> da bekommst du doch die NTP-Zeit. Aber dann überschreibst du sie wieder
> mit der Rechner-Zeit. Muss ich das verstehen?

Also hier bekomme ich die ntp-zeit und speichere sie mir in einer 
globalen vairable (zum einen zur initialisierung und zum anderen zum 
update)

Bauform B. schrieb:
>>                     time(&unixTime);
>>                     localtime_r(&unixTime, &utcTime);
>>                     convertUtcToLocalTimeDate(&utcTime);
> was macht eigentlich dieses convert? localtime_r() liefert doch schon
> unsere lokale Zeit? Was geht da vor?

localtime_r bestimmt ja nur die UTC-Zeit (+-0 Stunden).
mit convertUtcToLocalTimeDate berechne ich die Zeit hier. Hier sind wir 
ja eine Stunde weiter.
Also addiere ich quasi eine Stunde und überprüfe dann noch ob es der 
selbe Tag ist usw.
Gast #6631494
Lesenswert?

Bauform B. schrieb:
> Nein. Um UTC aus TAI oder GPS-Zeit abzuleiten, brauchst du eine Liste.
> Wenn die ca. 5 Jahre alt ist, fehlen in der Liste die letzten 3
> Schaltsekunden. Das passiert gerne mit alten GPS-Empfängern, aber nicht
> mit NTP.

Unsinn.
Das GPS überträgt die aktuelle Anzahl der Schaltsekunden mit den 
Almanachdaten. Eine eventuell im Empfänger vorhandene Liste interessiert 
allenfalls nach einem Kaltstart bis zum Empfang des betreffenden 
Datenblocks.
#6634666
Lesenswert?

Thomas G. schrieb:
> Ich habe mich allerdings auch schon mal gefragt, wie das mit den
> Schaltsekunden & UNIX-Zeit genau läuft.

Ganz einfach: die UNIX Time kennt Schaltsekunden genausowenig wie 
Windows.
Ohne Synchronisation geht die Zeit ab der Schaltsekunde einfach eine 
Sekunde vor.

Mit SNTP (simple NTP wie z.B: beim genannten ESP32): bei der nächsten 
Synchronisation tritt ein 1s Sprung auf (rückwärts), d.h. es gibt eine 
Sekunde dann doppelt.

Mit NTP gibt es mehrere Möglichkeiten.
A) Der NTP Client kennt die Schaltsekunde und hat kein LeapSmear 
konfiguriert, dann läuft die Zeit 2s lang nur halb so schnell
B) Der NTP Client kennt die Schaltsekunde und hat LeapSmear aktiviert, 
dann wird die Zeit weich angeglichen, d.h. die Sekunde wird über 1 bis 
24 Stunden verschmiert.
C) Der NTP Client hat keine Kenntnis der Schaltsekunde, dann wird nach 
ein paar Synchronisationsintervallen ein Sprung durchgeführt 
durchgeführt, da die Differenz über 128 ms beträgt.
D)  ....

Ist das wichtig? Ja, durch falsche Handhabung sind am 1.7.2012 Millionen 
von Linux Rechnern Amok gelaufen:
https://www.heise.de/ct/ausgabe/2015-14-Wie-Technik-mit-der-Schaltsekunde-am-30-Juni-umgeht-2681775.html

  Michael

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren