Forum: PC-Programmierung Unixtime zu Localtime OHNE Library


von Alex (Gast)


Lesenswert?

Moin,

Ich habe eine IOT Anwendung, wo das Gerät die UTC-Zeit per NTP aus dem 
Internet bekommt. Dieser Zeitstempel ist im 32bit unixtime format. Ich 
brauche jetzt allerdings die Zeit in Deutschland unter Berücksichtigung 
der Sommer/Winterzeit (auch als unixtime).
Bevor ich jetzt anfange aus den Zeitumstellungs-Regeln mir selbst etwas 
zu basteln - da gibt es doch sicher eine kompakte schlaue Formel für die 
Umrechnung! Hat die wer parat?
Ich habe in meiner Anwendung übrigens keine Library mit 
"UnixTimeToLocalTime" zur Verfügung - also ich brauche wirklich die 
Umrechnung.

Beispiel unixtime=1571740368 (also 22/10/2019,10:32:48) während es hier 
12:32 ist.

Danke & schönen Gruß,
Alex

von Bauform B. (bauformb)


Lesenswert?

Für eine Formel müsste man die Zukunft vorhersagen können. Der Vorteil 
dabei ist, dass du genauso gut eine Tabelle einbauen kannst. Ohne 
Update-Möglichkeit geht beides nicht, falls die Politiker sich etwas 
neues einfallen lassen.

Die Tabelle enthält die Zeitpunkte (32-Bit-Unixtime) zu denen sich etwas 
ändert und den Offset zur NTP-Zeit, der ab dem Zeitpunkt gilt. Der Rest 
ist ein Vergleich in einer Schleife und eine Addition. Die Länge der 
Tabelle richtet sich nach der geplanten Lebensdauer des Geräts ;)

Das sind normalerweise 2 mal zwei 32-Bit-Worte pro Jahr. Wenn man davon 
ausgeht, dass hier nur ganze Stunden vorkommen, kann man beide Werte in 
ein Wort packen. Evt. reichen sogar 24 Bit pro Zeitpunkt.

Als Bonus wird damit auch gleich die Zeitzone erschlagen. Wenn die 
umschaltbar sein soll, muss man aber eine Tabelle pro Zeitzone vorsehen, 
weil natürlich jedes Land jederzeit seine eigenen Regeln machen kann.

von P. S. (sandl)


Lesenswert?

Wikipedia hat da unter "Beispiel-Implementierung" eine solche 
Umrechnung:
https://de.wikipedia.org/wiki/Unixzeit

von Pandur S. (jetztnicht)


Lesenswert?

Zeitzonen .. ein Alptraum. Es gibt nebenbei auch Zeitzonen mit Halb- und 
Viertelstunden Versatz.
Vereinfacht, der Zusammenhang zum Laengengrad ist zufaellig.

von Alex (Gast)


Lesenswert?

Bauform B. schrieb:
> Für eine Formel müsste man die Zukunft vorhersagen können. Der Vorteil
> dabei ist, dass du genauso gut eine Tabelle einbauen kannst. Ohne
> Update-Möglichkeit geht beides nicht, falls die Politiker sich etwas
> neues einfallen lassen.

Ich würde mich da an die derzeit gültige Regel halten und bin kein Fan 
Tabellen, bis ich die erstellt hätte, hätte ich auch selbst den 
Algorithmus zusammengestrickt.
Die geltende Regel ist wohl 
http://www.zeitumstellung.de/regeln-zeitumstellung.html

§ 2

(1) Die mitteleuropäische Sommerzeit beginnt jeweils am letzten Sonntag 
im März um 2 Uhr mitteleuropäischer Zeit. Im Zeitpunkt des Beginns der 
Sommerzeit wird die Stundenzählung um eine Stunde von 2 Uhr auf 3 Uhr 
vorgestellt.

(2) Die mitteleuropäische Sommerzeit endet jeweils am letzten Sonntag im 
Oktober um 3 Uhr mitteleuropäischer Sommerzeit. Im Zeitpunkt des Endes 
der Sommerzeit wird die Stundenzählung um eine Stunde von 3 Uhr auf 2 
Uhr zurückgestellt. Die Stunde von 2 Uhr bis 3 Uhr erscheint dabei 
zweimal. Die erste Stunde (von 2 Uhr bis 3 Uhr mitteleuropäischer 
Sommerzeit) wird mit 2 A und die zweite Stunde (von 2 Uhr bis 3 Uhr 
mitteleuropäischer Zeit) mit 2 B bezeichnet.

Philipp S. schrieb:
> Wikipedia hat da unter "Beispiel-Implementierung" eine solche
> Umrechnung:
> https://de.wikipedia.org/wiki/Unixzeit

Themaverfehlung

Joggel E. schrieb:
> Zeitzonen .. ein Alptraum. Es gibt nebenbei auch Zeitzonen mit Halb- und
> Viertelstunden Versatz.
> Vereinfacht, der Zusammenhang zum Laengengrad ist zufaellig.

Es geht mir ja zum Glück nur um die in Deutschland.

schönen Gruß,
Alex

von Nick M. (Gast)


Lesenswert?

Nur UTC verwenden.
Die unsinnige (aus Sicht der Datenverarbeitung) Umrechnung in Lokalzeit 
erst im allerletzen Moment am Server vornehmen, wenn die Daten angezeit 
werden sollen. Alles Andere führt nur ins Unheil.
Was passiert, wenn auf dem IoT-Dingens plötzlich die Zeit umspringt aber 
eine Aktion alle X Zeiteinheiten ausgeführt werden soll? Das geht sogar 
so weit, dass nicht mal UTC für so was geeignet ist.

Nick

von Bauform B. (bauformb)


Lesenswert?

Alex schrieb:
> Ich würde mich da an die derzeit gültige Regel halten und bin kein Fan
> Tabellen, bis ich die erstellt hätte, hätte ich auch selbst den
> Algorithmus zusammengestrickt.

Geschenk:
1
typedef struct /* trans_struct */ {
2
   uint32_t  time;
3
    int32_t  gmtoff;
4
} trans_struct;
5
6
static const trans_struct  translist[] = {
7
   {  2140045200,   3600 },  //  8  Sun Oct 25 01:00:00 2037
8
   {  2121901200,   7200 },  //  7  Sun Mar 29 01:00:00 2037
9
   {  2108595600,   3600 },  //  8  Sun Oct 26 01:00:00 2036
10
   {  2090451600,   7200 },  //  7  Sun Mar 30 01:00:00 2036
11
   {  2077146000,   3600 },  //  8  Sun Oct 28 01:00:00 2035
12
   {  2058397200,   7200 },  //  7  Sun Mar 25 01:00:00 2035
13
   {  2045696400,   3600 },  //  8  Sun Oct 29 01:00:00 2034
14
   {  2026947600,   7200 },  //  7  Sun Mar 26 01:00:00 2034
15
   {  2014246800,   3600 },  //  8  Sun Oct 30 01:00:00 2033
16
   {  1995498000,   7200 },  //  7  Sun Mar 27 01:00:00 2033
17
   {  1982797200,   3600 },  //  8  Sun Oct 31 01:00:00 2032
18
   {  1964048400,   7200 },  //  7  Sun Mar 28 01:00:00 2032
19
   {  1950742800,   3600 },  //  8  Sun Oct 26 01:00:00 2031
20
   {  1932598800,   7200 },  //  7  Sun Mar 30 01:00:00 2031
21
   {  1919293200,   3600 },  //  8  Sun Oct 27 01:00:00 2030
22
   {  1901149200,   7200 },  //  7  Sun Mar 31 01:00:00 2030
23
   {  1887843600,   3600 },  //  8  Sun Oct 28 01:00:00 2029
24
   {  1869094800,   7200 },  //  7  Sun Mar 25 01:00:00 2029
25
   {  1856394000,   3600 },  //  8  Sun Oct 29 01:00:00 2028
26
   {  1837645200,   7200 },  //  7  Sun Mar 26 01:00:00 2028
27
   {  1824944400,   3600 },  //  8  Sun Oct 31 01:00:00 2027
28
   {  1806195600,   7200 },  //  7  Sun Mar 28 01:00:00 2027
29
   {  1792890000,   3600 },  //  8  Sun Oct 25 01:00:00 2026
30
   {  1774746000,   7200 },  //  7  Sun Mar 29 01:00:00 2026
31
   {  1761440400,   3600 },  //  8  Sun Oct 26 01:00:00 2025
32
   {  1743296400,   7200 },  //  7  Sun Mar 30 01:00:00 2025
33
   {  1729990800,   3600 },  //  8  Sun Oct 27 01:00:00 2024
34
   {  1711846800,   7200 },  //  7  Sun Mar 31 01:00:00 2024
35
   {  1698541200,   3600 },  //  8  Sun Oct 29 01:00:00 2023
36
   {  1679792400,   7200 },  //  7  Sun Mar 26 01:00:00 2023
37
   {  1667091600,   3600 },  //  8  Sun Oct 30 01:00:00 2022
38
   {  1648342800,   7200 },  //  7  Sun Mar 27 01:00:00 2022
39
   {  1635642000,   3600 },  //  8  Sun Oct 31 01:00:00 2021
40
   {  1616893200,   7200 },  //  7  Sun Mar 28 01:00:00 2021
41
   {  1603587600,   3600 },  //  8  Sun Oct 25 01:00:00 2020
42
   {  1585443600,   7200 },  //  7  Sun Mar 29 01:00:00 2020
43
   {  1572138000,   3600 },  //  8  Sun Oct 27 01:00:00 2019
44
   {  1553994000,   7200 },  //  7  Sun Mar 31 01:00:00 2019
45
   {  1540688400,   3600 },  //  8  Sun Oct 28 01:00:00 2018
46
   {  1521939600,   7200 },  //  7  Sun Mar 25 01:00:00 2018
47
   {  1509238800,   3600 },  //  8  Sun Oct 29 01:00:00 2017
48
   {  1490490000,   7200 },  //  7  Sun Mar 26 01:00:00 2017
49
   {  1477789200,   3600 },  //  8  Sun Oct 30 01:00:00 2016
50
   {           0,   3600 },  //  8
51
};
"trans" steht für "transition time".

von Daniel B. (dbuergin)


Lesenswert?

Habe vor 11 Jahren (uiii...) mal etwas gebaut/angepasst und gepostet:
Beitrag "GPS Uhr: UTC > MESZ umrechnung"
In der Zip Datei sind zwei Files mit Routinen zum arbeiten mit 
Timestamps.

Für Dich wäre wohl die Routine gettime(..) die Funktion der Wahl, 
rechnet einen Timestamp in eine Date/Time Struktur um. Damit hast Du 
Datum/Zeit für MESZ.

G.D.

von DPA (Gast)


Lesenswert?

Nutze die weltweit überall verwendete TZ datenbank, alles andere ist 
murks. Ist sogar code dabei:

https://en.wikipedia.org/wiki/Tz_database
https://www.iana.org/time-zones

von Marten Morten (Gast)


Lesenswert?

Nick M. schrieb:
> Nur UTC verwenden.

Genau das.

Nie-nicht irgendwas in lokaler Zeit in einem Gerät machen oder 
berechnen. Nie-nicht Daten in lokaler Zeit speichern oder übertragen. 
Lokale Zeit ist nur zur Anzeige und Eingabe für einem Benutzer. Innen 
immer UTC.

Bauform B. schrieb:
> Geschenk:
1
> typedef struct /* trans_struct */ {
2
>    uint32_t  time;
3
>     int32_t  gmtoff;
4
> } trans_struct;
5
> 
6
> static const trans_struct  translist[] = {
7
>    {  2140045200,   3600 },  //  8  Sun Oct 25 01:00:00 2037
8
...
9
> };
> "trans" steht für "transition time".

Kannst du neu machen (alle betroffenen IoT Geräte updaten/flashen) wenn 
es die EU schafft die Zeitumstellung vielleicht doch irgendwann nach 
2021 abzuschaffen. Dann musst du den Toolchain wieder finden und zum 
Laufen bekommen, den Sourcecode ausgraben, passenden Programmer finden 
usw. Ich kann dir sagen, bei der letzten Veränderung 1996 in Deutschland 
war das schon nicht lustig.

