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.
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:
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.
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
>typedefstruct/* trans_struct */{
2
>uint32_ttime;
3
>int32_tgmtoff;
4
>}trans_struct;
5
>
6
>staticconsttrans_structtranslist[]={
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?
Ε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..
Ε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.