carduinodst

Arduino Code to determine if we are in DST or not


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:

  1. Does this code look sane?
  2. Is there a better way of doing this? Remember it isn't a computer, its an ESP32C3; so you don't get date for example- it has no idea what the date/time is.

Solution

  • Does this code look sane?

    No.

    1. DST is not assigned at all under most timeonfo values.

    2. 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;