Daylight savings time

Nightstand and alarm clockIt’s that time of year again. Time to spring forward. Well, not exactly the same time as last year. The formula for daylight savings time changed for this year. That meant that I had to rewrite firmware that used daylight savings time. According to Wikipedia,

Beginning in 2007, DST will start on the second Sunday in March (March 11, 2007), and change back to standard time on the first Sunday in November (November 4, 2007). Under Section 110 of the Energy Policy Act of 2005, the U.S. Department of Energy is required to study the impact of the DST extension no later than nine months after the change takes effect. Congress has retained the right to revert to the DST schedule set in 1986 if it cannot be shown that there are significant energy savings from an extension of DST or if the extension may prove to be unpopular with the American public. One potential issue is that some northern regions on the western edge of time zones will for the first time since the 1974-75 “almost year round” DST experiment have sunrise times that occur after 8am.

In two of my controllers I use, the built in hardware clock of the PC/104 card automatically handles the daylight savings time change. I simply set a bit and it would automatically spring forward or fall back. Well, almost. One of the controllers used a realtime clock chip by Odin which didn’t come out of daylight savings time and got stuck at 1am on the last Sunday of October. Since I could no longer utilize the hardware clock, I had to handle the daylight savings time change in software. There were two cases that I needed to cover. The first case is handling the timer interrupt and springing forward one hour or falling back one hour. The timer interrupt code turned out to be much simpler than I first thought. It is a good thing to be simple in an interrupt. Here is part of the code:

  1. if (data.tm_year >= (2007-1900)) {    /* begin DST – Second Sunday in March */    /* ANSI is months since January */    if ((data.tm_mon == 2 /*March*/) &amp;&amp;        (data.tm_wday == 1 /*Sunday*/) &amp;&amp;        (data.tm_mday >= 8) &amp;&amp; /* second Sunday */        (data.tm_mday <= 14) &amp;&amp;        (data.tm_hour == 2) &amp;&amp; /* 2:00 am */        (data.tm_min == 0) &amp;&amp;        (data.tm_sec == 0)) {        /* do something here */         }}

The second case was to determine if the date and time was during daylight savings time or not. This is used when the date and time get set on the controller, and to display the daylight savings time status. The code is more complex than the interrupt routine. Here is part of the code:

  1. if (year >= 2007) {    /* simple bounds check */     if ((month >= 3) &amp;&amp; (month <= 11)) {        /* get the start date for DST – Second Sunday in March */         if (month == 3) {            for (i = 8; i <= MonthDays(month,year); i++) {                if (DayOfWeek(DaysSinceEpoch(year,month,i)) == SUNDAY) {                    if (day == i) {                        time_now = TO_SECONDS(hour,minute,second);                         time_dst = TO_SECONDS(3,0,0);                         if (time_now >= time_dst) {                            dst = true;                        }                    } else if (day > i) {                        dst = true;                    }                     break;                }            }        }    }}

Testing the Daylight Savings Time algorithm was fairly routine using Unit Testing:

  1. void testDaylightSavings(Test* pTest){  /* original DST */  ct_test(pTest, IsDaylightSavings(31,12,2003) == FALSE);  ct_test(pTest, IsDaylightSavings(26,10,2003) == FALSE);  ct_test(pTest, IsDaylightSavings(25,10,2003) == TRUE);  ct_test(pTest, IsDaylightSavings(10,7,2003) == TRUE);  ct_test(pTest, IsDaylightSavings(6,4,2003) == TRUE);  ct_test(pTest, IsDaylightSavings(1,4,2003) == FALSE);  ct_test(pTest, IsDaylightSavings(1,1,2003) == FALSE);  /* new for 2007 DST */  ct_test(pTest, IsDaylightSavings(1,1,2007) == FALSE);  ct_test(pTest, IsDaylightSavings(3,3,2007) == FALSE);  ct_test(pTest, IsDaylightSavings(7,3,2007) == FALSE);  ct_test(pTest, IsDaylightSavings(8,3,2007) == FALSE);  ct_test(pTest, IsDaylightSavings(9,3,2007) == FALSE);  ct_test(pTest, IsDaylightSavings(10,3,2007) == FALSE);  ct_test(pTest, IsDaylightSavings(11,3,2007) == TRUE);  ct_test(pTest, IsDaylightSavings(10,7,2007) == TRUE);  ct_test(pTest, IsDaylightSavings(3,11,2007) == TRUE);  ct_test(pTest, IsDaylightSavings(4,11,2007) == FALSE);  ct_test(pTest, IsDaylightSavings(7,11,2007) == FALSE);  ct_test(pTest, IsDaylightSavings(8,11,2007) == FALSE);  ct_test(pTest, IsDaylightSavings(30,11,2007) == FALSE);  ct_test(pTest, IsDaylightSavings(31,12,2007) == FALSE);
  3.   return;}

Hope you are getting used to waking up earlier!

About skarg

I write software for a living. So, I dedicated some web space for some stuff that I have worked on. I mostly write embedded C for PC based controllers, but I have dabbled in a few other areas as well.
This entry was posted in software. Bookmark the permalink.

One Response to Daylight savings time

  1. Marceline F. says:

    Thank you for this informative post!! And no, I do not enjoy, nor am I used to, waking up earlier 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *