I am writing C code for an ESP32C3, so an Arduino type piece of hardware. There is no internal clock, so to get the time I talking to an NTP server on the internet.
I am also talking to a weather server to get the weather locally, including the sunrise and sunset.
Now all is well, except the fact that the weather server doesn't seem to know about daylight saving times, so it gives me values that are one hour out.
So I wrote this routine to try to figure out if I need to adjust the answer for sunrise/sunset [its in Arduino C]
Here is the definition, yes I am in Europe.
Daylight saving time always starts on the second Sunday in March and ends on the first Sunday in November in the United States. This contrasts with the UK and European Union, where summer time begins on the last Sunday in March and ends on the last Sunday in October.
char dayName[10];
char dayMonth[2];
char monthYear[2];
strftime(dayName,64,"%A", &timeinfo); // day of the week
strftime(dayMonth,64,"%d", &timeinfo); // day of the month
strftime(monthYear,64,"%B", &timeinfo); // month of the year
if (!strcmp(dayName, "Sunday")) {
if (atoi(monthYear) == 10) {
if (atoi(dayMonth) > 31 - 7) {
// last Sunday of the month October, DST = false
DST = false;
}
}
if (atoi(monthYear) == 3) {
if (atoi(dayMonth) > 31 - 7) {
// last Sunday of the month March, DST = false
DST = true;
}
}
}
Get the time with this routine
const char* ntpServer = "ch.pool.ntp.org";
const long gmtOffset_sec = 3600;
const int daylightOffset_sec = 0;
void getTime() {
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
if(!getLocalTime(&timeinfo)){
//Serial.println("Failed to obtain time");
return;
}
}
Obviously I don't set the daylight variable before I get the time because I don't know if I am in DST. Chicken and Egg.
Questions:
Does this code look sane?
No.
DST
is not assigned at all under most timeonfo
values.
Rather than convert struct tm *timeinfo
to a string and then to a value, simply use the corresponding member of struct tm
.
// if (atoi(monthYear) == 10)
int month = timeinfo.tm_mon + 1
if (month == 10)
Is there a better way of doing this, (?)
First try accessing the .tm_isdst
member after calling getLocalTime(&timeinfo)
.
DST = timeinfo.tm_isds > 0;