by

Automatic DST Conversion with the Alpha Clock Five

If you live in a place that observes Daylight Saving Time, you might be interested to know how you can program your Alpha Clock Five to do automatic DST conversion.

Using the tmElement_t and time_t structures I was able to come up with a few methods that will allow your Alpha Clock Five seamlessly to convert to and from Daylight Saving Time.

At the time that this article was written DST was set to begin on the second Sunday in March at 2:00AM and set to end on the first Sunday in November at 2:00AM.

First you’ll need to create a few global variables:

//I put these near the top of the sketch where it says Other global variables:

boolean IsDST;
boolean ChangedToDST = false;

Then you can write a few methods:

//The first method is used to initially set up the IsDST value, and then is used during DST to reevaluate

void SetIsDST() {

    int sunday = 1;
    int march = 3;

    int november = 11;

    int DaysInWeek = 7;
    int firstDayOfMonth = 0;

    //BEGIN MARCH CALCULATIONS
    tmElements_t firstOfMarchTm;
    firstOfMarchTm.Second = 0;
    firstOfMarchTm.Hour = 0;
    firstOfMarchTm.Minute = 0;
    firstOfMarchTm.Day = 1;
    firstOfMarchTm.Month = march;
    firstOfMarchTm.Year = year() - 1970;

    time_t firstOfMarch = makeTime(firstOfMarchTm);

    firstDayOfMonth = weekday(firstOfMarch);

    int secondSundayOfMarch = (firstDayOfMonth == sunday) ? 8 : (firstDayOfMonth + DaysInWeek) + (DaysInWeek - (firstDayOfMonth - 1));

    tmElements_t secondSundayOfMarchTm;
    secondSundayOfMarchTm.Hour = 2;
    secondSundayOfMarchTm.Minute = 0;
    secondSundayOfMarchTm.Day = secondSundayOfMarch;
    secondSundayOfMarchTm.Month = march;
    secondSundayOfMarchTm.Year = year() - 1970;

    time_t secondSundayOfMarch_t = makeTime(secondSundayOfMarchTm);
    //END MARCH CALCULATIONS

    //BEGIN NOVEMBER CALCULATIONS
    tmElements_t firstOfNovemberTm;
    firstOfNovemberTm.Second = 0;
    firstOfNovemberTm.Hour = 0;
    firstOfNovemberTm.Day = 1;
    firstOfNovemberTm.Month = november;
    firstOfNovemberTm.Year = year() - 1970;

    time_t firstOfNovember = makeTime(firstOfNovemberTm);

    firstDayOfMonth = weekday(firstOfNovember);

    int firstSundayOfNovember = (firstDayOfMonth == sunday) ? 1 : (DaysInWeek - (firstDayOfMonth - 1)) + 1;

    tmElements_t firstSundayOfNovemberTm;
    firstSundayOfNovemberTm.Second = 0;
    firstSundayOfNovemberTm.Hour = 2;
    firstSundayOfNovemberTm.Minute = 0;
    firstSundayOfNovemberTm.Day = firstSundayOfNovember;
    firstSundayOfNovemberTm.Month = november;
    firstSundayOfNovemberTm.Year = year() - 1970;

    time_t firstSundayOfNovember_t = makeTime(firstSundayOfNovemberTm);
    //END NOVEMBER CALCULATIONS

    tmElements_t rightNowTm;
    rightNowTm.Second = second();
    rightNowTm.Hour = hour();
    rightNowTm.Minute = minute();
    rightNowTm.Day = day();
    rightNowTm.Month = month();
    rightNowTm.Year = year() - 1970;

    time_t rightNow_t = makeTime(rightNowTm);

    IsDST = (rightNow_t >= secondSundayOfMarch_t && rightNow_t < firstSundayOfNovember_t) ;
}
//The second method is used to reevaluate during non-DST

void SetIsNotDST() {

    int sunday = 1;

    int march = 3;
    int november = 11;

    int DaysInWeek = 7;
    int firstDayOfMonth = 0;

    //BEGIN MARCH CALCULATIONS
    tmElements_t firstOfMarchTm;
    firstOfMarchTm.Second = 0;
    firstOfMarchTm.Hour = 0;
    firstOfMarchTm.Minute = 0;
    firstOfMarchTm.Day = 1;
    firstOfMarchTm.Month = march;
    firstOfMarchTm.Year = (year() + 1) - 1970;

    time_t firstOfMarch = makeTime(firstOfMarchTm);

    firstDayOfMonth = weekday(firstOfMarch);

    int secondSundayOfMarch = (firstDayOfMonth == sunday) ? 8 : (firstDayOfMonth + DaysInWeek) + (DaysInWeek - (firstDayOfMonth - 1));

    tmElements_t secondSundayOfMarchTm;
    secondSundayOfMarchTm.Hour = 2;
    secondSundayOfMarchTm.Minute = 0;
    secondSundayOfMarchTm.Day = secondSundayOfMarch;
    secondSundayOfMarchTm.Month = march;
    secondSundayOfMarchTm.Year = (year() + 1) - 1970;

    time_t secondSundayOfMarch_t = makeTime(secondSundayOfMarchTm);
    //END MARCH CALCULATIONS

    //BEGIN NOVEMBER CALCULATIONS
    tmElements_t firstOfNovemberTm;
    firstOfNovemberTm.Second = 0;
    firstOfNovemberTm.Hour = 0;
    firstOfNovemberTm.Day = 1;
    firstOfNovemberTm.Month = november;
    firstOfNovemberTm.Year = year() - 1970;

    time_t firstOfNovember = makeTime(firstOfNovemberTm);

    firstDayOfMonth = weekday(firstOfNovember);

    int firstSundayOfNovember = (firstDayOfMonth == sunday) ? 1 : (DaysInWeek - (firstDayOfMonth - 1)) + 1;

    tmElements_t firstSundayOfNovemberTm;
    firstSundayOfNovemberTm.Second = 0;
    firstSundayOfNovemberTm.Hour = 1;
    firstSundayOfNovemberTm.Minute = 0;
    firstSundayOfNovemberTm.Day = firstSundayOfNovember;
    firstSundayOfNovemberTm.Month = november;
    firstSundayOfNovemberTm.Year = year() - 1970;

    time_t firstSundayOfNovember_t = makeTime(firstSundayOfNovemberTm);
    //END NOVEMBER CALCULATIONS

    tmElements_t rightNowTm;
    rightNowTm.Second = second();
    rightNowTm.Hour = hour();
    rightNowTm.Minute = minute();
    rightNowTm.Day = day();
    rightNowTm.Month = month();
    rightNowTm.Year = year() - 1970;

    time_t rightNow_t = makeTime(rightNowTm);

    IsDST = !((rightNow_t >= firstSundayOfNovember_t) && (rightNow_t < secondSundayOfMarch_t));

}

Then add this in the setup() method:

//I added this after the time has been retrieved from the RTC

SetIsDST();

if(!IsDST) {
    adjustTime(-3600);
} else {
    ChangedToDST = true;
}

And finally, add this in the loop() method:

//I added this right at the beginning of the loop() method

boolean wasDST = IsDST;

if(ChangedToDST) {
    SetIsDST();
} else {
    SetIsNotDST();
}

if (wasDST != IsDST) {
    if(IsDST) {
        setTime(hour() + 1, minute(), second(), day(), month(), year());
        ChangedToDST = true;
    } else {
        setTime(hour() - 1, minute(), second(), day(), month(), year());
        ChangedToDST = false;
    }
}

Write a Comment

Comment