Hi, ich suche den ganzen Tag schon nach einer Lösung für eine Sommerzeitumschaltung eines Weckers, den ich im Moment baue. Es gibt hier im Forum zwei Codebeispiele, die das implementiert haben was ich suche. Allerdings verstehe ich die Code-Schnipsel nicht Die Zeile: if( day - wday >= 25 && (wday || hour >= 2) ist m.E. nicht eindeutig. Es gibt doch mehrere Daten im März für die die Bedingung day - wday >= 25 zutrifft ??? Link: (Beitrag "Berechnung Datum + Uhrzeit + Sommerzeit") Mein Problem: Die Sommerzeitumschaltung findet am letzten Sonntag im März um 2 Uhr Morgens statt. Zurück wird am letzten Sonntag im Oktober gewschaltet. Soweit die Aufgabenstellung... Klar ist, dass ich über einen Algorithmus den Wochentag zu meinem (aktuell zu testenden) Datum berechnen muss. Diese Aufgabe ist für mich lösbar, wobei ich im Moment an einer Implementierung arbeite. Was dann kommt ist mir nicht ganz klar: Vielleicht hat da mal jemand einen Tipp: Es reicht ja nicht zu testen ob der aktuelle Tag im März ein Sonntag ist. Es könnte ja noch ein weiterer nachfolgen aleerdings will ich jetzt nicht absteigend vom 31.März an in einer Schleife testen ob der Tag ein Sonntag ist ... Wer hat eine Idee wie es nach der Wochentagsberechnung weiter geht? Ist irgendwio ein Algorithmus beschrieben ? Gruß Andreas
Schau dir mal den JavascriptCode von der Seite an: http://www.ez-calculators.com/daylight-saving-times-dates.htm insbesondere die Funktion whatdates. Gruß Roland
> Es reicht ja nicht zu testen ob der aktuelle Tag im März ein Sonntag > ist. Es könnte ja noch ein weiterer nachfolgen aleerdings will ich > jetzt nicht absteigend vom 31.März an in einer Schleife testen ob > der Tag ein Sonntag ist ... Überleg doch mal: 25.3. = Sonntag 26.3. = Montag 27.3. = Dienstag 28.3. = Mittwoch 29.3. = Donnerstag 30.3. = Freitag 31.3. = Samstag Also: Ist es März und ist es ein Sonntag und ist es der 25. Tag oder später im Monat, dann ist das definitiv der letzte Sonntag im März.
Wenn Du den Wochentag vom 31.März berechnest ( 0= So....6= Sa), brauchst Du nur "31.März - Wochentag" rechnen, dann hast Du das Datum des vorherigen Sonntags. gruss christian
Die obige Formel zeigt an, ob Sommerzeit ist oder nicht (der Oktober fehlt dann noch). wday ist 0 für Sonntag Der März hat in der Regel 31 Tage. Die Umstellung kann also frühestens am 25. und spätestens am 31. stattfinden. 25 So 0 26 Mo 1 27 Di 2 28 Mi 3 29 Do 4 30 Fr 5 31 Sa 6 Wenn der 25. ein Sonntag ist, ist wday 0 und day - wday = 25. Für alle anderen Tage ist wday größer und deshalb muss auch day größer sein, damit der obige Algorithmus greift. ( wday || hour >= 2 ) ist dann war, wenn es entweder nicht Sonntag ist (also mit dem vorangegangenen Teil jeder Tag nach der Zeitumstellung) oder sonntags ab 2 Uhr. Hier ist meiner Meinung nach noch ein Fehler zu suchen. Für jeden Sonntag nach der Zeitumstellung (kann natürlich nicht mehr im März liegen) ist leider erst ab 2 Uhr Sommerzeit nach diesem Algorithmus. Da aber sowieso noch der Teil mit März fehlt und wohl auch noch der Oktober-Teil (habe jetzt Deinen Link nicht angeschaut), muss da noch ein wenig gebastelt werden. Ansonsten passt es soweit. Normalerweise sollte tm_isdt des structs time_t gefüllt sein. Da wäre eigentlich alles drin. Das hängt aber leider von der Implementation ab.
Hi, Jetzt ist es klar - hätte eigentlich schon früher draufkommen können ... ich prüfe also ob der aktuelle Tag ein Sonntag ist. Wenn das der Fall ist, prüfe ich dann ob das Datum (im März) >= 25 ist. Wenn das der Fall ist, prüfe ich ob es schon 2 Uhr ist. wenn Ja, wird die Uhr vorgestellt Gruß und Danke Andreas
Nein. Du prüfst direkt auf den letzten Sonntag ob der aktuelle Tag später >= dem letzen Sonntag ist. Das Ergebnis ist auch 'true' für z.B. den Montag danach.
Florian wrote: > ( wday || hour >= 2 ) ist dann war, wenn es entweder nicht Sonntag ist > (also mit dem vorangegangenen Teil jeder Tag nach der Zeitumstellung) > oder sonntags ab 2 Uhr. > > Hier ist meiner Meinung nach noch ein Fehler zu suchen. Für jeden > Sonntag nach der Zeitumstellung (kann natürlich nicht mehr im März > liegen) ist leider erst ab 2 Uhr Sommerzeit nach diesem Algorithmus. Und deshalb wird nur im März returned, wenn es vor 2.00 Uhr ist:
1 | if( day - wday >= 25 && (wday || hour >= 2) ){ // after last Sunday 2:00 |
2 | if( month == 10 ) // October -> Winter |
3 | return; |
4 | }else{ // before last Sunday 2:00 |
5 | if( month == 3 ) // March -> Winter |
6 | return; |
7 | }
|
Peter
Hi, jetzt bin ich verwirrt ... "Nein. Du prüfst direkt auf den letzten Sonntag ob der aktuelle Tag später >= dem letzen Sonntag ist. Das Ergebnis ist auch 'true' für z.B. den Montag danach." Ich bin jetzt mal der Mega8: 1.) eben war es 23:59:59. Ein paar Interrups später ist es 00:00:00 und damit beginnt ein neuer Tag. 2) Ich erhöhe meinen Tageszähler um eins. es ist jetzt der 25. März. Den Tag kenne ich nicht, da ich ihn nicht ausgerechnet habe. 3.) Da das Datum >= 25 ist, ermittle ich den aktuellen Wochentag. Nehmen wir an, es ist Dienstag. Dann brauche ich nichts weiter zu machen. Viele Millarden Taktzyklen später ... 2) Ich erhöhe meinen Tageszähler um eins. es ist jetzt der 30. März. Den Tag kenne ich nicht, da ich ihn nicht ausgerechnet habe. 3.) Da das Datum >= 25 ist, ermittle ich den aktuellen Wochentag. Es ist Sonntag. Das Merke ich mir jetzt, da ich um 2 Uhr die Sommerzeitverstellung machen muss Jetzt bin ich wieder Andreas: Warum gefällt Euch diese Vorgehensweise nicht ??? Gruß Andreas
Und wie geht das mit der Vollmondberechnung? Muß ich da die Gaußsche Osterformel benutzen?
Hi, frage mich gerade ob ich während des normalen Betriebs überhaupt eine Wochentag-Ermittlungs-Funktion benötige. Der Wochentag kann ja genauso wie das Datum etc. mitgezählt werden. Man würde dann den Wochentag über die Uhr/Datum-Funktion eingeben (Oder EINMALIG berechnet werden) und bräuchte keine Aufwändigen Mod- und Divisions-Funktionen ??? Im Sinne der Programmiereffizienz wäre das doch die beste Lösung ??? Gruß Andreas
Ich sag mal so: Dein Wecker wird doch eine Änderung am GUI nur jede Sekunde machen (wenn überhaupt). Der µC hat dazwischen massig Zeit ein paar "Aufwändigen Mod- und Divisions-Funktionen" auszuführen. 'Programmiereffizienz' ist nicht alles. Es geht auch darum, was du deinem Benutzer alles zumuten willst.
UBoot-Stocki wrote: > frage mich gerade ob ich während des normalen Betriebs überhaupt eine > Wochentag-Ermittlungs-Funktion benötige. Der Wochentag kann ja genauso > wie das Datum etc. mitgezählt werden. Man würde dann den Wochentag über > die Uhr/Datum-Funktion eingeben (Oder EINMALIG berechnet werden) und > bräuchte keine Aufwändigen Mod- und Divisions-Funktionen ??? > > Im Sinne der Programmiereffizienz wäre das doch die beste Lösung ??? Die Berechnung ist überhaupt nicht aufwendig und ne Division braucht man auch nicht. Warum also nicht dem Benutzer die Arbeit abnehmen. Hier mal mein Code:
1 | ;------------------------------------------------------------------------ |
2 | ; |
3 | .equ FD = 0 ;offset weekday |
4 | |
5 | ;****************************** calculation weekday ********************* |
6 | get_wday: |
7 | mov zl, month ;Month (1..12) |
8 | ldi zh, 0 |
9 | subi zl, low(-(2 * _cwd5 - 1)) |
10 | sbci zh, high(-(2 * _cwd5 - 1)) |
11 | lpm ;get 1. day of month |
12 | |
13 | mov a0, year |
14 | cpi month, 3 ;start calculation with march |
15 | brcc _cwd1 |
16 | dec a0 ;use last year for jan. & feb. |
17 | _cwd1: mov a1, a0 |
18 | lsr a1 |
19 | lsr a1 |
20 | add a0, a1 ;* 1.25 |
21 | add a0, r0 ;+ 1. day of month |
22 | add a0, day ;+ day |
23 | _cwd2: subi a0, 7 |
24 | brcc _cwd2 |
25 | subi a0, -7 ;a0 = a0 % 7 |
26 | mov weekday, a0 ;0 = So, 1 = Mo, ... , 6 = Sa |
27 | ret |
28 | _cwd5: .db FD, FD+3, FD+2, FD+5, FD, FD+3, FD+5, FD+1, FD+4, FD+6, FD+2, |
29 | FD+4 |
30 | ;----------------------------------------------------------------------- |
Peter
Hi, Will ja nicht "rumquengeln" aber ich könnte ja mit der mod/div-Funktion einmalig (z.B. im Eingabedialog) den Wochentag zum eingegebenen Datum berechnen lassen und dann weiterzählen. Damit würde diese Funktion genau einmal aufgerufen. Ist doch einfacher und schneller... ? Die Argumente, die Ihr bisher hattet waren: Der µC hat dazwischen massig Zeit ein paar "Aufwändigen Mod- und Divisions-Funktionen" auszuführen. -> Macht vielleicht nichts aus aber wenns elleganter geht ? 'Programmiereffizienz' ist nicht alles. Es geht auch darum, was du deinem Benutzer alles zumuten willst. -> Es wäre ja kein Unterschied zur Lösung mit permanenten Funktionsaufrufen @Peter: Was macht dieser Code? Was sind das für Werte auf die mit lpm zugegriffen wird? Hast Du zufällig eine Beschreibung des Algorithmus den Du da verwendest? Ich habe bisher nur Monsterformeln mit div und mod gefunden.... Gruß andreas
UBoot-Stocki wrote: > @Peter: Was macht dieser Code? Er zählt pro Jahr um 1,25 Tage weiter, also 1-2-3-5 usw. Das Jahr zähle ich 2-stellig 00..99 > Was sind das für Werte auf die mit lpm > zugegriffen wird? Der Wochentag des 1. jedes Monats. Und der Trick, mit dem 1.3. anzufangen, umgeht die Sonderbehandlung des Schalttags. Peter
Danke Florian für den Link (auch wenn meine Frage etwas vom Thema abweicht). Man nimmt also einfach eine ausreichend breite Fließkommazahl. Die Gaußsche Osterformel soll auch irgendwann in 8000 Jahren danebengehen, das ist nur eine Näherung. Mein 8€-DCF77-Wecker vom Supermarkt kann die Mondphase anzeigen, also kann das nicht so kompliziert sein.
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.