Umschaltung NTP-Sommerzeit mit tm_isdst

Servus,

kann mir mal jemand helfen? Suche nun schon seit geraumer Zeit nach dem Fehler: Ziel: Umschaltung auf Sommerzeit mit NTP-Uhrzeit.

Folgender Code (in Auszügen):

  int timezone = 1;
  int summertime;
...
// NTPstuff
  configTime(timezone * 3600, 0, "0.europe.pool.ntp.org", "pool.ntp.org", "time.nist.gov");
...
void getTime() {
  time_t now = time(nullptr)+(summertime*3600);
  struct tm *tmp = localtime(&now);
  sprintf (actTime_str, "%02d:%02d:%02d", tmp->tm_hour , tmp->tm_min, tmp->tm_sec); 
  sprintf (actDate_str, "%02d.%02d.%04d", tmp->tm_mday , tmp->tm_mon+1, 1900+tmp->tm_year); 
  if (tmp->tm_isdst > 0){ 
     summertime = 1;
  }
  else {
     summertime = 0;
  }
}

Wenn ich 'summertime' manuell auf 1 setze, dann stimmt die Uhrzeit. Aber irgendwie wird das 'tm_isdst' nicht so richtig ausgewertet....

hk007: Servus,

kann mir mal jemand helfen? Suche nun schon seit geraumer Zeit nach dem Fehler: Ziel: Umschaltung auf Sommerzeit mit NTP-Uhrzeit.

Folgender Code (in Auszügen):

"Code (in Auszügen)", ja?

In dem Fall bekommst Du hier meine Antwort(ebenfalls in Auszügen): Irgendwas machst Du GRUNDLEGEND FALSCH, wenn Du so eine einfache Sache nicht hinbekommst, auf eine UTC-Zeitangabe entweder eine Stunde für Normalzweit oder zwei Stunden für Sommerzeit draufzuschlagen.

Glaub du hast mich nicht richtig verstanden.
Ich bin nicht zu dämlich auf die uhrzeit eine oder zwei Stunden drauf zu rechnen.
Es geht mir um die Erkennung: Haben wir jetzt Sommerzeit oder Winterzeit.
Dafür ist m.E. das tm_isdst da. ODER?

Allerdings bin ich der Meinung, dass tm_isdst nicht richtig von der Funktion localtime zurück kommt.
Ich hab das Beispiel jetz noch mal reduziert.
Und hier der GANZE Code.

#include <Streaming.h>
#include <time.h>
  unsigned long daycounter;  

void setup() {
   Serial.begin(115200);
   Serial << "\nProgramstart" << endl;
}
void loop() {
  time_t now = 1483268400 + daycounter;  // start @ 2017-1-1
  struct tm *tmp = localtime(&now);
  Serial << "Unixtime: " << now << " --- Daylight: " << tmp->tm_isdst << " --- " << ctime (&now);
  daycounter = daycounter + 86400; // + 1 day
}

Und hier die Ausgabe:

Unixtime: 1489575600 --- Daylight: 0 --- Wed Mar 15 11:00:00 2017
Unixtime: 1489662000 --- Daylight: 0 --- Thu Mar 16 11:00:00 2017
Unixtime: 1489748400 --- Daylight: 0 --- Fri Mar 17 11:00:00 2017
Unixtime: 1489834800 --- Daylight: 0 --- Sat Mar 18 11:00:00 2017
Unixtime: 1489921200 --- Daylight: 0 --- Sun Mar 19 11:00:00 2017
Unixtime: 1490007600 --- Daylight: 0 --- Mon Mar 20 11:00:00 2017
Unixtime: 1490094000 --- Daylight: 0 --- Tue Mar 21 11:00:00 2017
Unixtime: 1490180400 --- Daylight: 0 --- Wed Mar 22 11:00:00 2017
Unixtime: 1490266800 --- Daylight: 0 --- Thu Mar 23 11:00:00 2017
Unixtime: 1490353200 --- Daylight: 0 --- Fri Mar 24 11:00:00 2017
Unixtime: 1490439600 --- Daylight: 0 --- Sat Mar 25 11:00:00 2017
Unixtime: 1490526000 --- Daylight: 0 --- Sun Mar 26 11:00:00 2017
Unixtime: 1490612400 --- Daylight: 0 --- Mon Mar 27 11:00:00 2017
Unixtime: 1490698800 --- Daylight: 0 --- Tue Mar 28 11:00:00 2017
Unixtime: 1490785200 --- Daylight: 0 --- Wed Mar 29 11:00:00 2017
Unixtime: 1490871600 --- Daylight: 0 --- Thu Mar 30 11:00:00 2017
Unixtime: 1490958000 --- Daylight: 0 --- Fri Mar 31 11:00:00 2017
Unixtime: 1491044400 --- Daylight: 0 --- Sat Apr 01 11:00:00 2017
Unixtime: 1491130800 --- Daylight: 0 --- Sun Apr 02 11:00:00 2017
Unixtime: 1491217200 --- Daylight: 0 --- Mon Apr 03 11:00:00 2017
Unixtime: 1491303600 --- Daylight: 0 --- Tue Apr 04 11:00:00 2017
Unixtime: 1491390000 --- Daylight: 0 --- Wed Apr 05 11:00:00 2017
Unixtime: 1491476400 --- Daylight: 0 --- Thu Apr 06 11:00:00 2017
Unixtime: 1491562800 --- Daylight: 0 --- Fri Apr 07 11:00:00 2017
Unixtime: 1491649200 --- Daylight: 0 --- Sat Apr 08 11:00:00 2017
Unixtime: 1491735600 --- Daylight: 0 --- Sun Apr 09 11:00:00 2017
Unixtime: 1491822000 --- Daylight: 0 --- Mon Apr 10 11:00:00 2017
Unixtime: 1491908400 --- Daylight: 0 --- Tue Apr 11 11:00:00 2017
Unixtime: 1491994800 --- Daylight: 0 --- Wed Apr 12 11:00:00 2017
Unixtime: 1492081200 --- Daylight: 0 --- Thu Apr 13 11:00:00 2017
Unixtime: 1492167600 --- Daylight: 0 --- Fri Apr 14 11:00:00 2017
Unixtime: 1492254000 --- Daylight: 0 --- Sat Apr 15 11:00:00 2017

Danach hätten wir immer noch Winterzeit :frowning:

Woher soll der Arduino in seiner lokalen Zeit wissen, ob wir Winter- oder Sommerzeit haben? Das wirst Du ihm wohl per Programm beibringen müssen.

Gruß Tommy

Dachte schon dass hier etwas Wahrheit steht. http://www.cplusplus.com/reference/ctime/tm/

Anscheinend nicht.....

Das stimmt auch, es muß nur ein Programm geben, dass dies dem Rechner mitteilt. Darum kümmert sich in der Regel ein Teil des Btriebssystems. Der Arduino hat aber keins.

Gruß Tommy

Die Library ist wohl keine Spezial-Version für Berlin und Umgebung. Wie kommst du also darauf, dass in deinem
 struct tm *tmp = localtime(&now); irgendeine Zeitzonen-Information steckt?

Für nähere Informationen gibt es den Quellcode zu #include <time.h>
(was auch immer du da verwendest)

hk007: Allerdings bin ich der Meinung, dass tm_isdst nicht richtig von der Funktion localtime zurück kommt.

Was ist für Dich "richtig" und was "falsch"?

Auf der Welt gibt e wohl an die 200 Länder in 24 Zeitzonen, mit etlichen dutzend verschiedener Sommerzeitregeln.

Dass mal so wie in der Europäischen Union mehr als ein Dutzend Länder zum selben Zeitpunkt auf Sommerzeit und zurück die Zeit umstellen, ist eher selten.

Gemeinsamkeiten bei der Sommerzeitumstellung sind:

Die Zeitumstellung erfolgt im Sommer:

Der Unterschied ist: Länder südlich des Äquators haben dann Sommer, wenn Länder nördlich des Äquators Winter haben - und umgekehrt. Gemeinsamkeit ist wieder: Egal ob Nord- oder Südhalbkugel, bei Sommerzeit wird die Uhr immer vorgestellt.

Wenn Du nichts selbst mit Formeln berechnest, sondern Du die Angabe aus einer Blackbox-Library herausziehen möchtest, dann informiere Dich am besten, wie die Library funktioniert. Und auch, von was für einem Landsmann die Library stammt.

Wenn es die Library eines US-Amerikanerst ist, hat er vielleicht die Sommerzeitregeln für die USA eingebaut. Aber wenn er aus der EU, aus Chile , Argentinien oder Australien stammt, dann ist die von ihm in die Library eingebaute Sommerzeitregel vielleicht die Sommerzeitregel für die Region auf der Welt, wo ER herstammt und nicht die Sommerzeitregel, wo DU die Library bei Dir auf dem PC installiert hast.

Tommy56: Das stimmt auch, es muß nur ein Programm geben, dass dies dem Rechner mitteilt. Darum kümmert sich in der Regel ein Teil des Btriebssystems. Der Arduino hat aber keins.

Gruß Tommy

Ja, so gesehen ist das richtig.

Ich habe mich in meiner Faulheit wohl etwas von diesem Satz irritieren lassen:

The Daylight Saving Time flag (tm_isdst) is greater than zero if Daylight Saving Time is in effect, zero if Daylight Saving Time is not in effect, and less than zero if the information is not available.

Der hat mir suggeriert, dass ich hier die Info abgreifen kann. Dass auch das Feld beschrieben werden muss, daran hab ich gar nicht gedacht :o

Dann hack ich das mit dem letzten Sonntag im März/Oktober halt selber runter....

Merci@all

hk007: Dann hack ich das mit dem letzten Sonntag im März/Oktober halt selber runter....

Falls Du etwas (fast) fertiges suchst: Ich verwende zur Feststellung von Sommerzeit immer diese Funktion, die ich mir mal geschrieben und hier im Forum auch schon mehrfach gepostet habe, zum Beispiel hier: http://forum.arduino.cc/index.php?topic=172044.msg1278536#msg1278536

Nachteil dieser Funktion: Sie gilt so nur für das einundzwanzigste Jahrhundert von 2000 bis 2099 und benötigt für das kommende Jahrhundert von 2100 bis 2199 eine kleine Änderung (falls es dann die Sommerzeit immer noch gibt.

Das Vorgehen, wenn Du eine "Unixzeit" (Sekunden seit 1.1.1970 UTC) vorliegen hast, wäre wie folgt:

  1. Du wandelst die Unixzeit in Tag, Monat, Jahr, Stunde, Minute,Sekunde (UTC-Zeit um).
  2. Dann rufst Du meine Funktion mit dem Parameter tzHours=0 auf und bekommst einen boolschen Rückgabewert, ob es ein Zeitstempel ist, der in die Sommerzeit fällt.
  3. Wenn ja, zählst Du auf den Zeitstempel zwei Stunden drauf, andernfalls eine Stunde, und bekommst die gesetzliche Zeit in Deutschland
  4. Aufgepaßt: Beim Draufzählen von ein oder zwei Stunden auf UTC-Zeit kann ggf. das Datum auf den nächsten Tag umspringen!

Denn durch die unterschiedlichen Zeitzonen von London und Berlin, ist in London ggf. noch "heute um 23:00 Uhr, und in Berlin ist gleichzeitig Mitternacht 0:00 Uhr des Folgetags (Normalzeit), oder während der Sommerzeit sogar schon 01:00 Uhr nachts am Folgetag.

jurs: Falls Du etwas (fast) fertiges suchst:

Danke! Wieso das Rad neu erfinden. Und deine Funktion ist ja getestet :-)

Nachteil dieser Funktion: Sie gilt so nur für das einundzwanzigste Jahrhundert von 2000 bis 2099

2099...Das stört mich nicht mehr

  1. Aufgepaßt: Beim Draufzählen von ein oder zwei Stunden auf UTC-Zeit kann ggf. das Datum auf den nächsten Tag umspringen!

Ist kein Problem. Ich zähle auf den Unix-Timestamp direkt 3600 bzw. 7200 sek drauf, und berechne die Zeit neu.

Ergebnis passt!

Unixtime: 1490489880 --- Summertime: 0 --- Sun Mar 26 01:58:00 2017
Unixtime: 1490489940 --- Summertime: 0 --- Sun Mar 26 01:59:00 2017
Unixtime: 1490490000 --- Summertime: 1 --- Sun Mar 26 03:00:00 2017
Unixtime: 1490490060 --- Summertime: 1 --- Sun Mar 26 03:01:00 2017
.
.
Unixtime: 1509238680 --- Summertime: 1 --- Sun Oct 29 02:58:00 2017
Unixtime: 1509238740 --- Summertime: 1 --- Sun Oct 29 02:59:00 2017
Unixtime: 1509238800 --- Summertime: 0 --- Sun Oct 29 02:00:00 2017
Unixtime: 1509238860 --- Summertime: 0 --- Sun Oct 29 02:01:00 2017