Außerdem hast du keine historischen Daten vor 2016 drin. Je nach 
Anwendung kann das schief gehen.

Ich empfehle zum Verständnis des Problems immer sich die Zeitzonen-Daten 
wie sie in Unix verwendet herunter zu laden 
https://data.iana.org/time-zones/releases/tzdata2019c.tar.gz Es geht 
nicht darum die Daten so zu verwenden, sondern einfach mal die 
Kommentare in den Dateien zu lesen, zum Beispiel in der noch relativ 
harmlosen Datei "europe". Es ist ein einziges historisches Chaos und es 
beißt einen früher oder später immer in den Arsch.

von Alex (Gast)


Angehängte Dateien:

Lesenswert?

Nick M. schrieb:
> Nur UTC verwenden.
> Die unsinnige (aus Sicht der Datenverarbeitung) Umrechnung in Lokalzeit
> erst im allerletzen Moment am Server vornehmen, wenn die Daten angezeit
> werden sollen. Alles Andere führt nur ins Unheil.
> Was passiert, wenn auf dem IoT-Dingens plötzlich die Zeit umspringt aber
> eine Aktion alle X Zeiteinheiten ausgeführt werden soll? Das geht sogar
> so weit, dass nicht mal UTC für so was geeignet ist.

Da schau her, der Müllernick! Servus Nick :D

Es geht leider um die unsinnige Funktion eines halbwegs ordinären 
Weckers und da ist die UTC unsinnig. Wenn der Wecker z.B. 
Täglich/Wöchentlich zur gleichen Uhrzeit schlagen soll ist das natürlich 
am einfachsten in Lokaler Zeit und auch sonst interessiert mich nur die 
lokale Zeit. Umspringen ist kein Problem - eigentlich ja sogar 
gewünscht.
Die UTC ist nur im Spiel weil ich die halt so vom NTP bekomme - ich 
möchte also auf jeden fall umrechnen.

Bauform B. schrieb:
> Geschenk:

Danke für deine Mühe! Ich hoffe du nimmst es mir nicht übel, dass ich 
stattdessen einen zusammengeschusterten Spaghetticode nutze? :D

Daniel B. schrieb:
> Für Dich wäre wohl die Routine gettime(..) die Funktion der Wahl,
> rechnet einen Timestamp in eine Date/Time Struktur um. Damit hast Du
> Datum/Zeit für MESZ.

Danke!
Die "void summertime( volatile DATETIME_T *t )" hat mir geholfen!!!


DPA schrieb:
> Nutze die weltweit überall verwendete TZ datenbank, alles andere ist
> murks. Ist sogar code dabei:
Solche verallgemeinerungen halte ich für murks. Mein 8-Bit Controller 
hat für den Spaß vielleicht noch 2kB frei gehabt...


Marten Morten schrieb:
> Nie-nicht irgendwas in lokaler Zeit in einem Gerät machen oder
> berechnen. Nie-nicht Daten in lokaler Zeit speichern oder übertragen.
> Lokale Zeit ist nur zur Anzeige und Eingabe für einem Benutzer. Innen
> immer UTC.

Wie speicherst du denn eine Weckzeit, die natürlich Lokal gelten soll, 
also z.B. 8 Uhr egal im Sommer und Winter?



Das Problem ist jetzt mit der Routine von Daniel gelöst - vielen Dank 
nochmal!

schönen Gruß,
Alex

von Alex (Gast)


Lesenswert?

Wollte den source vom Post eigentlich wieder entfernen um Tumulte zu 
verhindern, aber jetzt ist er schon da.

Ist aus Wiki & Daniels Code zusammengeschnipselt - wer Spaghettikot 
findet darf ihn aufessen :D. (Und die Casterei ist nötig, ist kein GNU 
Compiler und kein 32Bit...)

schönen Gruß,
Alex

von Nick M. (Gast)


Lesenswert?

Achso, ein Wecker! Da ist UTC wirklich nicht angebracht.
Da würde ich DCF77 verwenden... (wenn empfangbar).

Gibts eigentlich einen "NTP-DCF77". Also ein NTP der die DCF77-Zeit 
verwendet? Wäre ja fast sinnvoll.

dcf77.ntp.org

Nick

von Nick M. (Gast)


Lesenswert?

Hmmm ...
Das da: https://www.worldtimeserver.com/current_time_in_DE.aspx
könnte man ja dazu verwenden. Hab jetzt auf die Schnelle nicht gefunden, 
ob die sowas wie einen ntp anbieten.
Und ich weiß nicht, ob die ihr HTML aus reiner Bosheit immer wieder 
ändern, damit das niemand auswertet.

Nick

von DPA (Gast)


Lesenswert?

Alex schrieb:
> DPA schrieb:
>> Nutze die weltweit überall verwendete TZ datenbank, alles andere ist
>> murks. Ist sogar code dabei:
> Solche verallgemeinerungen halte ich für murks. Mein 8-Bit Controller
> hat für den Spaß vielleicht noch 2kB frei gehabt...

Dann brauchst du eben nen grösseren Controller oder externen Speicher. 
TZ ist die einzige brauchbare & regelmässig geupdatete Datenbank, mit 
der man den Lokalzeit nonsens berechnen kann. Mit anderen Worten, 
verwendest du nicht immer die aktuelle TZ Datenbank, ist deine 
Zeitumrechnungsfunktion schlicht falsch. Das ist murks. Ob das in deinen 
Controller passt oder nicht, ist da völlig egal, das macht deine 
alternative Umrechnungsfunktion nicht richtiger. Aber wes solls, ist ja 
nicht mein wecker, wer dann bei der nächsten Änderung plötzlich die 
falsche Zeit anzeigt.

von Εrnst B. (ernst)


Lesenswert?

+1 für die Tabelle.

Kannst noch ein paar Jahre Rauskürzen, die EU will die Sommerzeitregel 
ja bis spätestens 2021 abstellen.

Und wenn du mit dem finalen Flashen noch bis nach dem WE wartest, kommt 
die Tabelle mit 4 Einträgen aus.

Problem: Noch steht nicht fest, ob danach für immer Sommerzeit oder 
Normalzeit herrschen soll...

Wenn es ganz superkorrekt sein soll: Lass die Tabelle automatisiert aus 
der aktuellen TZ-Datenbank erstellen, dann kann dein Build-System 
automatisch binaries für alle möglichen Zeitzonen erstellen.

Und Self-Update-Fähigkeiten sind für IOT-Geräte eigentlich sowieso ein 
Muss, nicht erst seit Mirai & co.


Was danach irgendwann ein Problem wird:

Alex schrieb:
> Dieser Zeitstempel ist im 32bit unixtime format.

Soll das als erzwungenes Verfallsdatum dienen, oder hält das Gerät eh 
nicht lang genug durch?

: Bearbeitet durch User
von Bauform B. (bauformb)


Lesenswert?

Εrnst B. schrieb:
> Lass die Tabelle automatisiert aus
> der aktuellen TZ-Datenbank erstellen, dann kann dein Build-System
> automatisch binaries für alle möglichen Zeitzonen erstellen.

Genau so läuft das hier, zwecks Zeitzonen. UTC verwende ich übrigens, 
weil ich es einfacher finde -- obwohl das Gerät kein NTP, GPS oder DCF 
hat, nur eine normale RTC.

> Und Self-Update-Fähigkeiten sind für IOT-Geräte eigentlich sowieso ein
> Muss, nicht erst seit Mirai & co.

Wobei für die Tabelle kein komplettes Build-System gebraucht wird, es 
sind ja nur Daten. Man muss die nur so im Flash ablegen, dass man sie 
getrennt updaten kann.

> Was danach irgendwann ein Problem wird:
>
> Alex schrieb:
>> Dieser Zeitstempel ist im 32bit unixtime format.
>
> Soll das als erzwungenes Verfallsdatum dienen, oder hält das Gerät eh
> nicht lang genug durch?

