Ein Datum auf Sommerzeit prüfen

Der Algorithmus ist eigentlich einfach:

Die Sommerzeit beginnt am letzten Sonntag im März, um 2 Uhr.
Die Sommerzeit endet am letzten Sonntag des Oktobers um 2 Uhr.

Wie mache ich das in der Software?

März und Oktober haben beide 31 Tage. Der letzte Sonntag liegt also innerhalb der letzten 7 Tage des Monats. Also ab dem 25. muss ich mir anschauen welcher Wochentag das ist. Diese Information kann mir z.B. ein RTC (Real Time Clock) Baustein liefern.

Für diese Woche gilt dann folgende Tabelle:

25 26 27 28 29 30 31
So Mo Di Mi Do Fr Sa
Sa So Mo Di Mi Do Fr
Fr Sa So Mo Di Mi Do
Do Fr Sa So Mo Di Mi
Mi Do Fr Sa So Mo Di
Di Mi Do Fr Sa So Mo
Mo Di Mi Do Fr Sa So

Das sind alle möglichen Kombinationen.

Für März gilt dann: Ab inklusive Sonntag nach rechts ist Sommerzeit. Alle Tage links vom Sonntag sind dann Winterzeit.

Für den Oktober gilt: Ab inklusive Sonntag nach rechts ist Winterzeit. Alle Tage links vom Sonntag sind dann Sommerzeit.

Bevor ich die Sommerzeit checke lese ich natürlich erst den RTC ein.

Die Codierung ist dann Fleißarbeit:

// Sommerzeit check
#define SONNTAG (byte)1
#define MONTAG (byte)2
#define DIENSTAG (byte)3
#define MITTWOCH (byte)4
#define DONNERSTAG (byte)5
#define FREITAG (byte)6
#define SAMSTAG (byte)7

#define MAERZ (byte)3
#define APRIL (byte)4
#define MAI (byte)5
#define JUNI (byte)6
#define JULI (byte)7
#define AUGUST (byte)8
#define SEPTEMBER (byte)9
#define OKTOBER (byte)10

typedef enum JahresZeiten
{
SommerZeit,
WinterZeit
};

// Variablen —————————————————————–
// Zeitangaben
byte tag = (byte)0;
byte monat = (byte)0;
byte jahr = (byte)0;
byte stunde = (byte)0;
byte minut = (byte)0;
byte wtag = (byte)1; // Wochentag von 1=Sonntag bis 7=Samstag

/****************************************************************************
* Sommerzeit erkennen
* (c) 2017 softwareentwicklung-als-prozess.de
* Dokumentation s. Blog
***************************************************************************/

JahresZeiten CheckSommerzeit(void)
{
JahresZeiten ret = WinterZeit;
// vom 1.4. bis 24.10. ist sicher Sommerzeit
switch(Get_Monat())
{
case APRIL:
case MAI:
case JUNI:
case JULI:
case AUGUST:
case SEPTEMBER:
ret = SommerZeit;
break;
case OKTOBER:
ret = SommerZeit; /* bis zum 24.! */
if ((byte)25 > Get_Tag())
{
ret = WinterZeit;
}
else
{
ret = SommerZeit;
}
}

// Die letzte Woche von Maerz und Oktober muss untersucht werden
if ((MAERZ == Get_Monat()) || (OKTOBER == Get_Monat()))
{
switch(Get_Tag())
{
case (byte)25:
switch(Get_Wochentag())
{
case SONNTAG:
ret = OberhalbDiagonale();
break;

default:
ret = UnterhalbDiagonale();
break;
}
break;

case (byte)26:
switch(Get_Wochentag())
{
case SONNTAG:
case MONTAG:
ret = OberhalbDiagonale();
break;

default:
ret = UnterhalbDiagonale();
break;
}
break;

case (byte)27:
switch(Get_Wochentag())
{
case SONNTAG:
case MONTAG:
case DIENSTAG:
ret = OberhalbDiagonale();
break;

default:
ret = UnterhalbDiagonale();
break;
}
break;

case (byte)28:
switch(Get_Wochentag())
{
case SONNTAG:
case MONTAG:
case DIENSTAG:
case MITTWOCH:
ret = OberhalbDiagonale();
break;

default:
ret = UnterhalbDiagonale();
break;
}
break;

case (byte)29:
switch(Get_Wochentag())
{
case SONNTAG:
case MONTAG:
case DIENSTAG:
case MITTWOCH:
case DONNERSTAG:
ret = OberhalbDiagonale();
break;

default:
ret = UnterhalbDiagonale();
break;
}
break;

case (byte)30:
switch(Get_Wochentag())
{
case SONNTAG:
case MONTAG:
case DIENSTAG:
case MITTWOCH:
case DONNERSTAG:
case FREITAG:
ret = OberhalbDiagonale();
break;

default:
ret = UnterhalbDiagonale();
break;
}
break;

case (byte)31:
switch(Get_Wochentag())
{

default:
ret = OberhalbDiagonale();
break;
}
break;

default: // Fehlerkorrektur fuer Version 2.0
{
if (MAERZ == Get_Monat())
{
ret = WinterZeit;
}
if (OKTOBER == Get_Monat())
{
ret = SommerZeit;
}
}
}
}
return(ret);
}

static JahresZeiten OberhalbDiagonale(void)
{
JahresZeiten ret = SommerZeit;

if(MAERZ == Get_Monat())
{
ret = SommerZeit;
}
if(OKTOBER == Get_Monat())
{
ret = WinterZeit;
}
return(ret);
}

static JahresZeiten UnterhalbDiagonale(void)
{
JahresZeiten ret = SommerZeit;

if(MAERZ == Get_Monat())
{
ret = WinterZeit;
}
if(OKTOBER == Get_Monat())
{
ret = SommerZeit;
}
return(ret);
}

Literaturhinweise und Links

Zbigniew Michalewicz / David B. Vogel
– How to Solve It: Modern Heuristics

Datenblatt Real Time Clock DS1302

Klicke, um auf DS1302.pdf zuzugreifen

Veröffentlicht von

Jürgen

Ich bin Software Ingenieur und habe meine Schwerpunkte in allen Aktivitäten, die zur Software Entwicklung gehören. Am längsten bin ich als Software Entwickler von Embedded Software in C tätig.