Page 1 of 1

Daylight Saving Time and ESP32

Posted: Mon Nov 19, 2018 3:45 am
by TimTim
Hello everyone,

I am working with esp32 and daylight saving time (DST). My situation is my devices work in USA or EU, etc.
When user set the timer, when the country applies DST-the hour will be forward or upward an hour, the devices should also update its time to synchronize the time.
However, every country has its own time zone and DST rule.
So my question is how ESP32 can adapt with each country time rule.
I found some libraries, it needs the starting/ending time of DST, and also the region.
Starting time, ending time and region are different in each country.
Do we need the database or server to manage data? or ESP32 can do itself?
Thanks.

Thank everyone a lot.

Re: Daylight Saving Time and ESP32

Posted: Mon Nov 19, 2018 4:43 am
by ESP_igrr

Re: Daylight Saving Time and ESP32

Posted: Thu Aug 17, 2023 2:34 pm
by Bill Glass
The code below will automatically adjust the RTC using a user-defined rule. I am using the time.h library''s functions. French time is Unix time+delta where delta=3600sec in Winter and 7200 in Summer. France changes last Saturday of March or October at GMT midnite. You can see below that I first look for the day of the week(Sun=0) for April 1 or November 1 then back up by that value. This gives me the current Unix time moment for automatically adjusting the RTC with delta. You can easily modify this rule for your country/state.

Code: Select all

struct timeval tv={unix_time+UnixTimeAdj(unix_time),0};
settimeofday(&tv, NULL); 

unsigned long UnixTimeAdj(unsigned long unixTime)
{ 
  struct tm timeinfo;
  unsigned add1,add0,longval;
  int Year,Weekday,delta;
  //----------- Get current year --------
  time_t timestamp = unixTime;
  struct tm * now = localtime( & timestamp );
  Year=now->tm_year+1900;
  //----------- Get Unix time for start of DST ----
  timeinfo={0};
  timeinfo.tm_year = Year - 1900;//April 1 at 00:00
  timeinfo.tm_mon  = 3; //April
  timeinfo.tm_mday = 1;
  timeinfo.tm_hour = 0;
  timeinfo.tm_min = 0;
  timeinfo.tm_sec = 0;
  longval = difftime(mktime(&timeinfo), (time_t)0);
  Weekday=timeinfo.tm_wday;
  delta=Weekday; //find DST start Unix time for last Sunday morning in March 
  add1=longval-(unsigned long)delta*(unsigned long)24*(unsigned long)3600; //back up to last Sunday of previous month
  //----------- Get Unix time for end of DST ----
  timeinfo.tm_mon  = 10; //Nov
  longval = difftime(mktime(&timeinfo), (time_t)0);
  Weekday=timeinfo.tm_wday;
  delta=Weekday;//find DST end Unix time for last Sunday morning in Oct. 
  add0=longval-(unsigned long)delta*(unsigned long)24*(unsigned long)3600; //back up to last Sunday of previous month
  //----- calculate GMT offset according to DST or not ------
  if ((unixTime>add1)&&(unixTime<add0)) return 7200UL; //2 hour offset from GMT during DST
  else return 3600UL; //1 hour offset from GMT NOT during DST
}

Re: Daylight Saving Time and ESP32

Posted: Fri Aug 18, 2023 6:22 am
by Bill Glass
Sorry, corrected a coupla errors in my description. Forget the last post and look here:


The code below will automatically adjust the RTC using a user-defined rule. I am using the time.h library's functions. French time is Unix time+offset where offset=3600sec in Winter and 7200 in Summer. France changes last Saturday of March or October at GMT midnite. You can see below that I first look for the day of the week(Sun=0) for April 1 or November 1 then back up by that value. This gives me the current Unix time moment for automatically adjusting the RTC with offset. You can easily modify this rule for your country/state.

Code: Select all

struct timeval tv={unix_time+UnixTimeAdj(unix_time),0};
settimeofday(&tv, NULL); 

unsigned long UnixTimeAdj(unsigned long unixTime)
{ 
  struct tm timeinfo;
  unsigned add1,add0,longval;
  int Year,Weekday,delta;
  //----------- Get current year --------
  time_t timestamp = unixTime;
  struct tm * now = localtime( & timestamp );
  Year=now->tm_year+1900;
  //----------- Get Unix time for start of DST ----
  timeinfo={0};
  timeinfo.tm_year = Year - 1900;//April 1 at 00:00
  timeinfo.tm_mon  = 3; //April
  timeinfo.tm_mday = 1;
  timeinfo.tm_hour = 0;
  timeinfo.tm_min = 0;
  timeinfo.tm_sec = 0;
  longval = difftime(mktime(&timeinfo), (time_t)0);
  Weekday=timeinfo.tm_wday;
  delta=Weekday; //find DST start Unix time for last Sunday morning in March 
  add1=longval-(unsigned long)delta*(unsigned long)24*(unsigned long)3600; //back up to last Sunday of previous month
  //----------- Get Unix time for end of DST ----
  timeinfo.tm_mon  = 10; //Nov
  longval = difftime(mktime(&timeinfo), (time_t)0);
  Weekday=timeinfo.tm_wday;
  delta=Weekday;//find DST end Unix time for last Sunday morning in Oct. 
  add0=longval-(unsigned long)delta*(unsigned long)24*(unsigned long)3600; //back up to last Sunday of previous month
  //----- calculate GMT offset according to DST or not ------
  if ((unixTime>add1)&&(unixTime<add0)) return 7200UL; //2 hour offset from GMT during DST
  else return 3600UL; //1 hour offset from GMT NOT during DST
}

Re: Daylight Saving Time and ESP32

Posted: Sat Aug 26, 2023 7:51 pm
by JoeSensoric
There is an NTP example which includes converting time to local timezone including DST:
https://github.com/espressif/esp-idf/bl ... ple_main.c

The example uses the standard C timezone definition described here:
https://www.gnu.org/software/libc/manua ... iable.html

From that example:

Code: Select all

// Set timezone to Eastern Standard Time and print local time
    setenv("TZ", "EST5EDT,M3.2.0/2,M11.1.0", 1);
    tzset();
    localtime_r(&now, &timeinfo);
    strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
    ESP_LOGI(TAG, "The current date/time in New York is: %s", strftime_buf);

Re: Daylight Saving Time and ESP32

Posted: Sun Aug 27, 2023 12:43 pm
by Bill Glass
Interesting, looks like less code, but (without studying all of your documentation) does it take care of all the different rules governing when DST switches for all countries. If so, I might try it for my 2 applications.

Re: Daylight Saving Time and ESP32

Posted: Mon Aug 28, 2023 9:11 am
by Bill Glass
In my application using the ESP32, I am not using an NTP server. I need to use ESP-NOW. I have to connect to internet via an additional ESP01 chip. I use AT commands and ThingSpeak's ThingHTTP for the URL of "https://timezonedb.com/unix-time".

I tried your example while using the ESP32 wifi connected to an NTP server instead of ESP-NOW.

Seems to work for me.

According to "https://github.com/nayarsystems/posix_t ... /zones.csv" , I get
America/New_York "EST5EDT,M3.2.0,M11.1.0" instead of: "EST5EDT,M3.2.0/2,M11.1.0" in your example.

What is the "/2" for in "M3.2.0/2" ?

Re: Daylight Saving Time and ESP32

Posted: Sat Oct 21, 2023 8:57 am
by JoeSensoric
Bill Glass wrote:
Mon Aug 28, 2023 9:11 am
According to "https://github.com/nayarsystems/posix_t ... /zones.csv" , I get
America/New_York "EST5EDT,M3.2.0,M11.1.0" instead of: "EST5EDT,M3.2.0/2,M11.1.0" in your example.

What is the "/2" for in "M3.2.0/2" ?
It's the time when the change occurs:
The time fields specify when, in the local time currently in effect, the change to the other time occurs. If omitted, the default is 02:00:00.
Source: https://www.gnu.org/software/libc/manua ... iable.html

As "2" is the default, both definitions are correct.

Re: Daylight Saving Time and ESP32

Posted: Sat Oct 21, 2023 11:01 pm
by tommeyers
There is a time zone database (tzdb).