RTC setting time question
Moderators: adafruit_support_bill, adafruit

RTC setting time question

by Duinowelder on Tue Apr 02, 2013 5:30 pm

I have a simple little "thermostat" box I use to control a relay which acts as a thermostat. When the temperature gets too low the relay closes and this wire goes to the furnace and triggers the furnace relay which starts a circulator pump to heat the hot water from the boiler when the solar hot water system is insufficient for hot showers. I could have done this any one of a number of ways but I set this box up with a LCD display which displays the outside temp, time and solar hot water temp. I wanted to add a function to automatically change the time for daylight savings time. These times and dates are published so I thought I could get the next 4 years programmed in and that would be kind of cool. The function kind of works, it does change something but I am not sure why it changes things to the wrong value?

void DaylightSavingsSchedule(){//start function
 DateTime now = RTC.now();   //get the data from the RTC
 Year =now.year(), DEC; //get the year from the RTC
 Month =now.month(),DEC; //get the month from the RTC
 Day =now.day(),DEC; //get the day from the RTC
 hour =now.hour(),DEC; //get the hour from RTC
 if (Year ==2013 && Month ==4 && Day ==2 && hour ==17&&DaylightTest ==0)//fall back an hour
      {//start if section
       Serial.println (hour);
       Serial.println(now.unixtime());
       now =now.unixtime()-3600;
       Serial.print ("Future ");
       Serial.println(now.unixtime());
       RTC.adjust(DateTime(now.hour(),now.minute(),now.second(),now.day(),now.month(),now.year())); // set time & date
       DaylightTest =1;                            //flag variable so it won't go back in time continously
      }//end if section
}//end function

Duinowelder
 
Posts: 6
Joined: Tue Nov 01, 2011 10:30 am

Re: RTC setting time question

by adafruit_support_bill on Tue Apr 02, 2013 6:16 pm

DateTime is not the same as unixtime, so you can't just assign it like that. But you can construct a new one from the unixtime:

Code: Select all | TOGGLE FULL SIZE
       DateTime future (now.unixtime()-3600);
       RTC.adjust(DateTime(future .hour(),future .minute(),future .second(),future .day(),future .month(),future .year())); // set time & date
User avatar
adafruit_support_bill
 
Posts: 31071
Joined: Sat Feb 07, 2009 10:11 am

Re: RTC setting time question

by Duinowelder on Wed Apr 03, 2013 7:03 am

Thank you so much for getting back to me so promptly, in the meantime I messed around with it, until I got it to work, of course I am not sure it is going to work right until I have done further testing but here is the code I came up with that will change the time automatically for the next three years.

void DaylightSavingsSchedule(){//start function
 if (Year ==2013 && Month ==11 && Day ==2 && hour ==2&&DaylightTest ==0)//fall back an hour
     FallBack();
 if (Year ==2013 && Month ==11 && Day ==4 && hour ==2&&DaylightTest ==1)//reset flag
     DaylightTest =0;
 if (Year ==2014 && Month ==3 && Day ==9 && hour ==2&&DaylightTest ==0)//spring forward an hour
     SpringForward();
if (Year ==2014 && Month ==3 && Day ==10 && hour ==2&&DaylightTest ==1)//reset flag
    DaylightTest =0;
if (Year ==2014 && Month ==11 && Day ==2 && hour ==2&&DaylightTest ==0)//fall back an hour
      FallBack();
if (Year ==2014 && Month ==11 && Day ==3 &&DaylightTest ==1)//reset flag
    DaylightTest =0;
if (Year ==2015 && Month ==3 && Day ==8 && hour ==2&&DaylightTest ==0)//spring forward an hour
     SpringForward();
if (Year ==2015 && Month ==3 && Day ==9 && hour ==2&&DaylightTest ==1)//reset flag
    DaylightTest =0;
if (Year ==2015 && Month ==11 && Day ==1 && hour ==2&&DaylightTest ==0)//fall back an hour
      FallBack();
if (Year ==2015 && Month ==11 && Day ==2 &&DaylightTest ==1)//reset flag
    DaylightTest =0;
if (Year ==2016 && Month ==3 && Day ==13 && hour ==2&&DaylightTest ==0)//spring forward an hour
     SpringForward();
if (Year ==2016 && Month ==3 && Day ==14 && hour ==2&&DaylightTest ==1)//reset flag
    DaylightTest =0;
if (Year ==2016 && Month ==11 && Day ==6 && hour ==2&&DaylightTest ==0)//fall back an hour
      FallBack();
if (Year ==2016 && Month ==11 && Day ==7 &&DaylightTest ==1)//reset flag
    DaylightTest =0;
}//end function
void SpringForward(){//start function
       DateTime now = RTC.now();                   //get the data from the RTC
       now =now.unixtime()+3600;                   //subtracts an hour from the time
       RTC.adjust(DateTime(now.unixtime()));       //resets the time to an hour earlier
       DaylightTest =1;                            //flag variable so it won't go back in time continously
}//end function
 
void FallBack(){//start function
       DateTime now = RTC.now();                   //get the data from the RTC
       now =now.unixtime()-3600;                   //subtracts an hour from the time
       RTC.adjust(DateTime(now.unixtime()));       //resets the time to an hour earlier
       DaylightTest =1;                            //flag variable so it won't go back in time continously
}//end function

[/quote]
Duinowelder
 
Posts: 6
Joined: Tue Nov 01, 2011 10:30 am

Re: RTC setting time question

by odometer on Sat Apr 06, 2013 8:10 pm

Difficulties with Daylight Saving Time seem fairly common.

Another source of difficulties is month numbering. It seems that in the old DateTime library, months are numbered 0 to 11 (yes, I hate this too); whereas in the more recent Time library, the month numbering is from 1 to 12. Which library are you using? (Test: what day comes after 6/30 ? Is it 6/31 or 7/1 ?)

"Thirty days hath September" - numeric version:
Fourth, eleventh, ninth, and sixth,
Thirty days to each affix;
Every other thirty-one
Except the second month alone.


Assuming you have month numbering taken care of, that leaves Daylight Saving Time.
The way I handle adjustment of my clock for Daylight Saving Time is I don't. Internally, the clock keeps "winter" time all year. When Daylight Saving Time is in effect, I simply display a time that is one hour later. I made a set of functions to handle this, but it is probably more than you need. Instead is a list of faux "Unix Time" values when the change happens. All of these values are in local "winter" time. If your time value is greater than the first number in some pair but less than the second, add 3600 before converting to human units for display.

Code: Select all | TOGGLE FULL SIZE
// these are for the U.S. Daylight Saving Time rule
// DST start & end moments, in faux "Unix Time"
// start with 2013

1362880800
1383440400

1394330400
1414890000

1425780000
1446339600

1457834400
1478394000

1489284000
1509843600

1520733600
1541293200

1552183200
1572742800

1583632800
1604192400

1615687200
1636246800

1647136800
1667696400

1678586400
1699146000

1710036000
1730595600

1741485600
1762045200

1772935200
1793494800

1804989600
1825549200

1836439200
1856998800

// this will get you through 2028
odometer
 
Posts: 98
Joined: Sun Aug 21, 2011 11:01 pm

Re: RTC setting time question

by Duinowelder on Mon Apr 08, 2013 8:38 am

Nice and succinct, thank you very much, I am learning a lot. I must be using the library from one to twelve since in Jan it did not start at zero. I am simply displaying the date in M/D/Y format. I will write a function based on your information Thanks again
Duinowelder
 
Posts: 6
Joined: Tue Nov 01, 2011 10:30 am

Re: RTC setting time question

by adafruit_support_mike on Mon Apr 08, 2013 11:19 am

FWIW, most date algorithms use a 146097-day cycle that spans a full 400-year cycle of leap years. Within a year, coders shift the beginning of the year to March 1st so the leap day (if it occurs) is the last day of the year.

A fairly well commented piece of sample code lives here: http://c2.com/cgi/wiki?PerpetualCalendarAlgorithm
When you void a product warranty, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
adafruit_support_mike
 
Posts: 10257
Joined: Thu Feb 11, 2010 2:51 pm