struct RTC {
uint8_t sec;
uint8_t min;
uint8_t hour;
uint8_t dow;
uint8_t day;
uint8_t month;
uint8_t year;
uint8_t config;
uint16_t doy; // not BCD!
};
tatic uint8_t dec2bcd(uint8_t x) //
{ //
uint8_t n = 0; //
while(x > 9) x -= 10, n += 0x10; //
n += x; //
return n; //
} //
//
void ntp_to_rtc(uint32_t t, RTC &rtc) //
{ //
t -= (2208988800UL); // Convert to common time_t epoch (Jan 1 1970)
t += (-5L * 60 * 60); // Adjust for time zone
//
// - Convert seconds to year, day of year, day of week, hours, minutes, seconds
ldiv_t d = ldiv(t, 60); // Seconds
rtc.sec = dec2bcd(d.rem); //
d = ldiv(d.quot, 60); // Minutes
rtc.min = dec2bcd(d.rem); //
d = ldiv(d.quot, 24); // Hours
rtc.hour = dec2bcd(d.rem); //
rtc.dow = ((d.quot + 4) % 7) + 1; // Day of week
d = ldiv(d.quot, 365); // Day of year
int doy = d.rem; //
unsigned yr = d.quot + 1970; // Year
//
// - Adjust day of year for leap years
unsigned ly; // Leap year
for(ly = 1972; ly < yr; ly += 4) { // Adjust year and day of year for leap years
if(!(ly % 100) && (ly % 400)) continue; // Skip years that are divisible by 100 and not by 400
--doy; //
} //
if(doy < 0) doy += 365, ++yr; // Handle day of year underflow
rtc.year = dec2bcd(yr - 2000); //
//
// - Find month and day of month from day of year
static uint8_t const dm[2][12] = { // Days in each month
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, // Not a leap year
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} // Leap year
}; //
int day = doy; // Init day of month
rtc.month = 0; // Init month
ly = (yr == ly) ? 1 : 0; // Make leap year index 0 = not a leap year, 1 = is a leap year
while(day > dm[ly][rtc.month]) day -= dm[ly][rtc.month++]; // Calculate month and day of month
//
rtc.doy = doy + 1; // - Make date ones based
rtc.day = dec2bcd(day + 1); //
rtc.month = dec2bcd(rtc.month + 1); //
rtc.ampm = 0; //
} //
//