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
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.
Wikipedia hat da unter "Beispiel-Implementierung" eine solche Umrechnung: https://de.wikipedia.org/wiki/Unixzeit
Zeitzonen .. ein Alptraum. Es gibt nebenbei auch Zeitzonen mit Halb- und Viertelstunden Versatz. Vereinfacht, der Zusammenhang zum Laengengrad ist zufaellig.
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
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
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".
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.
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
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.
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
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
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
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
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.
+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
Ε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) :)
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
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
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.
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
Ε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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.