Adding Daylight Savings Time to Your RTC

Published

Introduction: Adding Daylight Savings Time to Your RTC

Having made a little toddler clock for my daughter (just a RGB LED that turns green at 7:30am and red at 7:30pm to let her know the time) I realized in March that it does not have support for Daylight Savings Time.

Since I live in Canada which shares this with most of the United States, our Daylight Savings Time (DST for short) begins on the second Sunday in March and ends on the first Sunday of November.

Below is the code snippet you can add to your RTC project to add support for DST (tested on DS3231 with the RTClib.h library from Adafruit: https://github.com/adafruit/RTClib). It uses Arduino's EEPROM.h library to store the DST flag. It works best if the RTC project is always plugged in (as it updates at 2am) but there is a piece of code in the setup() function that lets you very quickly adjust DST if you miss the time window (if the project is not plugged in all the time) Note that RTClib uses 0 to 6 for days, 0 being Sunday.

#include <EEPROM.h>
#include <RTClib.h>

RTC_DS3231 rtc; int DST;

void setup() {

DST = EEPROM.get(0, DST);

if(DST != 0 && DST != 1)

{

DST = 1;

EEPROM.put(0, DST);

}

// Uncomment the following 2 lines if you need to set the DST (if you miss the actual day etc). Change the +1 to -1 in the fall. // DateTime t2 = rtc.now(); // rtc.adjust(DateTime(t2.year(), t2.month(), t2.day(), t2.hour()+1, t2.minute(), t2.second()));

}

void loop() {

DateTime now = rtc.now();

if (now.dayOfTheWeek() == 0 && now.month() == 3 && now.day() >= 8 && now.day() <= 16 && now.hour() == 2 && now.minute() == 0 && now.second() == 0 && DST == 0) {

rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour()+1, now.minute(), now.second())); DST = 1; EEPROM.put(0, DST);

} else if(now.dayOfTheWeek() == 0 && now.month() == 11 && now.day() >= 1 && now.day() <= 8 && now.hour() == 2 && now.minute() == 0 && now.second() == 0 && DST == 1) {

rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour()-1, now.minute(), now.second())); DST = 0; EEPROM.put(0, DST);

}

}

Share

    Recommendations

    • Woodworking Contest

      Woodworking Contest
    • Microcontroller Contest

      Microcontroller Contest
    • Casting Contest

      Casting Contest
    user

    We have a be nice policy.
    Please be positive and constructive.

    Tips

    Questions

    Hi, Thanks for the cool code. I was a little lost as to the now.day >= 8 and <= 16. Where do the 8 and 16 come from? Thanks : )

    4 Comments

    Very helpful information!

    MichaelB247, do you know how and where to add your code to existing one I use for Word Clock project. Thanks a lot!

    Here is top part of code I use:

    #include <Wire.h>

    #include <RTClib.h>

    #include <Adafruit_GFX.h>

    #include <Adafruit_NeoPixel.h>

    #ifdef __AVR__

    #include <avr/power.h>

    #endif

    //#include <DateTimeStrings.h>

    #define RTCGND A2 // use this as DS1307 breakout ground

    #define RTCPWR A3

    RTC_DS3231 RTC; // Establish clock object

    Adafruit_NeoPixel pixels = Adafruit_NeoPixel(93, 6, NEO_GRB + NEO_KHZ800);

    void setup() {

    // Serial.begin(9600);

    #if defined (__AVR_ATtiny85__)

    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);

    #endif

    // set analog pins to power DS1307 breakout!

    pinMode(RTCGND, OUTPUT); // analog 2

    pinMode(RTCPWR, OUTPUT); // analog 3

    digitalWrite(RTCGND, LOW); // GND for RTC

    digitalWrite(RTCPWR, HIGH); // PWR for RTC

    // put your setup code here, to run once:

    pinMode(6, OUTPUT);

    Wire.begin(); // Begin I2C

    if (RTC.lostPower()) {

    RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));

    }

    pixels.begin();

    pixels.show();

    // DateTime.sync(1262304000L);

    }

    void loop() {

    DateTime theTime = RTC.now();

    // Serial.print(theTime.hour(), DEC);

    // Serial.print(':');

    // Serial.print(theTime.minute(), DEC);

    // Serial.print(':');

    // Serial.print(theTime.second(), DEC);

    // Serial.println();

    // put your main code here, to run repeatedly:

    for(int i = 0; i <93; i++){

    pixels.setPixelColor(i, pixels.Color(0,0,0));

    }

    if(theTime.hour() == 0 || theTime.hour() == 12){

    3 replies

    You should be able to add it in your main loop just after your call for RTC.now(). Hope this helps

    Arduino: 1.8.5 (Mac OS X), Board: "Pro Trinket 5V/16MHz (USB)"

    In file included from /Users/roman/Downloads/wc code/LEDClockTested/LEDClockTested.ino:50:0:

    /Users/roman/Library/Arduino15/packages/arduino/hardware/avr/1.6.16/libraries/EEPROM/src/EEPROM.h: In function 'void loop()':

    /Users/roman/Library/Arduino15/packages/arduino/hardware/avr/1.6.16/libraries/EEPROM/src/EEPROM.h:130:5: error: invalid declaration of member template in local class

    template< typename T > T &get( int idx, T &t ){

    ^

    /Users/roman/Library/Arduino15/packages/arduino/hardware/avr/1.6.16/libraries/EEPROM/src/EEPROM.h:137:5: error: invalid declaration of member template in local class

    template< typename T > const T &put( int idx, const T &t ){

    ^

    LEDClockTested:59: error: a function-definition is not allowed here before '{' token

    {

    ^

    LEDClockTested:474: error: expected '}' at end of input

    }

    ^

    Multiple libraries were found for "Wire.h"

    Used: /Users/roman/Library/Arduino15/packages/adafruit/hardware/avr/1.4.9/libraries/Wire

    Not used: /Users/roman/Library/Arduino15/packages/arduino/hardware/avr/1.6.16/libraries/Wire

    exit status 1

    a function-definition is not allowed here before '{' token

    This report would have more information with

    "Show verbose output during compilation"

    option enabled in File -> Preferences.

    I am new to Arduino, this is error message I got afre I paste you code.

    Any idea? Thanks Mishael!