20 October 2016

Cheating on DST calculation

My homemade clocks currently lack a commodity feature: automatic switch to daylight saving time and back. Throughout Europe this change occurs in the early hours of the last Sunday of March and October. I do have an RTC that can keep track of day-of-the week, but no clocks o' mine display it, so it is usually left out when setting date and time.
On the other hand I usually have lots of unused code/EEPROM space in my Arduinos, so I am seriously considering to hardcode a static table of the last Sunday of March and October. It is a lazy solution, but a change in the official DST rules would require a firmware update anyway.

Without carefully packing up data, I would need two bytes for each year, one byte per last-Sunday value. Something like:

int DSTdates[3][2] = {
   {27, 30}, // 2016, get it with DSTdates[currentYear-2016][0] and DSTdates[currentYear-2016][1]
   {26, 29}, // 2017
   {25, 28} // 2018
My usual Arduino sketch leaves way more than 1000 bytes free for variables. If I hardcoded DST changeover for 50 years, that would account for 100 bytes. I could even leave it like that, but let's discuss further optimizations.
DST for 2016 will be over in a week, that is more or less the amount of time it will take me to implement this function and update my clock firmwares around the house. Nevertheless, since we still live in 2016, I need to keep that line in the bidimensional array otherwise it would break the lookup algorithm that begins from 2016.
Second optimization. The last Sunday of March and October will always be on day 25 or later, so the array data can be rearranged substracting 25 from every number. That means the day range will be between 0 (= 25 - 25) and 6 (= 31 - 25). If we think of these numbers in BCD, they now fit in one single byte. In the previously allocated 100 bytes I can now store 100 years of DST changeover! This is how it looks now:

int DSTdates[3] = { 25, 14, 03 };  // 2016, 2017, 2018

While the code above is not human-readable, a simple lookup function does the trick. And since I will write a simple program to generate the array, I don't worry about those unreadable values as long as the unpack function works.

Now I need the script to generate the array. Stay tuned!

No comments: