Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions examples/DST_Europe/DST_Europe.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/* European Daylight Saving Time (DST) example */

// The Real Time Clock is kept in local winter time (standard time). This approach is key for the simplicity of this solution.
// This code is for a DST from Last sunday in March 1:00 (am) local time until Last sunday in October 3:00 (am) local time.
// The DST time can be changed if required, by choosing a different hour in the DateTime function (4th parameter).

#include <RTClib.h> // https://github.com/adafruit/rtclib
RTC_DS3231 rtc;
//RTC_DS1307 rtc;

#define USEDST true // Use DST (true or false)
#define BAUD 57600 // Baud rate for the serial monitor

DateTime now;
int lastsec;

DateTime dstclock(DateTime n) { // Return the given (DST adjusted) date and time according to DST settings (for extensive date and time calculations)

DateTime b, e;

b = DateTime(n.year(), 3, 31, 1, 0, 0); // Begin of DST: set on March 31 1:000 (am)
if (n.month() == 3) b = DateTime(n.year(), 3, 31 - b.dayOfTheWeek(), 1, 0, 0); // Begin of DST: adjusted to last sunday in March 1:00 (am) when actual month is March
e = DateTime(n.year(), 10, 31, 3, 0, 0); // End of DST: set on October 31 3:00 (am)
if (n.month() == 10) e = DateTime(n.year(), 10, 31 - e.dayOfTheWeek(), 3, 0, 0); // End of DST: adjusted to last sunday in October 3:00 (am) when actual month is October
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I already explained a couple of times, the DST transitions should happen at 02:00 RTC time, not at 01:00 or 03:00.


if (USEDST && (n > b) && (n < e)) n = n + TimeSpan(0,1,0,0); // adjust to standard time if within summertime
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test n > b should be n >= b, otherwise the transition happens one second too late.

return n;
};

DateTime getclock() { // Retrieve the (DST adjusted) date and time

DateTime n, b, e;

n = rtc.now();
b = DateTime(n.year(), 3, 31, 1, 0, 0); // Begin of DST: set on March 31 1:000 (am)
if (n.month() == 3) b = DateTime(n.year(), 3, 31 - b.dayOfTheWeek(), 1, 0, 0); // Begin of DST: adjusted to last sunday in March 1:00 (am) when actual month is March
e = DateTime(n.year(), 10, 31, 3, 0, 0); // End of DST: set on October 31 3:00 (am)
if (n.month() == 10) e = DateTime(n.year(), 10, 31 - e.dayOfTheWeek(), 3, 0, 0); // End of DST: adjusted to last sunday in October 3:00 (am) when actual month is October

if (USEDST && (n > b) && (n < e)) n = n + TimeSpan(0,1,0,0); // adjust to standard time if within summertime
return n;
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace this function with

DateTime getclock() { // Retrieve the (DST adjusted) date and time
  return dstclock(rtc.now());
};

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realized that this function could be replaced with:

#define getclock() dstclock(rtc.now())

Do you want me to make that change?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a slight preference for a function over a #define, as a function is more type-safe and more C++-idiomatic. But I don't care that much, and I am fine with whatever option you prefer.


void setclock(DateTime n) { // if the clock is set during summertime then adjust the clock to standard time

if (USEDST && (n != dstclock(n))) n = n - TimeSpan(0,1,0,0); // if summertime then adjust to the standard time
rtc.adjust(n); // Set the clock to standard time
};

void setup() {
// initialise the rtc
rtc.begin();
if (rtc.lostPower()) setclock(DateTime(F(__DATE__), F(__TIME__))); // Set date and time for use with the DS3231 RTC
// if (!rtc.isrunning()) setclock(DateTime(F(__DATE__), F(__TIME__))); // Set date and time for use with the DS1307 RTC

// initialise the serial port
Serial.begin(BAUD);
Wire.begin();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to initialize Wire here: this is done by RTClib. Besides, there would be no point in initializing Wire after rtc.begin().

Serial.println(""); Serial.println(""); Serial.println("----------------- New start ------------------");;

// Start the DST demonstration
setclock(DateTime(F(__DATE__), F(__TIME__))); // Set the clock to compile date and time

// show standard (winter) time
now = rtc.now(); // retreive the winter time
Serial.print(" Actual standard time: ");
Serial.print(now.timestamp(DateTime::TIMESTAMP_DATE)); Serial.print(" "); // print the date
Serial.println(now.timestamp(DateTime::TIMESTAMP_TIME)); // print the time

// show DST corrected time (only when in DST period, otherwise this equals the standard time)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Contrary to what the comment says, the lines below are not conditioned on the clock being in DST period.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

----------------- New start ------------------
Actual standard time: 2024-10-14 16:21:11
Actual DST corrected time: 2024-10-14 17:21:11 <- corrected because in DST

----------------- New start ------------------
Actual standard time: 2024-11-14 16:21:11
Actual DST corrected time: 2024-11-14 16:21:11 <- not corrected because not in DST

Serial.print("Actual DST corrected time: ");
now = getclock(); // get DST corrected time
Serial.print(now.timestamp(DateTime::TIMESTAMP_DATE)); Serial.print(" "); // print the date
Serial.print(now.timestamp(DateTime::TIMESTAMP_TIME)); Serial.println(""); // print the time
Serial.println("");
delay(5000);

Serial.println("Demonstration of the DST activation");
Serial.println("-----------------------------------");
Serial.println(" DST starts at: 2024-03-31 01:00:00");
Serial.println("First DST time: 2024-03-31 02:00:01");
Serial.println("");
delay(5000);
setclock(DateTime(2024, 3, 31, 0, 59, 45)); // Set the clock 15 seconds before DST starts
lastsec = now.second();
}

void loop() {
now = getclock(); // read the time from the RTC and adjust for DST or
// now = dstclock(rtc.now()); // read the time from the RTC and adjust for DST
if (lastsec != now.second()) { // if a new second
Serial.print(now.timestamp(DateTime::TIMESTAMP_DATE)); Serial.print(" "); // print the date
Serial.print(now.timestamp(DateTime::TIMESTAMP_TIME)); Serial.println(""); // print the time
lastsec = now.second(); // store the current second
}
}