Go Down

Topic: Time-Libary Sommerzeit/ Winterzeit (Read 8453 times) previous topic - next topic

-Jan-

Guten Abend,

damit ich in Sachen Elektronik und Programmieren fitter werde, habe ich mir mit dem Arduino eine kleine Wetterstation aufgebaut. Ich logge auf einer SD-Karte verschiedene Werte von Sensoren und auch die Uhrzeit - ohne würd es ja keinen Sinn machen.  :)

Jedenfalls nutze ich für die Uhrzeit die Time-Libary (Time.h) und verwende KEINE RTC. Später werde ich mir eine RTC anschaffen, wahrscheinlich die DS1307. So eine Uhr kann man schließlich ja immer gebrauchen.
Da ja demnächst die Uhren umgestellt werden, habe ich mich gefragt, ob die Time-Libary das auch kann bzw. macht. Und ob die Time-Libary eine Schaltjahrerkennung besitzt. Leider habe ich durch googlen nichts Brauchbares herausgefunden.

Gruß
Jan

Serenifly

#1
Mar 23, 2014, 09:34 pm Last Edit: Mar 23, 2014, 09:36 pm by Serenifly Reason: 1
Die Schaltjahrkorrektur wird in der RTC selbst gemacht.

Sommmer/Winterzeit kann man leicht selbst machen. Hier ist eine Funktion um zu berechnen um gerade Sommerzeit ist:
http://forum.arduino.cc/index.php?topic=172044.msg1278536#msg1278536

Code: [Select]

boolean summertime_EU(int year, byte month, byte day, byte hour, byte tzHours)
// European Daylight Savings Time calculation by "jurs" for German Arduino Forum
// input parameters: "normal time" for year, month, day, hour and tzHours (0=UTC, 1=MEZ)
// return value: returns true during Daylight Saving Time, false otherwise
{
 if (month<3 || month>10) return false; // keine Sommerzeit in Jan, Feb, Nov, Dez
 if (month>3 && month<10) return true; // Sommerzeit in Apr, Mai, Jun, Jul, Aug, Sep
 if (month==3 && (hour + 24 * day)>=(1 + tzHours + 24*(31 - (5 * year /4 + 4) % 7)) || month==10 && (hour + 24 * day)<(1 + tzHours + 24*(31 - (5 * year /4 + 1) % 7)))
   return true;
 else
   return false;
}

Je nachdem addiert man dann noch eine Stunden drauf oder nicht

In der Lib ist das nicht drin, weil es unterschiedliche Zeitumstellungen gibt, je nachdem wo man sich befindet.


Am besten kaufst du dir übrigens eine DS3231:
http://www.ebay.de/itm/DS3231-AT24C32-IIC-Real-Time-Clock-Memory-Modul-RTC-fur-Arduino-AVR-UNO-ARM-PIC-/281140941523?pt=Bauteile&hash=item41754e52d3
Ich habe nicht so schlechte Erfahrungen mit der DS1307 gemacht wie viele andere, aber sie geht trotzdem schnell falsch



-Jan-

Hallo,

erstmal Danke für Deine Antwort.

Die Funktion hilft mir sehr weiter!!!

Also muss ich ohne eine RTC auf die Schaltjahrerkennung verzichten oder mir eine Funktion basteln, die genau das berücksichtigt?

Gruß
Jan

skorpi080

Kann ich nur bestätigen, hol dir alles andere, nur KEIN DS1307
playground.arduino.cc/PmWiki/433Mhz-Funkmodule

jurs


Also muss ich ohne eine RTC auf die Schaltjahrerkennung verzichten oder mir eine Funktion basteln, die genau das berücksichtigt?


Die time-Library hat in time.h dieses Makro als Inline-Funktion definiert:
Code: [Select]

#define __isleap(year) \
  ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))

Das könnte man auch als Einzeiler schreiben
Code: [Select]

#define __isleap(year)  ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))


Bei Verwendung der Time-Library kannst Du über den Funktionsaufruf
__isleap(jahreszahl)
jederzeit ermitteln, ob ein Jahr ein Schaltjahr ist. Die Time-Library berücksichtigt natürlich auch selbst Schaltjahre und benutzt diese Funktion an diversen Stellen im Code.

Wenn Du nicht die Time-Library verwendest, kannst Du Dir den define-Einzeler selbst in jedes Deiner Programme einfügen, das so eine Funktion benötigt.

-Jan-

