There are many other, most likely better, functions to calculate if a given date/time is in European Daylight Saving Time. But the function below is simpler to understand because most calculations are done in-line. Only the "toEpoch" function is used from the "TimeLib.h" library.
This function calculates the epoch at 2AM of the last Sunday of March (start of EU DST) and the epoch at 2AM on the last Sunday of October (end of EU DST) and checks if the given date is in between (summertime) or not (wintertime).
#include <TimeLib.h>
void setup()
{
Serial.begin(74880);
delay(1000);
Serial.println();
//--- Begin of EU DST in 2021...
Serial.println(inDST(2021,3,28,1,59,59));
Serial.println(inDST(2021,3,28,2,0,0));
//--- End of EU DST in 2021...
Serial.println(inDST(2021,10,31,1,59,59));
Serial.println(inDST(2021,10,31,2,0,0));
}
void loop()
{
}
boolean inDST(int y, int M, int d, int h, int m, int s)
{
boolean isInDST = false;
unsigned long parsedDate = toEpoch(y, M, d, h, m, s); //--- Parsed date to epoch...
unsigned long firstDSTepoch = toEpoch(y,3, lastSundayOfMonth(y,3) ,2,0,0); //--- Start of DST in epoch...
unsigned long lastDSTepoch = toEpoch(y,10,lastSundayOfMonth(y,10),2,0,0); //--- End of DST in epoch...
if (parsedDate >= firstDSTepoch && parsedDate < lastDSTepoch)
{
isInDST = true;
}
return isInDST;
}
//--- Calculate the day of the last Sunday of a given month...
int lastSundayOfMonth(int y, int M)
{
//--- Take care of leap years...
int daysInMonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
if (y % 4 == 0 && y % 100 != 0) {daysInMonth[1] = 29;}
//--- Last day of month M to epoch...
unsigned long epoch = toEpoch(y,M,daysInMonth[M-1],0,0,0);
//--- Day of week, based on ISO8601...
int dayOfWeek = ((epoch / 86400) + 4) % 7;
//--- Calculate date of last Sunday...
return (daysInMonth[M-1] - dayOfWeek);
}
//--- Converts a date to epoch (TimeLib.h)...
unsigned long toEpoch(int y, byte M , byte d, byte h, byte m, byte s)
{
tmElements_t tmSet;
tmSet.Year = y - 1970;
tmSet.Month = M;
tmSet.Day = d;
tmSet.Hour = h;
tmSet.Minute = m;
tmSet.Second = s;
return makeTime(tmSet);
}
The output shows the second before and after the change to/from DST in 2021:
07:16:31.652 ->
07:16:31.652 -> ets Jan 8 2013,rst cause:2, boot mode:(3,6)
07:16:31.652 ->
07:16:31.652 -> load 0x4010f000, len 3584, room 16
07:16:31.652 -> tail 0
07:16:31.652 -> chksum 0xb0
07:16:31.652 -> csum 0xb0
07:16:31.652 -> v2843a5ac
07:16:31.652 -> ~ld
07:16:32.755 ->
07:16:32.755 -> 0
07:16:32.755 -> 1
07:16:32.755 -> 1
07:16:32.755 -> 0
No comments :
Post a Comment