Naja, wer keine libc verwendet ist klar im Vorteil und nimmt uint32_t 
statt time_t. Das reicht für Heute + (40 Jahre Produktzyklus) + (40 
Jahre Gebrauchsdauer) :)

von Ralf D. (doeblitz)


Lesenswert?

Nick M. schrieb:
> Gibts eigentlich einen "NTP-DCF77". Also ein NTP der die DCF77-Zeit
> verwendet? Wäre ja fast sinnvoll.

Ahemm, woher glaubst du denn, dass DCF77 die Zeit bekommt? Wenn du das 
per NTP haben willst, dann bieten sich also ganz natürlich die 
NTP-Server der PTB an.

ptbtime1.ptb.de
ptbtime2.ptb.de
ptbtime3.ptb.de

von Nick M. (Gast)


Lesenswert?

Ralf D. schrieb:
> Ahemm, woher glaubst du denn, dass DCF77 die Zeit bekommt?

Von ihrem Zeitnormal, das auch international untereinander abgeglichen 
wird.

> ptbtime1.ptb.de

Das hatte ich bei der PTB gesucht, aber nicht gefunden. Und, ist das die 
Lokalzeit?


Nick

von Bauform B. (bauformb)


Lesenswert?

Nick M. schrieb:
>> ptbtime1.ptb.de
>
> Das hatte ich bei der PTB gesucht, aber nicht gefunden. Und, ist das die
> Lokalzeit?

Falls das eine Frage sein sollte: Natürlich nicht, es sind NTP Server.

Allerdings sind die kein Stück genauer oder sonstwie besser als 
de.pool.ntp.org, solange die Verbindung über DSL oder gar Funk läuft. 
Deshalb braucht die auch kein normaler Benutzer. Erstaunlich, dass die 
immer noch frei zugänglich sind.

von Εrnst B. (ernst)


Lesenswert?

Nick M. schrieb:
> Und, ist das die
> Lokalzeit?

mach statt NTP einen HTTP GET request auf

http://worldtimeapi.org/api/timezone/Europe/Berlin.txt

oder meinetwegen

http://worldtimeapi.org/api/ip.txt

Wenn die Zeitzone automatisch aus deiner Public IP erraten werden soll.

".txt" am Ende jeweils weglassen für JSON output. Für den µC ist aber 
plain-Text einfacher zu parsen, denke ich.



Und ja: Da wird nicht wie bei NTP die Netzwerk-Latenz ausgeglichen. Auf 
<1 Sekunde Abweichung wird man aber trotzdem von fast überall her 
kommen..

: Bearbeitet durch User
von Bauform B. (bauformb)


Lesenswert?

Εrnst B. schrieb:
> mach statt NTP einen HTTP GET request auf
>
> http://worldtimeapi.org/api/timezone/Europe/Berlin.txt

Witzige Idee, aber man sollte das kleingedruckte Lesen (die FAQ):
 * If the data is incorrect, it’s because our data might be a little old 
and in need of refreshing.
 * The API can go down from time-to-time, for relatively long periods.
 * What shouldn’t I use it for?
   - as an alternative to ntp
 * The project is entirely funded at a loss, and should costs become 
prohibitive the API will, with a heavy heart, be taken down permanently.
 * This API should NOT be used for commercial applications. The API can 
go down from time-to-time, for relatively long periods. It is provided 
with no SLA, no guarantees, and no direct funding.

Man kann diese Daten übrigens zusammen mit NTP benutzen. Also, man hat 
einen normalen NTP-Client und holt sich den aktuellen Offset zur lokalen 
Zeit von worldtimeapi.org (ntp + raw_offset + dst_offset). Wer ein 
EEPROM o.ä. hat, kann sich den Wert, zusammen mit "dst_until", auch 
merken. Dann darf die API auch mal für long periods down sein.

von Marten Morten (Gast)


Lesenswert?

Alex schrieb:
> Es geht leider um die unsinnige Funktion eines halbwegs ordinären
> Weckers

Und warum laberst du was von IoT?

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.