#5
Mar 24, 2014, 02:46 pm Last Edit: Mar 24, 2014, 02:48 pm by -Jan- Reason: 1
Hallo,

alles klar, dann werde ich mir wohl ein paar DS3231 kaufen.


[...] Die Time-Library berücksichtigt natürlich auch selbst Schaltjahre und benutzt diese Funktion an diversen Stellen im Code. [...]


Heißt, dass ich nicht extra eine Funktion einbauen muss, die die Schaltjahre berücksichtig und dann ein Tag hinzuaddiert, da das die Time-Libary schon von sich aus tut?!

Gruß
Jan

jurs


Heißt, dass ich nicht extra eine Funktion einbauen muss, die die Schaltjahre berücksichtig und dann ein Tag hinzuaddiert, da das die Time-Libary schon von sich aus tut?!


Ja. Wenn Du ein Datum in Unix-Sekunden umwandelst, da 86400 Sekunden draufaddierst und Unix-Sekunden wieder in ein Datum zurückverwandelst, wird alles berücksichtigt: Tageswechsel, Monatswechsel, Jahreswechsel - und auch Schaltjahre!

SkobyMobil

Hallo,
eine RTC mit Maxim´s DS3231 (z.B. Chronodot) hat die Schaltjahr-Korrektur schon on Board.
LaufzeitFehler seid Nov/Dez 2013 keine "sichtbare" Sekunde.
Gruß und Spaß
Andreas
die zweite Maus bekommt den Speck...

michael_x

Quote
wird alles berücksichtigt: Tageswechsel, Monatswechsel, Jahreswechsel - und auch Schaltjahre

Wo wir gerade kurz davor, und die Amerikaner kurz danach sind: Alles ausser Sommer/Winter-Umschaltung.

x + 86400sec = vierundzwanzig Sunden später.
Wie man damit einen Tag ( mit 23, 24 oder 25 Stunden ) weiterzählt, ist nicht so trivial.
Einen Monat weiter geht übrigens so auch nicht.
Da muss man schon das Datum als struct tm nehmen und eines der Elemente weiterzählen (+ Überlauf-Betrachtung).

oino

Ich nutze den DS3231, wenn ich mir mit rtc.getUnixTime(rtc.getTime()) den aktuellen Unix Timestamp ausgebe, wurde in diesem Zeitstempel auch die Schaltjahre berücksichtigt?

qualidat

#10
Dec 31, 2016, 01:51 pm Last Edit: Dec 31, 2016, 01:52 pm by qualidat
Es gibt keine "WINTERZEIT" - Schwachsinn! Auch wenn die Medien dies jedes Jahr wiederholen, wird es dadurch nicht wahrer.

Es gibt die Sommerzeit (um eine Stunde gegenüber der MEZ verschoben) und es gibt die MEZ (mittel-europäische Zeit). Letztere ist die gemäß Sonnenstand in Mitteleuropa "richtige" Standardzeit.

michael_x

Quote
Es gibt keine "WINTERZEIT" - Schwachsinn
Was veranlasst dich heute (draussen herrscht bei uns eklige Winterzeit mit festem Hochnebel)
zu diesem Gefühlsausbruch ?
Auch dir ein entspanntes 2017 8)

@onio: In der DS3231 Hardware werden Schaltjahre ( zumindest die normalen alle 4 Jahre ) breücksichtigt.
In welchem Jahrhundert/Jahrtausend die DS3231 läuft, weiss sie nicht.

Auch die library, die dir unixtime liefert, wird das wohl bezüglich Schaltjahren vermutlich richtig machen. Schau es dir an.

Doc_Arduino

#12
Jan 01, 2017, 02:32 pm Last Edit: Jan 01, 2017, 02:33 pm by Doc_Arduino
Hallo,

ich denke eher er wollte damit sagen das unsere Winterzeit sowieso die normale MEZ Zeit ist. Und nur unsere Sommerzeit von der MEZ abweicht. Nur ist der Begriff Winterzeit geläufiger wie MEZ. Von daher würde ich das nun nicht unbedingt als falsch ansehen.
Für uns Europäer wird nun einmal leider am Zeiger gedreht.   :)
Wenn ihr mich zum Bundes-Papa wählt, schaffe ich den Mist ab. Versprochen!  ;)
Die ganzen Zeitzonen und Schaltjahre werden gleich mit abgeschafft, dann haben wir es leichter beim programmieren.  :)

Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

jar_

Die Schaltjahrkorrektur wird in der RTC selbst gemacht.

