The Arduino and Daylight saving time

wintertijd It is that time of the year again that many countries will end the Daylight Saving Time.
But what about your microcontroller? Many programs on the arduino and other microcontrollers keep time and do that with one of the popular RTC chips such as the DS1307 or the DS3231. They keep time very well (but I prefer the DS3231) and there are a hoist of libraries available for them.
One thing they do not do is to automatically between standard time and daylight saving time (DST). Obviously that would be quite hard as  there are different DST conditions all over the world

Though one could of course reset the RTC chip manually twice a year but that is tedious, especially while it can easily be solved with a few lines of code.

Different parts of the world have different rules for when the daylight saving time takes place and many countries of course have no daylight saving: It only makes sense (if at all) to do it between the tropics and the Arctic circles, so in fact between the tropic of Cancer and the Arctic circle and the tropic of Capricorn and the Antarctic circle.

In Australia daylight saving time is a matter of the states and territories but in general daylight saving time is between the first sunday in oktober and the first Sunday in April (remember, it is down under)

In Canada it largely depends on where you live, some states follow the United states. Newfoundland en Nunavut have their own rule and many of the northern territories do not have daylight saving time

The USA has daylight saving time from the 2nd Sunday of March till the first Sunday of November.

The EU of course has a guideline on it that determines the daylight saving time to start on the last Sunday of March and to end on the last Sunday of October. In the EU the hour to switch is at 01:00 UTC. In practice UTC is equal to GMT (Greenwich Mean Time). UTC itself is not an abbreviation but a compromise between the French abbreviation “TUC” and the English “CUT” (Temps Universel Coordonné resp Coordinated Universal Time).

At 1:59 AM the DST is still OFF (“Uit”), then 1 min later the DST is set and it is 3:00 AM

Catering for your local daylight savings program is usually quite easy:
Let your program check for the proper month and then count the number of Sundays (the change is usually on a Sunday). When you arrived at the
required Sunday check the time and if it is say 2 am, advance the clock an hour (=set it to 3) if DST has to start, or wait till 3 am and reset the clock hours to ‘2’.
Obviously you also need to set a flag to do the clock correction only once.

Simple enough… Unless you live in the EU (or Nunavut). In the EU the switch isn’t made at the first, second, third or fourth Sunday in March resp. October, but at the LAST Sunday of the month.

Well, a month has four Sundays right? Wrong. If for instance October starts on a Friday, Saturday or Sunday, it has 5 Sundays. So what to do?
Well you could of course determine if the first day starts on Friday, Saturday or Sunday and if so, count to 5 and otherwise count to 4. But there is a simpler way, in which you don’t even have to count.

Lets put that in a program for Western Europe, which means that the switch times are 2 and 3 am (that is 1:00 UTC)

Let’s agree that you have an RTC that will keep the “day of week” *as the DS1307 and the DS3231 do). As you set these yourself lets agree that you have set the day of week such that Monday is day 1 and Sunday is day 7. Some people like to start the week on Sunday, but that is just a matter of taste.
Anyway, we have the following variables read from our RTC
dow= day of week (as in 1-7)
d=day (as in 1-31)
DST is a flag we set when DST starts and that we clear at the end of DST to avoid that the program starts correcting the time for a full hour and even getting in an endless loop when we set the clock back
As October has 31 days, we know that the last Sunday will always fall from the 25th to the 31st
So our check at the end of daylight saving will be as follows:

if (dow == 7 && mo == 10 && d >= 25 && d <=31 && h == 3 && DST==1)
setclockto 2 am;

As you may be using different libraries the command ‘setclockto 2 am’ is just a place holder for your specific routine to set your RTC to 2 am. I would advise to store the DST flag somewhere in non volatile memory, in case you need to unplug your arduino.
The DS1307 has some on chip Non Volatile RAM where you can store it, the DS3231 does not. Both however usually come as a module with an EEPROM on it as well, otherwise the EEPROM of the Arduino can be used.

Anyway lets do a check if we have the right routine:
Suppose October 1 is a Sunday. That means the 25th is a Wednesday and the 29th a Sunday (the last and 5th Sunday), so the routine will indeed be activated on the 29th as all conditions are met.
Suppose October starts on a Monday. That means there are only 4 Sundays and the last Sunday will fall on the 28th. Again, that is between 25 and 31 so the condition is met.
Suppose October first falls on a Thursday, then the 25th will be a Sunday (the fourth Sunday) and the 31st will be a Saturday, so again the condition will be met for the last (and in this case 4th Sunday).

To start summertime/daylightsaving time on the last Sunday in March is mutatis mutandis the same:

if (dow == 7 && mo == 3 && d >= 25 && d <=31 && h ==2 && DST==0)
setclockto 3 am;

March also has 31 days so the calculations are the same. This time though we check at 2 am and a reset DST flag and then set the clock to 3 am and set the DST flag to indicate it is done already.

Now if you do NOT use an RTC that keeps the day of week or if you keep track of time and date in some other way than with an RTC, then there is an easy formula to determine the day of the week from the date with Sakamoto’s Algorithm

//gives day of week for a given date Sunday=0, Saturday=6
int dow(int y, int m, int d)
static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
y -= m < 3;
return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;

mind you though that this routine counts from 0 (Sunday) to 6 (Saturday)

So when is it Dark?

I have removed the text that used to be here,in favour of a new post on sunset and sunrise.

6 thoughts on “The Arduino and Daylight saving time”

    1. Thanks. I didnt know that. Didnt find it either when I was looking for a solution so I ended up with the few lines of code. As I havent seen the library you refer to I am not sure how much overhead it would be, but for those people that use Studio7 IDE it is good to know. Thanks!

      Btw… checked yr blog. cool stuff 🙂

  1. “mo == 3 && d >= 25 && d <=31"
    If the first two are TRUE then the third one is always TRUE so you don't have to test for it.

    1. You are fully correct. I think someone else made that remark too but as it is not wrong and changing code in WordPress is sometimes tricky, especially if fishhook characters are used, I just left it for what it is.

  2. My friend.
    Your routines are not complete; suppose I start my computer, or Pi or Arduino monday 27th of March. DST !
    Your routine will say it ain’t DST. So you have to test for the last days of this week as well.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.