Forum: Mikrocontroller und Digitale Elektronik Unix zeiten unterschiedlich


von Johannes (Gast)


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?

von Stefan F. (Gast)


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?

von Johannes (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Was ist mit den unregelmäßigen Schaltsekunden, werden die
> berücksichtigt?

ich bin mir nicht ganz sicher, ob diese in der Funktion
time(&unixTime);
bzw.
localtime_r(&unixTime, &utcTime);
berücksichtigt werden.

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

von Bauform B. (bauformb)


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?

: Bearbeitet durch User
von Johannes (Gast)


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.

von Bastler_HV (Gast)


Lesenswert?

Eine sehr schöne Webseite ist

   https://uhr.ptb.de/

In der Uhr auf Abweichung clicken, dann sieht man wie genau der Rechner 
ist.
Ich weiss aber nicht woher die Zeit kommt, ob von der PTB selbst oder 
nicht nur ntp.

von Thomas G. (Firma: Frickelhauptquartier) (taximan)


Angehängte Dateien:

Lesenswert?

Und jetzt?

von Karl (Gast)


Lesenswert?

Thomas G. schrieb:
> Und jetzt?

Bist du nicht der TO und wir wissen immer noch nicht, ob seine PC-Uhr 
richtig geht. Annahme, Website und EPS zeigen 3 Sekunden weniger als der 
PC, Website zeigt gleiche Zeit wie mein (Unix)-PC -> Zeitanzeige auf dem 
PC vom TO ist falsch.

von Dirk B. (dirkb2)


Lesenswert?

Bastler_HV schrieb:
> Ich weiss aber nicht woher die Zeit kommt, ob von der PTB selbst oder
> nicht nur ntp.

Ja.

Mehr unter https://oar.ptb.de/files/download/5e1d7c744c93907cfc00698b

von foobar (Gast)


Lesenswert?

> localtime_r bestimmt ja nur die UTC-Zeit (+-0 Stunden).

Klar, deshalb heißt sie ja auch *local*time.  Wenn du vorher allerdings 
nicht die Zeitzone setzt ...

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/system_time.html#timezones

von Dirk B. (dirkb2)


Lesenswert?

Karl schrieb:
> Zeitanzeige auf dem
> PC vom TO ist falsch.

Windows scheitert auch mal bei der Nachfrage beim Server.
Irgendwo steht dann aber, wann die letzte Synchronisation erfolgte.

von Stefan F. (Gast)


Lesenswert?

Thomas G. schrieb:
> Und jetzt?

Meine geht 3ms vor.

von Wolfgang (Gast)


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.

von Thomas G. (Firma: Frickelhauptquartier) (taximan)


Lesenswert?

OK, ich hätte dabei schreiben können, dass das unterwegs auf dem Handy 
war. Meine PC-Uhr geht aktuell 0,5 sec vor.

NTP-Zeit kann man auch einfacher haben:
https://werner.rothschopf.net/201802_arduino_esp8266_ntp.htm

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

: Bearbeitet durch User
von Michael D. (nospam2000)


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

: Bearbeitet durch User
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.