Sommmer/Winterzeit kann man leicht selbst machen. Hier ist eine Funktion um zu berechnen um gerade Sommerzeit ist:
http://forum.arduino.cc/index.php?topic=172044.msg1278536#msg1278536

Code: [Select]

boolean summertime_EU(int year, byte month, byte day, byte hour, byte tzHours)
// European Daylight Savings Time calculation by "jurs" for German Arduino Forum
// input parameters: "normal time" for year, month, day, hour and tzHours (0=UTC, 1=MEZ)
// return value: returns true during Daylight Saving Time, false otherwise
{
  if (month<3 || month>10) return false; // keine Sommerzeit in Jan, Feb, Nov, Dez
  if (month>3 && month<10) return true; // Sommerzeit in Apr, Mai, Jun, Jul, Aug, Sep
  if (month==3 && (hour + 24 * day)>=(1 + tzHours + 24*(31 - (5 * year /4 + 4) % 7)) || month==10 && (hour + 24 * day)<(1 + tzHours + 24*(31 - (5 * year /4 + 1) % 7)))
    return true;
  else
    return false;
}

Je nachdem addiert man dann noch eine Stunden drauf oder nicht

In der Lib ist das nicht drin, weil es unterschiedliche Zeitumstellungen gibt, je nachdem wo man sich befindet.


Am besten kaufst du dir übrigens eine DS3231:
http://www.ebay.de/itm/DS3231-AT24C32-IIC-Real-Time-Clock-Memory-Modul-RTC-fur-Arduino-AVR-UNO-ARM-PIC-/281140941523?pt=Bauteile&hash=item41754e52d3
Ich habe nicht so schlechte Erfahrungen mit der DS1307 gemacht wie viele andere, aber sie geht trotzdem schnell falsch



sagt mal rechnet der falsch?

der liefert in 2018, Oktober 2 Uhr schon Winterzeit dabei wird erst um 3
Uhr zurückgestellt!

mein Code rechnet zumindest richtig!
Start!
2018/03/26_12:09:13 MESZ

2018/03/26_12:09:14 MESZ
-------
(2018, 3, 25, 1, 1) 01. MEZ
(2018, 3, 25, 2, 1) 02.MESZ
(2018, 3, 25, 3, 1) 03.MESZ
(2018, 10, 28, 1, 1) 04.MESZ
(2018, 10, 28, 2, 1) 05.MESZ
(2018, 10, 28, 3, 1) 06. MEZ
-------
06.MESZ
-------
2018/03/26_12:09:14 MESZ

Code: [Select]

boolean summertime_EU(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, int8_t tzHours)
// European Daylight Savings Time calculation by "jurs" for German Arduino Forum
// input parameters: "normal time" for year, month, day, hour and tzHours (0=UTC, 1=MEZ)
// return value: returns true during Daylight Saving Time, false otherwise
{
/*
// !!!!!!!!!!! RECHNET falsch !!!!!!!!!!
 if (month<3 || month>10) return false; // keine Sommerzeit in Jan, Feb, Nov, Dez
 if (month>3 && month<10) return true; // Sommerzeit in Apr, Mai, Jun, Jul, Aug, Sep
 if (month==3 && (hour + 24 * day)>=(1 + tzHours + 24*(31 - (5 * year /4 + 4) % 7)) || month==10 && (hour + 24 * day)<(1 + tzHours + 24*(31 - (5 * year /4 + 1) % 7)))
 return true;
 else
 return false;
*/
// !!!!!!!!!!! RECHNET richtig !!!!!!!!!!
 uint8_t beginnMESZ = tagesnummer( year, 3, 31 );
 uint16_t endeMESZ = tagesnummer( year, 10, 31 );
// uint8_t mo=month;
 uint16_t tij=tagesnummer(year, month, day);
 if(month > 2 && month < 11) // 11, 12, 1 und 2 haben keine Sommerzeit
 { // auf Sommerzeit korrigieren
 while(wochentag_im_jahr(year, beginnMESZ) != 7)
 beginnMESZ--;
 while(wochentag_im_jahr(year, endeMESZ) != 7)
 endeMESZ--;

 if( tij>beginnMESZ && tij<endeMESZ )
 return true;
 else
 { if( tij==beginnMESZ && hour>=2 )
 return true;
 if( tij==endeMESZ && hour<3 )
 return true;
 }
 } // if(mo > 2 && mo < 11)
 return false;
} // boolean summertime_EU(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, int8_t tzHours)


Go Up