Set Tz
From: https://randomnerdtutorials.com/esp32-ntp-timezones-daylight-saving/
ESP32 NTP Time – Setting Up Timezones
and Daylight Saving Time
In this tutorial, you’ll learn how to properly get the time with the ESP32 for
your timezone and consider daylight saving time (if that’s the case ). The ESP32
will request the time from an NTP server, and the time will be automatically
adjusted for your timezone with or without daylight saving time.
ESP32 Timezones and Daylight Saving Time
Quick Answer: call
setenv( “TZ”, timezone, 1 )
, where timezone is one of the
timezones listed here. Then, call tzset() to update to that timezone.
If you’re getting started, we recommend taking a look at the following tutorial
first to learn how to get date and time from an NTP server:
ESP32 NTP Client-Server: Get Date and Time (Arduino IDE )
In that previous tutorial, we’ve shown an option to set up your timezone.
However, that example doesn’t take into account daylight saving time. Continue
reading this tutorial to learn how to set up the timezone and daylight saving
time properly.
Thanks to one of our readers (Hardy Maxa ) who shared this information with us.
ESP32 Setting Timezone with Daylight Saving Time
According to documentation:
“To set local timezone, use setenv and tzset POSIX functions. First, call setenv
to set TZ environment variable to the correct value depending on device location
. Format of the time string is described in libc documentation. Next, call tzset
to update C library runtime data for the new time zone. Once these steps are
done, localtime function will return correct local time, taking time zone offset
and daylight saving time into account.”
You can check a list of timezone string variables here.
For example, I live in Porto. The timezone is Europe/Lisbon. From the list of
timezone string variables, I see that the timezone string variable for my
location is WET0WEST,M3.5.0/1,M10.5.0, so after connecting to the NTP server, to
get the time for my location I need to call:
setenv( "TZ","WET0WEST,M3.5.0/1,M10.5.0",1 );
Followed by:
tzset();
Let’s look at a demo sketch to understand how it works and how to use it in your
ESP32 project.
ESP32 Timezone and DST Example Sketch
The following example was provided by one of our followers (Hardy Maxa ), we’ve
just made a few modifications.
Copy the following code to your Arduino IDE.
/*H********************************************************************
* RTC demo for ESP32, that includes TZ and DST adjustments
Get the POSIX style TZ format string from
https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
Created by Hardy Maxa Complete project details at:
https://RandomNerdTutorials.com/esp32-ntp-timezones-daylight-saving/
**********************************************************************/
#include <WiFi.h>
#include "time.h"
//************************* DEFINES ************************************
//************************* PROTOTYPES ************************************
void setTimezonegString timezone );
void initTime( String timezone );
void printLocalTime();
void startWifi();
void setTime( int yr, int month, int mday, int hr, int minute, int sec
, int isDst );
//************************* VARIABLES ************************************
const char *ssid = "REPLACE_WITH_YOUR_SSID";
const char *wifipw = "REPLACE_WITH_YOUR_PASSWORD";
/*F********************************************************************
*
**********************************************************************/
void
setup()
{
Serial.begin( BAUD );
Serial.setDebugOutput( true );
startWifi();
initTime( "WET0WEST,M3.5.0/1,M10.5.0" ); // SET FOR Melbourne/AU
printLocalTime();
}
/*F********************************************************************
*
**********************************************************************/
void
loop()
{
int cnt;
// PUT YOUR MAIN CODE HERE, TO RUN REPEATEDLY
Serial.println( "Lets show the time for a bit. Starting with TZ "
"set for Melbourne/Australia" );
for( cnt =0; cnt < 10; cnt++ )
{
delay( 1000 );
printLocalTime();
}
Serial.println();
Serial.println( "Now - change timezones to Berlin" );
setTimezone( "CET-1CEST,M3.5.0,M10.5.0/3" );
for( cnt =0; cnt < 10; cnt++ )
{
delay( 1000 );
printLocalTime();
}
Serial.println();
Serial.println( "Now - Lets change back to Lisbon and watch Daylight "
"savings take effect" );
setTimezone( "WET0WEST,M3.5.0/1,M10.5.0" );
printLocalTime();
Serial.println();
Serial.println( "Now change the time. 1 min before DST takes effect. "
"(1st Sunday of Oct)" );
Serial.println( "AEST = Australian Eastern Standard Time. = UTC+10" );
Serial.println( "AEDT = Australian Eastern Daylight Time. = UTC+11" );
setTime( 2021,10,31,0,59,50,0 ); // SET TO 1 MINUTE BEFORE DAYLIGHT SAVINGS
// HAPPENS
for( cnt =0; cnt < 20; cnt++ )
{
delay( 1000 );
printLocalTime();
}
Serial.println( "Now change the time. 1 min before DST should finish. "
"(1st Sunday of April)" );
setTime( 2021,3,28,1,59,50,1 ); // SET TO 1 MINUTE BEFORE DAYLIGHT SAVINGS
// COMES IN. Note. isDst=1 TO INDICATE THAT TIME WE SET IN DST
for( cnt =0; cnt < 20; cnt++ )
{
delay( 1000 );
printLocalTime();
}
// WATCH TIME AND SEE HOW LONG IT TAKES FOR NTP TO FIX CLOCK
Serial.println( "Waiting for NTP update (expect in about 1 hour )" );
while( 1 )
{
delay( 1000 );
printLocalTime();
}
}
/*F********************************************************************
*
**********************************************************************/
void
setTimezonegString timezone )
{
Serial.printf( " Setting Timezone to %s\n",timezone.c_str() );
// ADJUST TZ. CLOCK SETTINGS ARE ADJUSTED TO SHOW THE NEW LOCAL TIME
setenv( "TZ", timezone.c_str(), 1 );
tzset();
}
/*F********************************************************************
*
**********************************************************************/
void
initTime( String timezone )
{
struct tm timeinfo;
Serial.println( "Setting up time" );
configTime( 0, 0, "pool.ntp.org" );// 1ST CONN TO NTP SRVR, WITH 0 TZ OFFSET
if( !getLocalTime( &timeinfo ) )
{
Serial.println(" Failed to obtain time" );
return;
}
Serial.println( " Got the time from NTP" );
setTimezone( timezone ); // NOW SET REAL TIMEZONE
}
/*F********************************************************************
*
**********************************************************************/
void
printLocalTime()
{
struct tm timeinfo;
if( !getLocalTime( &timeinfo ) )
{
Serial.println( "Failed to obtain time 1" );
return;
}
Serial.println( &timeinfo, "%A, %B %d %Y %H:%M:%S zone %Z %z " );
}
/*F********************************************************************
*
**********************************************************************/
void
startWifi()
{
WiFi.begin( ssid, wifipw );
Serial.println( "Connecting Wifi" );
while( WiFi.status() != WL_CONNECTED )
{
Serial.print( "." );
delay( 500 );
}
Serial.print( "Wifi RSSI=" );
Serial.println( WiFi.RSSI() );
}
/*F********************************************************************
*
**********************************************************************/
void
setTime( int yr, int month, int mday, int hr, int minute, int sec, int isDst )
{
struct tm tm;
tm.tm_year = yr - 1900; // SET DATE
tm.tm_mon = month-1;
tm.tm_mday = mday;
tm.tm_hour = hr; // SET TIME
tm.tm_min = minute;
tm.tm_sec = sec;
tm.tm_isdst = isDst; // 1 OR 0
time_t t = mktime( &tm );
Serial.printf( "Setting time: %s", asctime( &tm ) );
struct timeval now = { .tv_sec = t };
settimeofday( &now, NULL );
}
BTW:
int cnt;
for( cnt =20: cnt--; )
{
xyz();
}
For just a counter, should be a little faster.
How the Code Works
First, you need to include the WiFi library to connect the ESP32 to the internet
(NTP server ) and the time library to deal with time.
#include <WiFi.h>
#include "time.h"
To set the timezone, we created a function called setTimezone() that accepts as
an argument a timezone string.
void
setTimezone( String timezone )
{
Inside that function, we call the setenv() function for the TZ (timezone )
parameter to set the timezone with whatever timezone you pass as an argument to
the setTimezone() function.
setenv( "TZ",timezone.c_str(),1 ); // NOW ADJUST TZ.
// CLOCK SETTINGS ARE ADJUSTED TO SHOW NEW LOCAL TIME
After that, call tzset() function for changes to take effect.
tzset();
We won’t go into detail about the other functions declared in the code because
those were already explained in a previous tutorial:
ESP32-NTP-TimeZones-DST.html
setup()
In the setup(), we initialize Wi-Fi so that the ESP32 can connect to the internet to connect to the NTP server.
initWifi();
Then, call the initTime() function and pass as argument the timezone String. In our case, for Lisbon/PT timezone.
initTime("WET0WEST,M3.5.0/1,M10.5.0" ); // Set for Lisbon/PT
After that, print the current local time.
printLocalTime();
loop()
In the loop() show the local time for ten seconds.
Serial.println( "Lets show the time for a bit. Starting
with TZ set for "
"Lisbon/Portugal" );
for( cnt =0; cnt < 10; cnt++ )
{
delay( 1000 );
printLocalTime();
}
If at any time in your code you need to change the timezone, you can do it by
calling the setTimezone() function and passing as an argument the timezone
string. For example, the following lines change the timezone to Berlin and
display the time for ten seconds.
Serial.println();
Serial.println( "Now - change timezones to Berlin" );
setTimezone( "CET-1CEST,M3.5.0,M10.5.0/3" );
for( cnt =0; cnt < 10; cnt++ )
{
delay(1000 );
printLocalTime();
}
Then, we go back to our local time by calling the setTimezone() function again with the Lisbon/PT timezone string variable.
Serial.println();
Serial.println("Now - Lets change back to Lisbon and watch Daylight savings take effect" );
setTimezone("WET0WEST,M3.5.0/1,M10.5.0" );
printLocalTime();
To check if daylight saving time is taking effect, we’ll change the time to 10 seconds before the winter time takes effect. In our case, it is on the last Sunday of October (it might be different for your location ).
Serial.println();
Serial.println( "Now change time. 1 min before DST takes effect. (Last "
"Sunday of Oct )" );
setTime( 2021,10,31,0,59,50,0 ); // Set it to 1 minute before daylight
//savings comes in.
Then, show time for a while to check that it is adjusting time, taking into account DST.
for( cnt =0; cnt < 20; cnt++ )
{
delay( 1000 );
printLocalTime();
}
After this, let’s change the time again to check if it changes to summer time when it comes the time. In our case, it is on the last Sunday of March.
Serial.println("Now change the time. 1 min before DST should finish. (Last Sunday of March )" );
setTime(2021,3,28,1,59,50,1 ); // Set it to 1 minute before daylight savings comes in. Note. isDst=1 to indicate that the time we set is in DST.
Show the time for a while to check that it is adjusting to the summer time.
for( cnt =0; cnt < 20; cnt++ )
{
delay( 1000 );
printLocalTime();
}
Demonstration
Now, let’s test the code. After inserting your network credentials, upload the
code to your ESP32.
After that, open the Serial Monitor at a baud rate of 115200 and press the ESP32
RST button to start running the code.
First, it shows your local time with the timezone you’ve set on the code.
ESP32 NTP Time Set Timezone
After that, it will change to the other timezone you’ve set on the code. In our
case, we set to Berlin.
ESP32 NTP Time Change between timezones
After that, you should see the change to winter time. In our case, when it’s
2 a.m., the clock goes back one hour.
ESP32 NTP Time Adjust to Winter Time Automatically
We also check if it adjusts to summer time when it comes the time. In the
example below, you can see that the clock goes forward one hour to set summer
time.
ESP32 NTP Time Adjust to Summer Time Automatically
Wrapping Up
This quick tutorial taught you how to set timezone with daylight saving time
using the setenv() and tzset() functions.