I am working with an Arduino and a real time clock chip. The chip compensates for leap years and such, so it will always have the correct date, but it does not handle daylight s
I found this all very helpful. Brazil has some special issues, southern hemisphere, and sometimes Carnival overlaps the fall change date.
In these cases, the legislature delays DST by one week. The US Naval observatory calculation can find easter, (at http://aa.usno.navy.mil/faq/docs/easter.php, retrieved 1/3/2017), and carnival is an exact number of days earlier, the week-end before ash wednesday (Mardi Gras means "fat tuesday").
So, in C:
static const uint8_t carnival[] = {
0x04, 0x24, 0x24, 0x21, // 2000... 2031
0x01, 0x09, 0x48, 0x09, // 2032... 2063
0x4a, 0x40, 0x4a, 0x52, // 2064... 2095
0x02, 0x90, 0x12, 0x94 // 2096... 2127
}
/* Returns the current time offset. */
int dst(struct tm *tm_ptr)
{
int st = 0;
int dst = 60;
int mon = tm_ptr->tm_mon;
int mday, previous_sunday;
int gmt_offset = tm_ptr->gmt_offset;
// If not Brasilia or Amazon time, no DST.
if(gmt_offset != -240 && gmt_offset != -300)
return st;
if(NOV < mon || FEB > mon) // Summer?
return dst;
else if(NOV > mon && FEB < mon) // Winter?
return st;
mday = tm_ptr->tm_mday;
previous_sunday = mday - tm_ptr->tm_wday;
// Begin DST on first Sunday of November.
if(NOV == mon) // If it's November... i.e. spring, so forward
{
if(previous_sunday < 1) // Before Sunday, week 1?
{
return st;
} else { // After or during Sunday, week 1
return dst;
}
// End DST in February, accounting for Carnival.
} else { // It has to be February, i.e. fall, so backward.
int year, week_start;
year = tm_ptr->tm_year;
if(0 == (carnival[year/8] & (1 << (year%8))))
week_start = 15; // 3rd Sunday is not in Carnival.
else
week_start = 22; // Use 4th Sunday, 1 week after Carnival.
if(previous_sunday < (week_start-1))
return dst;
if(previous_sunday < week_start) {
if(tm_ptr->tm_isdst == st) // if it already fell backward, stay.
return st;
return dst;
}
// On or after the correct Sunday?
return st;
}
}