Hallo,
einiges klappt schon aber anderes leider noch nicht.
Ich habe im 32 Bit Register eines STM32F103 die aktuelle Epoch Time und
kann diese auch umrechnen in ein normales Zeitformat.
Zur Zeit rechne ich UTC in MEZ+1 derart um, dass ich 3600s drauf addiere
und localtime die Arbeit machen lasse. Zieht gut 2kb extra an Code dazu
aber 128kb habe ich ja sowieso.
Nun gibt es aber in der time.h Lib auch die Funktion tzset mit der man
angeblich einstellen kann in welcher Zeitzone man sich befindet und wann
die Sommerzeit beginnt. Schaut man im POSIX Stndard nach wird da vom
Umgebungsvariablen gesprochen, die da gesetzt sind. Natürlich hat ein UC
sowas nicht. tzset wird aber in time.h als LIB Funktion referenziert,
leider ohne Parameter. Auch gmtime, ctime usw sind alle da, man kann
sich aus der Epoch Time poroblemlos einen String bauen lassen.
Hat da jemand ne Idee, wie ich mir die Wurschtelei das manuell
umzurechnen wann die Sommerzeit beginnt, samt Korrektur etc sparen kann?
Ich wüsste nicht, dass es einfacher geht. Ich benutze für die
WordClock mit WS2812 eine ähnliche Routine, welche Du für Deine
Berechnungen offenbar als Vorlage genommen hast, denn die Ähnlichkeiten
sind unverkennbar ;-)
Jedoch ist in Deiner Funktion ein Fehler:
1
if(31-mytime.tm_mday<8){
Der letzte Sonntag im März ist immer im Bereich vom 25. bis 31. März,
das sind die letzten 7 Tage.
Wenn der Sonntag auf den 24.03. fällt, ist wegen 31 - 24 = 7
1
if(31-mytime.tm_mday<8){
der obige Ausdruck wahr, obwohl in diesem Fall der 31. März und nicht
der 24. März der letzte Sonntag ist.
Schreibe besser:
1
if(mytime.tm_mday>=25){
Da sieht man auf den ersten Blick, dass es nur Tage zwischen dem 25. und
31. März sein können und muss nicht erst rechnen.
EDIT:
Du hast noch einen weiteren Fehler drin: Du prüfst nur auf Sonntage im
März. Was ist mit einem Montag, wie z.B. der 27.03. in diesem Jahr?
Komischerweise hast Du da die if-Bedingungen umsortiert - offenbar um
den Source zu vereinfachen. Dabei hast Du aber einiges "wegoptimiert",
was hätte stehen bleiben müssen.
Hier das Original:
1
uint_fast8_tsummertime=0;
2
...
3
// calculate summer time:
4
if(mytm->tm_mon>=3&&mytm->tm_mon<=8)// april to september
5
{
6
summertime=1;
7
}
8
elseif(mytm->tm_mon==2)// march
9
{
10
if(mytm->tm_mday-mytm->tm_wday>=25)// after or equal last sunday in march
11
{
12
if(mytm->tm_wday==0)// today last sunday?
13
{
14
if(mytm->tm_hour>=2)// after 02:00 we have summer time
15
{
16
summertime=1;
17
}
18
}
19
else
20
{
21
summertime=1;
22
}
23
}
24
}
25
elseif(mytm->tm_mon==9)// it's october
26
{
27
summertime=1;
28
29
if(mytm->tm_mday-mytm->tm_wday>=25)// it's after or equal last sunday in october...
30
{
31
if(mytm->tm_wday==0)// today last sunday?
32
{
33
if(mytm->tm_hour>=3)// after 03:00 we have winter time
Hi Frank,
danke für die Tips. Nee, ich habe nix abgeschaut, das ist alles bisher
mein Werk und ähnlich ist es sicherlich irgendwo. Bin alle Monate
durchgegangen, das >=24 hatte ich schon eingefügt, da der letzte Sonntag
maximal 7 Tage entfernt sein kann.
Mit den ersten beiden ifs hole ich alles raus bis auf März und Ooktober.
Ok, habe da was vertauscht, hast recht, die ifs müssen verdreht werden.
Ganze easy kann man sich das auch machen, wenn man sich bis Ende 2039
alle Epoch Times heraussuchen lässt, wo die Umstellung passiert. Ich
vermute zwar, dass wir 2039 andere Sorgen haben (oder gar keine mehr,
weil wir tot sind) aber so geht es auch.
2017: 1490580000 und 1509242400
2018: usw...
März und Oktober kann man aber gleich behandeln, beide 31 Tage, beide
bis auf die Stunde der gleiche Tag der Umstellung.
Ich melde mich später nochmal...
Gruss,
Christian
PS: Ist doch etwas komplizierter, da man das nicht auf einen Zeitpunkt
festmachen darf. Ich kann ja zwischendurch auch mal resetten auf dem
Montag nach dem Umschalt Sonntag oder an dem Sonntag ist die Uhr aus und
dann würde meine Rechnung keine Sommerzeit liefern in den Tagen danach.
Muss noch etwas nachdenken. Ich möchte globale Entweder-Oder-Switch
Flags vermeiden, eben wegen dem Reset.
Das ist bei Dir allerdings auch so!
Schaltest Du die Uhr erst im Oktober am Montag nach dem Wechsel ein
bleibt Dein Flag auf Sommerzeit stehen.
Schätze mal einfacher ist es wirklich sich die Unix Zeiten aller Tage
raus zu suchen und in eine Tabelle zu packen.
Christian J. schrieb:> März und Oktober kann man aber gleich behandeln, beide 31 Tage, beide> bis auf die Stunde der gleiche Tag der Umstellung.
Wie das ?
Hier, das ist besser und schneller:
Christian J. schrieb:> Das ist bei Dir allerdings auch so!
Nein, da hast Du meinen Code zu flüchtig gelesen.
> Schaltest Du die Uhr erst im Oktober am Montag nach dem Wechsel ein> bleibt Dein Flag auf Sommerzeit stehen.
Hier nochmal der Block ab Oktober:
1
elseif(mytm->tm_mon==9)// it's october
2
{
3
summertime=1;
4
5
if(mytm->tm_mday-mytm->tm_wday>=25)// it's after or equal last sunday in october...
6
{
7
if(mytm->tm_wday==0)// today last sunday?
8
{
9
if(mytm->tm_hour>=3)// after 03:00 we have winter time
10
{
11
summertime=0;
12
}
13
}
14
else
15
{
16
summertime=0;
17
}
18
}
19
}
Am Montag nach der Zeitumstellung wird der letzte else-Block
durchlaufen: summertime = 0;
Vergleiche mal den Block für März mit dem Block für Oktober: Während ich
im März das Flag bedingt setze, setze ich es im Oktober bei gleichen
(bzw. ähnlichen) Bedingungen zurück, mache also genau das Gegenteil.
Beachte auch, dass ich immer den Wochentag bei der Berechnung mit
einbeziehe:
1
if(mytm->tm_mday-mytm->tm_wday>=25)
Bei Dir steht da immer nur:
1
if(mytm->tm_mday>=25)// nach Umstellung der Terme
Das ist zu kurz gedacht. Bei Dir ist alles ab dem 25. schon vorbei, egal
ob der letzte Sonntag noch kommt oder bereits vorüber ist.
Ok ;-)
Habe schon nen Knoten im Hirn wegen der vielen returns. Soll ja nicht
heissen, ich hatte abgeschrieben. Obwohl die Subtraktionen ist gut, wäre
ich jetzt nicht drauf gekommen. Hoffe ich habe es jetzt. Testen bin ich
zu faul, das wäre ne Arbeit für Doofe da im Debugger alles per hand
einzutragen. Werde aber Sonntag nachts mal aufstehen und schauen, ob das
klappt.
PS: Es gibt diese Funktionen fertig in den StdLibs, aber leider wohl nur
für PC's. Mit tzset erschlägt man das alles. Und localtime
berücksichtigt das auch.
Christian J. schrieb:> enum Wochentag> {Montag,Dienstag,Mittwoch,Donnertag,Freitag,Samstag,Sonntag};> ...> if (mytime.tm_wday == Sonntag)
Das ist ebenso falsch. Laut Definition von tm_wday beginnt die Woche mit
Sonntag, also Sonntag = 0, Montag = 1 usw.
Schreibe also:
Christian J. schrieb:> Habe ich früher auch so gemacht, noch einfacher wie gesagt mit den Unix> Zeiten, da reduziert es sich auf einen einzigen Vergleich :-)
Schneler und einfacher als lesen aus der Tabelle ?
SchaltTag = MonatsTabelle[year-2015]
Ausserdem prüfst du das Ganze in _Bool IsSummertime(), da ist aber
mehr als nur ein Vergleich drin.
P.S.
Und _Bool IsSummertime() wird bei dir immer aufgerufen, nicht nur in
März und Oktober. Ich würde die Monatsabfrage vor dem Aufruf machen.
Ich glaube, die paar Takte spielen bei einem 72 Mhz Cortex keine Rolle
und der Aufruf passiert nur jede Sekunde einmal. Für eine derarrt lahme
Anwendung wie ich sie habe, die maximal alle paar Stunden überhaupt
Leben zeigt ist das egal. Die SleepTime beträgt unendlich, aufwachen tut
er nur wenn ein INT kommt.
Christian J. schrieb:> Ich glaube, die paar Takte spielen bei einem 72 Mhz Cortex keine Rolle> und der Aufruf passiert nur jede Sekunde einmal. Für eine derarrt lahme> Anwendung wie ich sie habe, die maximal alle paar Stunden überhaupt
Du hast mit einfacher und schneller angefangen und gefragt:
Christian J. schrieb:> Hat da jemand ne Idee, wie ich mir die Wurschtelei das manuell> umzurechnen wann die Sommerzeit beginnt, samt Korrektur etc sparen kann?
Und jetzt auf einmal ist die benötigte Zeit und Wurschtelei nicht mehr
wichtig ?
Und meine Frage steht immer noch:
Christian J. schrieb:> März und Oktober kann man aber gleich behandeln, beide 31 Tage, beide> bis auf die Stunde der gleiche Tag der Umstellung.
Wie das ?
Selbst in der Zeitrechnung kommt Mist heraus, wenn man
amerikanische Maßeinheiten und Konventionen benutzt!
Mit feet/meter-Problemen wurden vielversprechende, teure
Sonden in den Marsboden gerammt.
Und mit tm_wday beginnt die Woche am Sonntag, womit du in
Europa keinen Blumentopf gewinnen kannst, weil da ISO-8601
den Montag als Wochenanfang vorgibt.
Ist doch auch logisch: Sag mal die Wochentage auf:
Selbst im hintersten Kentucky fängt dabei jeder mit
"Monday" an.
Make REASON great again!
Jacko schrieb:> Und mit tm_wday beginnt die Woche am Sonntag, womit du in> Europa keinen Blumentopf gewinnen kannst, weil da ISO-8601> den Montag als Wochenanfang vorgibt.> Ist doch auch logisch: Sag mal die Wochentage auf:> Selbst im hintersten Kentucky fängt dabei jeder mit> "Monday" an.
Hat doch eher mit der Bibel zu tun: