Is that the (daylight saving) time? -

Is that the (daylight saving) time?


In my previous column on this topic (see Outfoxed by Daylight Saving Time ), I mentioned that I'd completely forgotten to account for Daylight Saving Time (DST) when capturing the code for the Cunning Chronograph.

Community member Realjjj commented: “But tomorrow you'll be bothered by the RTC's lack of accuracy; might as well go with WWVB — more retro than other solutions.” So I had a root around and discovered that WWVB offers as a great a Heath Robinson / Rube Goldberg combination of “modern” and “retro” as anyone could wish for. On the one hand, the signal is derived from a set of atomic clocks that yield a frequency uncertainty of less than 1 part in 10^12. On the other hand, this information is then modulated onto a 60kHz carrier signal and transmitted at one bit per second, resulting in each frame of time code beginning at the start of each minute and lasting the entire minute.

Well, this set me off on a tangent, resulting in my ordering a High Sensitivity WWVB Time Receiver Module with Antenna from my chum Pete Virica who owns PV Electronics in the UK (Pete also stocks modules for use in the UK and Europe). I will be playing with this as soon as is arrives. You have to admit that there's a certain cachet and je ne sais quoi attached to being able to say that the accuracy of one's Cunning Chronograph is regulated by atomic clocks, but all of this is for the future…

Another community member, Matt Weber, asked how long I intended my Cunning Chronograph to run, and noted that if I use only a 16-bit unsigned integer to represent the year, then my descendants are doomed to experience a Y64K bug in the year 65,535. Matt also noted that by that time, we (i.e., humans) might be living on Kepler-186f (the first Earth-sized planet we've discovered in the habitable zone), in which case we'll need to adjust the Cunning Chronograph to deal with years containing ~130 days.

Artist's concept depicting Kepler-186f (Source: NASA Ames/JPL-Caltech/T. Pyle)

Well, I'm ever the optimist, and there's always an outside chance we will discover faster-than-light travel while I still maintain a corporeal presence on this plane of existence, so I feel it behooves me to modify my Cunning Chronograph to allow its owner to specify the number of hours in a day, the number of days in a year, and so on and so forth. Once again, however, this is something to mull over in the future…

Returning to the problem at hand, my Cunning Chronograph is currently displaying standard time and running an hour behind. I obviously want it to reflect DST. In particular, I want it to reflect DST in Huntsville, Alabama, which is where I currently hang my hat.

The simplest solution is for me to simply reset the time by hand at the start and end of DST season, but I'm not that sort of man. The next simplest solution would be to have a switch on the back of the clock and/or an option on my Bluetooth control system (Off = standard time; On = DST).

Of course, we can keep on adding to the complexity. Do I want to add the ability to specify Pacific, Mountain, Central, and Eastern USA time? What about the fact that some states like Arizona don’t observe DST (although, confusingly, Phoenix — the capital of Arizona — does)? Similarly, if I one day wish to transport my Cunning Chronograph on a trek around the world, I'll have to contend with DST in Northern hemisphere summers, DST in Southern hemisphere summers, the fact that different countries move into and out of DST on different days, and the fact that some countries don’t support DST at all (see also DST by Country) .

Sometimes I have to rein myself in. Let's return to the problem at hand. My Cunning Chronograph currently resides with me in Huntsville, Alabama, and that's where we both plan to be for the foreseeable future, so the first step is to come up with an algorithm that will allow the Chronograph to automatically correct for DST here on my own turf.

In the case of DST in America, the time advances by one hour at 2:00 a.m. on the second Sunday in March, and it is set back by one hour at 2:00 a.m. on the first Sunday in November. Using the RTC (real time clock) in my Cunning Chronograph, I can easily access the following values:

    year   (2016, for example)    month  (1 to 12)    day    (1 to 31)    hour   (0 to 23)    minute (0 to 59)    second (0 to 59)

From my previous column, we know that we can create a dayOfWeek() function that will accept year , month , and day arguments and return an integer value of 0 = Sunday, 1 = Monday, 2 = Tuesday, etc.; for example:

  int dayOfWeek (int y, int m, int d)  {      return (d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7;  }

How we actually use this function depends on the inner machinations of the Cunning Chronograph's implementation. In the case of my chum Steve Manley's Cunning Chronograph in the UK, for example, he only uses his RTC to determine the current year , month , day , hour , minute , and second values on power-up. Thereafter, he employs a 1Hz signal from his RTC to generate an interrupt, which he then uses to modify these values as required.

This means that, if we were to assume Steve's clock to be located here in Alabama (remembering that DST may start and end on different days in the UK), at exactly 2:00 a.m. on the second Sunday in March, he would use something like hour += 1 to advance the time by one hour to 3:00 a.m. Similarly, at exactly 2:00 a.m. on the first Sunday in November, he would use something like hour -= 1 to regress the time by one hour to 1:00 a.m. (the reason I say "something like" in this latter case is that, if we actually used hour -= 1 , we'd spend the rest of our lives locked in a 1:00 a.m. to 2:00 a.m. time loop).

In my case, however, I don’t have access to a 1Hz signal from my RTC. Thus, having displayed the current hour , minute , and second values on the face of my Cunning Chronograph, I simply sit around polling the RTC until we transition into the next second, and then I regenerate everything from scratch. This means that, once every second, my code needs to determine if we are currently between the start and end of DST season and -- if we are -- it needs to increment the hour value before displaying it.

Bearing all this in mind, let me walk you through the way in which I arrived at the algorithm I intend to implement this coming weekend. (I could jump straight into the solution, but I think some folks may find it useful to see the way in which one might set about solving problems of this ilk.)

Now, I can’t talk as to the way in which other people would tackle this conundrum. All I can say is that I'm a visual person, so I often begin by sketching things out on a piece of paper. I started with the fact that I need to know the number of the day the second Sunday occurs in March. Obviously, this will be determined by which day falls on March 1. After a bit of messing around, I came up with the following diagram:

(Source: Max Maxfield /

You will recall that our original dayOfWeek() function returns 0 = Sunday, 1 = Monday, 2 = Tuesday... ending with 6 = Saturday. Sad to relate, this gives us a discontinuity when we come to Sunday being the first day of the month.

We could work around this by adding a test to see if the returned value was 0 (Sunday), in which case we could change this to 7, resulting in 1 = Monday, 2 = Tuesday, 3 = Wednesday... ending with 7 = Sunday. This solves the discontinuity problem, but it still leaves us having to perform some algorithmic gymnastics to generate the results we desire.

Since we know that we're going to "munge" the output from the function anyway, let's come at things from a different angle. It doesn’t take long to realize that we can make our lives a whole lot easier if we swap things around a bit and modify the dayOfWeek() function to return 0 = Sunday, 1 = Saturday, 2 = Friday... ending with 6 = Monday as illustrated below:

(Source: Max Maxfield /

All of this is easily achieved my means of a cross-reference array, which means that -- assuming we've defined NUM_DAYS_IN_WEEK to be 7 -- our new dayOfWeek() function will look like the following:

  int dayOfWeek(int y, int m, int d)  {      int xRef[NUM_DAYS_IN_WEEK] = {0,6,5,4,3,2,1);      return xRef[(d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7];  }

Based on this, it's really easy for us to determine which days of the month the first, second, third, etc. Sundays fall on. For example, let's assume we have the following definitions:

  #define MARCH             3  #define NOVEMBER         11  #define FIRST_DAY         1  #define NUM_DAYS_IN_WEEK  7

In this case, we can determine the day DST begins, startDayDST (the second Sunday in March), as follows:

  startDayDST = FIRST_DAY + NUM_DAYS_IN_WEEK                          + dayOfWeek(year, MARCH, FIRST_DAY);

Similarly, we can determine the day DST ends, endDayDST (the first Sunday in November), as follows:

  endDayDST = FIRST_DAY + dayOfWeek(year, NOVEMBER, FIRST_DAY);

Based on this, instead of simply calling my displayHour(hour) function, I can now perform the following test:

  if (((month >= MARCH) && (day >= startDayDST) && (hour >= 2))         &&       ((month <= NOVEMBER) && (day <= endDayDST) && (hour <= 2)))  {      displayHour(hour + 1); // Display Daylight Saving Time  }  else  {      displayHour(hour);     // Display Standard Time  }

So, this is where I'm currently at. I intend to add the above to my Cunning Chronograph's code this weekend, with fingers crossed that I haven’t messed anything up.

38 thoughts on “Is that the (daylight saving) time?

  1. “Max, just a minor correction, the ChronoDot RTC does have a square wave output and it can be set to 1Hz. I have a ChronoDot and have used the 1Hz function myself. “

    Log in to Reply
  2. “–Sad to relate, this gives us a discontinuity when we come to Sunday being the first day of the month.nnHaving read this blog a couple of times now, It is still not clear to me why the Sunday being the first day of the month causes a discontinuity. May

    Log in to Reply
  3. “After speaking with you the other day, it is clear I have an issue in October when DST kicks in, in that my algorithm puts my clock into ground hog hour. I also have the issue where if the clock is not active or is performing one of its other functions li

    Log in to Reply
  4. “I have recently acquired one of PV Electronics Nixie Tube clock kits and noted that it has a DST button. I also have a sophisticated electro mechanical wrist watch that will automatically advance the date display on the shorter months back to the 1st of t

    Log in to Reply
  5. “Fortunately for Max, DST in the USA starts at 2AM not at midnight so the date issue is not a problem. I don't know about the UK…nAlso, there are a couple flaws in the way Max implemented his final if statement. The way it's written, I don't think it wo

    Log in to Reply
  6. “I realise that DST starts at 2AM and at that point I is no issue, Its every day thereafter during the DST months that I see the date being incorrect for one hour a day. If Max reads the date and time from the RTC then adds an hour for display, unless he c

    Log in to Reply
  7. “Hi Steve — sorry, I'm probably not explaining things very well. Take a look at my first diagram — this is based on our day-of-week function returning a DOW of 0 if the first day of the month is Sunday, 1 if it's Monday, 2 if it's Tuesday … all the way

    Log in to Reply
  8. “Hi Steve — in the USA the time changes exactly at 2:00:00 am — so in March, instead of going from 1:59:59 to 2:00:00, it goes from 1:59:59 to 3:00:00.nnSimilarly, in November, instead of going from 1:59:59 to 2:00:00, it goes from 1:59:59 to 1:00:00.”

    Log in to Reply
  9. “As you say, when you are exiting DST, if you say “when it's 2:00am go back to 1:00am” then you could run into a problem — what you're going to have to do is have a flag saying “already exited DST” so you only subtract the hour one time.”

    Log in to Reply
  10. “Hi Elizabeth, I didn't get a chance to work on this over the weekend — something came up — but as soon as I get a free moment I'll take a look and see if I can see what's wrong with my if statement.”

    Log in to Reply
  11. “In the case of my first-pass solution, I'm planning on adding a DST On/Off “switch” to my Bluetooth Menu System. But this won't just add 1 hour when the “switch” is on. nnThe way this will work is that, by default, DST will be On, which means the

    Log in to Reply
  12. “Hi Matt — thanks so much for this — one point is that (due to this commenting system) links don;t work if you enclose them in parentheses. so here are your links broken out:n

    Log in to Reply
  13. “C/C++ has a “comma” operator. It evaluates the first operand and throws away the result, then evaluates the second and returns its result.nSon return (d+=m 3?y–:y-2,23*m/9+d+4+y/4-y/100+y/400)%7;nis equivalent ton d+=m 3?y–:y-2;n return (

    Log in to Reply
  14. “It's what Matt said LOLnnI knew there was a comma operator — but I've not gotten to that part of the C book yet, so I didn't know exactly how to explain what it does.”

    Log in to Reply
  15. “”It evaluates the first operand and throws away the result, then evaluates the second and returns its result.”nnWell — it doesn't exactly “throw away the result” does it? The first part changes the value in 'd' — and then this value is used in the

    Log in to Reply
  16. “”Throwing away the result” doesn't mean there is no impact. Side-effects such as auto-increment, etc. still happen, it's just that the result doesn't get passed any further along.nSo nc = (a++,b);nwill increment a, not use that result, and set c=b.n

    Log in to Reply
  17. “”…it's just that the result doesn't get passed any further along…”nnAh — OK, that makes sense — thanks MattnnHey — will you be coming to ESC Boston?”

    Log in to Reply
  18. “Max do you remember you blog on which standard to use, MISRA or Barr? Does that one line version of Zellers Congruence pass either one of them? Zeller didn't even have a computer back in the 1800's…”

    Log in to Reply
  19. “”Max are you aware of Time Nuts?”nnI wasn't — but now I want to be one. Also I have to get an image of Johnny Depp as Willie Wonka saying “Don't touch that squirrel's time nuts!””

    Log in to Reply
  20. “Never ceases to amaze me that the world still changes time twice a year. For what reason? At least we are the smart ones and don't change in Saskatchewan.”

    Log in to Reply
  21. “MaxnnIt always seems to happen- I read an article, think a bit and then dismiss it with- “interesting, but I'll never have to do this.” And then the universe bites me in the rear end…nnI have just been working on my implementation if this and it o

    Log in to Reply
  22. “Nice article.nI couple of things I noticed.nshould the last parentheses in nint xRef[NUM_DAYS_IN_WEEK] = {0,6,5,4,3,2,1);nbe a curly bracket, like this?nint xRef[NUM_DAYS_IN_WEEK] = {0,6,5,4,3,2,1};nnAlso,nShould the displayHour() function also i

    Log in to Reply

Leave a Reply

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