Martin's corner on the web

Auto DST adjustment

We are close to that time of the year when Daylight Saving Time (DST) starts.  It is intended to save on energy use, however, studies have found this to be questionable, even contrary – energy use increases in some cases. The change itself causes a number of inconveniences.

For me DST start/end means adjusting a number of clocks around the house/office/cars, this process takes about 20-30 minutes twice a year. Many of the devices with clocks that I use run on schedule, so failing to update the time to account for DST means things don’t work well and as planned. For example, the hot water tank heater schedule is such that accounts for night electricity tariff (cheaper) and my usual wake-up time. I’ve come to the conclusion that having the user deal with DST manually means bad product design. So how can I improve the situation? I could adjust the firmware on the devices I designed to automatically account for DST.

Making a universal solution is quite hard – it turns out that only 32% of the countries observe DST, and the rules for those that observe it are varying widely:

Furthermore, these rules seem to change from time to time, so hard-coding may not be a good idea (still I went for it). Below is an example of the US DST rule changing over time, the last change happening in 2007:

I decided to only support EU/North America rules in my projects, hardcoding the rules. Should a change be needed, a FOTA update will be pushed. The code (source) I use goes like this,(DoW Sunday = 0 .. Saturday = 6):

   bool IsDST_NA(int day, int month, int dow)
    {
        //January, February, and December are out.
        if (month < 3 || month > 11) { return false; }
        //April to October are in
        if (month > 3 && month < 11) { return true; }
        int previousSunday = day - dow;
        //In march, we are DST if our previous Sunday was on or after the 8th.
        if (month == 3) { return previousSunday >= 8; }
        //In November we must be before the first Sunday to be DST.
        //That means the previous Sunday must be before the 1st.
        return previousSunday <= 1;
    }

..and the EU version

    bool IsDST_EU(int day, int month, int dow)
    {
        if (month < 3 || month > 10)  return false; 
        if (month > 3 && month < 10)  return true; 

        int previousSunday = day - dow;

        if (month == 3) return previousSunday >= 25;
        if (month == 10) return previousSunday < 25;

        return false; // this line never gonna happend
    }

Configuration screen allows for using EU, NA or no auto-DST adjustment rules.

 

Problem solved.

Tagged on: ,