Learn how to request date and time from an NTP Server using the ESP32 with Arduino IDE. Getting date and time is useful in data logging projects to timestamp readings. To get time from an NTP Server, the ESP32 needs to have an Internet connection and you don’t need additional hardware (like an RTC clock).
Before proceeding with this tutorial you need to have the ESP32 add-on installed in your Arduino IDE:
Recommended: Get Date and Time with ESP8266 NodeMCU NTP Client-Server
NTP (Network Time Protocol)
NTP stands for Network Time Protocol and it is a networking protocol for clock synchronization between computer systems. In other words, it is used to synchronize computer clock times in a network.
There are NTP servers like pool.ntp.org that anyone can use to request time as a client. In this case, the ESP32 is an NTP Client that requests time from an NTP Server (pool.ntp.org).
Getting Date and Time from NTP Server
To get date and time with the ESP32, you don’t need to install any libraries. You simply need to include the time.h library in your code.
The following code gets date and time from the NTP Server and prints the results on the Serial Monitor. It was based on the example provided by the time.h library.
/*
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp32-date-time-ntp-client-server-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*/
#include <WiFi.h>
#include "time.h"
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 0;
const int daylightOffset_sec = 3600;
void setup(){
Serial.begin(115200);
// Connect to Wi-Fi
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected.");
// Init and get the time
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
printLocalTime();
//disconnect WiFi as it's no longer needed
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
}
void loop(){
delay(1000);
printLocalTime();
}
void printLocalTime(){
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
return;
}
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
Serial.print("Day of week: ");
Serial.println(&timeinfo, "%A");
Serial.print("Month: ");
Serial.println(&timeinfo, "%B");
Serial.print("Day of Month: ");
Serial.println(&timeinfo, "%d");
Serial.print("Year: ");
Serial.println(&timeinfo, "%Y");
Serial.print("Hour: ");
Serial.println(&timeinfo, "%H");
Serial.print("Hour (12 hour format): ");
Serial.println(&timeinfo, "%I");
Serial.print("Minute: ");
Serial.println(&timeinfo, "%M");
Serial.print("Second: ");
Serial.println(&timeinfo, "%S");
Serial.println("Time variables");
char timeHour[3];
strftime(timeHour,3, "%H", &timeinfo);
Serial.println(timeHour);
char timeWeekDay[10];
strftime(timeWeekDay,10, "%A", &timeinfo);
Serial.println(timeWeekDay);
Serial.println();
}
How the Code Works
Let’s take a quick look at the code to see how it works. First, include the libraries to connect to Wi-Fi and get time.
#include <WiFi.h>
#include "time.h"
Setting SSID and Password
Type your network credentials in the following variables, so that the ESP32 is able to establish an Internet connection and get date and time from the NTP server.
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
NTP Server and Time Settings
Then, you need to define the following variables to configure and get time from an NTP server: ntpServer, gmtOffset_sec and daylightOffset_sec.
NTP Server
We’ll request the time from pool.ntp.org, which is a cluster of timeservers that anyone can use to request the time.
const char* ntpServer = "pool.ntp.org";
GMT Offset
The gmtOffset_sec variable defines the offset in seconds between your time zone and GMT. We live in Portugal, so the time offset is 0. Change the time gmtOffset_sec variable to match your time zone.
const long gmtOffset_sec = 0;
Daylight Offset
The daylightOffset_sec variable defines the offset in seconds for daylight saving time. It is generally one hour, that corresponds to 3600 seconds
const int daylightOffset_sec = 3600;
setup()
In the setup() you initialize the Serial communication at baud rate 115200 to print the results:
Serial.begin(115200);
These next lines connect the ESP32 to your router.
// Connect to Wi-Fi
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected.");
Configure the time with the settings you’ve defined earlier:
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
printLocalTime()
After configuring the time, call the printLocalTime() function to print the time in the Serial Monitor.
In that function, create a time structure (struct tm) called timeinfo that contains all the details about the time (min, sec, hour, etc…).
struct tm timeinfo;
The tm structure contains a calendar date and time broken down into its components:
- tm_sec: seconds after the minute;
- tm_min: minutes after the hour;
- tm_hour: hours since midnight;
- tm_mday: day of the month;
- tm_year: years since 1900;
- tm_wday: days since Sunday;
- tm_yday: days since January 1;
- tm_isdst: Daylight Saving Time flag;
- tm structure documentation.
Get all the details about date and time and save them on the timeinfo structure.
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
return;
}
Then, print all details about the time in the Serial Monitor.
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
Serial.print("Day of week: ");
Serial.println(&timeinfo, "%A");
Serial.print("Month: ");
Serial.println(&timeinfo, "%B");
Serial.print("Day of Month: ");
Serial.println(&timeinfo, "%d");
Serial.print("Year: ");
Serial.println(&timeinfo, "%Y");
Serial.print("Hour: ");
Serial.println(&timeinfo, "%H");
Serial.print("Hour (12 hour format): ");
Serial.println(&timeinfo, "%I");
Serial.print("Minute: ");
Serial.println(&timeinfo, "%M");
Serial.print("Second: ");
Serial.println(&timeinfo, "%S");
To access the members of the date and time structure you can use the following specifiers:
%A | Full weekday name |
%B | Full month name |
%d | Day of the month |
%Y | Year |
%H | Hour in 24h format |
%I | Hour in 12h format |
%M | Minute |
%S | Second |
There are other specifiers you can use to get information in other format, for example: abbreviated month name (%b), abbreviated weekday name (%a), week number with the first Sunday as the first day of week one (%U), and others (read more).
We also show you an example, if you want to save information about time in variables. For example, if you want to save the hour into a variable called timeHour, create a char variable with a length of 3 characters (it must save the hour characters plus the terminating character). Then, copy the information about the hour that is on the timeinfo structure into the timeHour variable using the strftime() function.
Serial.println("Time variables");
char timeHour[3];
strftime(timeHour,3, "%H", &timeinfo);
Serial.println(timeHour);
To get other variables, use a similar process. For example, for the week day, we need to create a char variable with a length of 10 characters because the longest day of the week contains 9 characters (saturday).
char timeWeekDay[10];
strftime(timeWeekDay,10, "%A", &timeinfo);
Serial.println(timeWeekDay);
Serial.println();
Demonstration
After inserting your network credentials and modifying the variables to change your timezone and daylight saving time, you can test the example.
Upload the code your ESP32 board. Make sure you have the right board and COM port selected. After uploading the code, press the ESP32 “Enable” button, and you should get the date and time every second as shown in the following figure.
Wrapping Up
In this tutorial you’ve learned how to get date and time from an NTP server using the ESP32 programmed with Arduino IDE. Now, you can use what you’ve learned here to timestamp the sensor readings in your own projects.
This method only works if the ESP32 is connected to the Internet. If your project doesn’t have access to the internet, you need to use other method. You can use an RTC module like the DS1307.
If you want to learn more about the ESP32, check our resources:
Thanks for reading.
Excellent As usually!
Thanks 😀
I’ve been using the ESP32 with the NTP code in a project linked to a Blynk program for controlling 3 heating circuits.
As a means of checking the ESP32 is still running I send the local time from the ESP32 to Blynk every minute.
The project has been running successfully for weeks until this morning I noticed the time was one hour head of local time. I’m in the UK. It seems as the NTP has brought Summer Time early!
To check I’ve run your example program and I get the same result.
I have these settings
const char* ntpServer = “pool.ntp.org”;
const long gmtOffset_sec = 0;
const int daylightOffset_sec = 3600;
Any ideas please?
Just come across this myself, my keepalive email arrived an hour before the midnight change over when I expected it, Checked clock (NTP) and its one hour ahead, because US NTP – so will be correct again on the 28th March I think
According to this
https://www.meinbergglobal.com/english/faq/faq_33.htm
Looks like you(we) have to handle it locally
Change over dates are ..
US changes on Second Sunday March at 02:00 local standard time
UK changes on Last Sunday March at 01:00 UTC
Then there is the change back in winter to consider
Based on those dates – need to adjust this code item
“const int daylightOffset_sec = 3600;”
Or wait for them to come into sysnc again on the 28th
Just reading thru the Q/A in these comments
Seems a common issue – not seen a definitive answer yet
Although just seen a comment further below by
Jos
March 19, 2020 at 7:13 pm
Looks promising , will be experimenting with that solution tomorrow
Set your timezone correctly.
const char* TZ_INFO = “GMT+0BST-1,M3.5.0/01:00:00,M10.5.0/02:00:00”;
const char* ntpServer = “uk.pool.ntp.org”;
configTime(0, 0, ntpServer);
setenv(“TZ”, TZ_INFO, 1);
tzset();
Thanks, i will try it! Do you mean I need to put both config time under each other like you wrote?
Hey i need help. i use NTP for my ESP32 project
the project should be like this
1. There are 2 ESP32 (A and B)
2. A will send data to B (and printed time stamp as shown in google drive picture)
3. B will receive that data and send it back to A (and printed timed stamp)
4 A will receive data from B
my problem is the NTP time stamp wasn’t synchronized.
when A sending data the timestamp is ( ….:1.945333)
when B receiving data the timestamp is (….:1.3798)
when B sending back the data (…..:1.7583)
when A receiving the data (….:1.949366)
I tried using timeClient.update, timeClient.forceUpdate but still can’t
the code are in gdrive if you want to see.
thankyou so much for your reply.
https://drive.google.com/drive/folders/1XEf3wtC2dMaWqqLWlyOblD8ptyb6DwTf?usp=sharing
Hi dear Sara Santos
How can I set alarm? for example I want set alarm at
Sunday, April 23 2023 10:15:00
Could you help me ?
Best regards
Hassan Nikkhoo
Hi.
Check this example: https://gist.github.com/Tech500/bc4bd77a357b8d401cd13487ef6de800?fbclid=IwAR0lZjcMZFqqygWkqj5Yc6qv3XAoV17tx0u2L6OGXaKwnjXlxhhY2gRl9SU
I think this will help.
Regards,
Sara
Hi
Thank you so much
I visited web sit that you had sent for me but I could not write code for alarm .
Could you help me to write code for set alarm with using NTP Server for example I want set alarm
at Sunday, April 23 2023 10:15:00
Best regards
Nikkhoo
I have problem with ESP32 Client NTP
Error:
.
WiFi connected.
assert failed: sntp_setoperatingmode /IDF/components/lwip/lwip/src/apps/sntp/sntp.c:728 (Required to lock TCPIP core functionality!)
Backtrace: 0x40082549:0x3ffb2090 0x4008db75:0x3ffb20b0 0x40093d52:0x3ffb20d0 0x400e835f:0x3ffb2200 0x400d72ce:0x3ffb2220 0x400d27de:0x3ffb2240 0x400d86fa:0x3ffb2270 0x4008e7ee:0x3ffb2290
Help I need this.
Thanks!
Dule
Perfect tutorial!
Ill need this át once for sure! (For logging with timestamp)
Excellent !
Hi, will this code work on ESP8266 ?
I believe this code DOES NOT work with 8266. The reason is that time.h does not work with 8266 and there is no internal RTC with the 8266.
As you can see, this sketch calls the NTP server only once to set the internal RTC of the ESP32 then it disconnects itself from the Internet.
A Lee,
Where is the time actually gotten from the NTP server?
* I’m thinking that configTime(…) only sets up the communication but does not actually contact the NTP server
* It looks like getLocalTime(&timeinfo)) contacts the NTP server(?) – but if that’s the case wouldn’t this report an error once WiFi is turned off?
Most of us probably want to sync the RTC to the NTP server only periodically. Frequent retrievals of timestamps would be from the ESP32’s internal RTC. Thus we need to isolate the command that does the actual NTP contact. For the whole time our WiFi would be running, never disconnected.
I think I’m misconstruing something, but I’m not sure what it is.
you might want to look at this:
https://forum.arduino.cc/index.php?topic=655222.0
Great! Seems much easier than the NTPclient way we did before.
Hi Joseph, I do like this approach to build a clock because it accesses the NTP server only once. The problem that I have encountered is that the ESP32 “WiFi Manager” is not reliable compare with 8266. This is another article all together!
I love the ESP32 and your clear explanations that are always well tested before publication. I do not understand how we can disconnect from WiFi and also turn off WiFi and still get accurate time data.
Hi Richard.
That’s because the ESP32 has an internal RTC that can keep track of time.
Regards,
Sara
I was puzzled by this point too. If you are updating the article at all, it woudl be good to mention that ESP32 has a built in RTC and that therefore it is only necessary to get a time snapshot from NTP once (or perhaps once per day if the internal clock drifts). For me it was not clear from the article that the snapshop was all that was needed.
Many thanks for a great tutorial on this.
ESP32 internal clock is quite bad, drifts some 10-15 min for every 8 hours or so when in deep sleep. I am using ESP32 for some time sensitive application, had to resort to external GPS module with pps. everytime esp32 wakes up, get the time sync from gps.
Thanks for sharing this experience. Fortunately for me, my application only needs accuracy to a few minutes a day and the ESP is not deep sleeping much, so if I “sniff” the NTP server every 3-4 hours i should be all sorted.
Great idea, how about adding a GPS receiver to update the clock say once a day
Hi
I changed your code
$sql = “INSERT INTO Sensor (value1, value2, value3)
VALUES (‘” . $value1 . “‘, ‘” . $value2 . “‘, ‘” . $value3 . “‘)”;
with this:
$sql = “INSERT INTO `Sensor` ( `value1`, `value2`, `value3`, `reading_time`) VALUES ( ‘” . $value1 . “‘, ‘” . $value2 . “‘, ‘” . $value3 . “‘, UTC_TIMESTAMP())”;
This way I always put a utc timestamp in the database
The problem was that I sometimes had to add 7 hours and other times 8 hours
Esben
Hi.
With this code, you can adjust the daylightOffset_sec (to adjust summer time) and the gmtOffset_sec to adjust the time for your timezone.
Regards,
Sara
No need to set daylightOffset.
Just get timeinfo.tm_isdst
Returns 1 wintertime ,0 summertime
Exellent as always
Thanks 🙂
Thanks for this article in ESP32, iam begginer in this program with C++
Now, would you change
struct tm timeinfo();
to
struct tm timeinto.tm_isdt ? (and of course, change all later instances to that as well)
Do you have a solution for a NTP clock with the 8266? I did not find a similar tutorial for it.
Thanks
Yes Richard, here’s the tutorial: https://randomnerdtutorials.com/esp8266-nodemcu-date-time-ntp-client-server-arduino/
Hey.
Can you request the month as a number instead of “Full month name”?
Nice work from you again.
Greetings Bert.
Hi Bert.
Yes, use the %m specifier.
Regards,
Sara
Thank you.
Hi Sara,
I am new to this, but where do I find the list of specifiers for the function calls?
Is there a Julian Date specifier?
Thanks, and keep up the good work!
Hi.
There’s a link in the tutorial: cplusplus.com/reference/ctime/strftime/
Regards,
Sara
the code wont compile for me at configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
Said configTime ‘was not declared’
sorry i was compiling on an ‘uno’ not an ESP8266
🙂
Hello there!
How can I store the entire “Serial.println(&timeinfo, “%A, %B %d %Y %H:%M:%S”);” into a single variable?
Hi Marcelo.
Yes, you can use, for example:
char now[20];
strftime(now, sizeof(now), “%A, %B %d %Y %H:%M:%S”,&timeinfo);
Serial.print(now);
Regards,
Sara
Thanks!!!
Hi
the code wont compile for me at
‘getLocalTime’ was not declared in this scope
Hi.
This just works with ESP32.
Regards,
Sara
Excellent travail !!
Un grand bravo de France.
Thank you.
Merci 😀
Regards,
Sara
very interesting project:
I plan to update time once a day: how can tha esp keep track of the time?
How could I do That Please?
Thaks for all.
Ciao
Can I use this post to show time on a webpage?
Just the question I am currently grappling with. Does anyone have any suggestions?
Thanks,
John
John,
Webpage shows information/data. Time & date are variables like temperature and humidity. Yes, you can show it on your webpage if your project has a HTML page.
hey Rui.
I use this to sync time once in a while.
// server.on (“/ ntpsync”, HTTP_GET, [] (AsyncWebServerRequest * request) {
// configTime (gmtOffset_sec, daylightOffset_sec, ntpServer);
// request-> redirect (“/ rtc”);
//});
Is there a way to test whether the synchronization is successful.
i can not use this “if(!getLocalTime(&timeinfo)){}”
Cause it only gives me the time of esp32 internal clock.
I solved it by using the NTPClient library.
// #include <NTPClient.h>
//#include <WiFiUdp.h>
// server.on(“/ntpsync”, HTTP_GET, [](AsyncWebServerRequest *request){
// unsigned long nowLong;
//timeval tv;
// timeClient.update();
// int timeout = millis() / 1000;
// timeClient.begin();
// timeClient.setTimeOffset(7200);
//while(!timeClient.update()) {
//timeClient.forceUpdate();
// if((millis() / 1000) > timeout + 5){
// break;
// }
// }
// if (timeClient.update()){
// nowLong = timeClient.getEpochTime();
// tv.tv_sec=nowLong;
// tv.tv_usec = 0;
// settimeofday(&tv, 0);
// request->redirect(“/rtc”);
// }
// else{
// request->send (200, “text/html”, “Failed sync to NTP server”);
// }
// });
Hi Ron:
I think “configTime” configs the internal RTC on the ESP 32 (esp 8266 has no internal RTC) with data from NTP server. See below message from Sarah on April 3rd:
That’s because the ESP32 has an internal RTC that can keep track of time.
getLocalTime(&timeinfo) — get the time and date info from the internal RTC. That’s why once the internal RTC is configurated with NTP data. The ESP 32 can be disconnected from WiFi. I hope this helps.
Hi A Lee,
So, once per day when I want to re-sync the RTC with the NTP server, I just execute the configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); statement again? My WiFi stays on all the time due to the needs of other parts of the application, so I don’t have to turn it on/off for each re-sync.
I have not done this process because I am using the ESP 32 as a clock. Yes, just run this configTime(gmtOffset_sec, daylightOffset_sec, ntpServer) everytime you want to sync the time.
Thanks a lot guys. Especially for the free of charge, free for use permission.
Works like a charm..
Cheers.
Hi,
I just spent several hours searching the internet for how to do automatic daylight saving time changes on the ESP32 using the Arduino IDE. I’m posting this here because it may save someone else having to search so much info.
This code seems to work:
// Comment out original code with manual setting of offsets
// configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
// Can use 0,0 for offsets now because using TZ below
configTime(0, 0, ntpServer);
// Set offsets and daylight saving change rules for UK
setenv(“TZ”,”GMTGMT-1,M3.4.0/01,M10.4.0/02″,1);
// Set offsets etc for Paris – I checked time is UK time +1 hour with this
// setenv(“TZ”,”CET-1CEST,M3.5.0,M10.5.0/3″,1);
tzset();
There are plenty of examples for TZ strings for different time zones on the internet (I searched so many places I can’t remember exactly where I got the strings from for the above code). It currently sets the correct time offset (UTC + 1 hour for daylight saving). I haven’t tested it for change from daylight saving on to off. I guess I’ll find out later this month if it works. I couldn’t think of an easy way to test it now.
Finally thank you so much for the nice ESP32 tutorials. I have made a web server for my loft to control the LED strip lighting in different areas. It also monitors the door on a humane rodent trap and sends me an e-mail if the door closes. I used your NTP, SMTP and web server tutorials to help me get started
Best regards
Dave
and does it work now we are in winter time again?
i have issues with dst now.. esp32 still gives an extra hour today.
i live in gmt plus 1 and with dst. but this code still ads 1 extra hour today(28/10/2020)
regards Thomas
No unfortunately I’m still on +1 DST too. I haven’t looked at why it doesn’t work. Rebooting it made no difference.
Now in November it seems to work right again. I just installed a newer time library (1.6) but i wont know if it works correct until the next dst change…
Mine is still stuck in DST+1. When I saw your message I hoped reboot would fix it, but unfortunately not. Perhaps I’ll try updating my libraries. I’m not actively working on this project any longer. It’s installed in my loft and works fine. The time is only used for time stamps on log entries and emails. I’m the only person that looks at this info and it’s of no significance if the time is +1 hour. It would be more satisfying if it worked properly though. It probably wouldn’t be hard to write a test NTP server, or perhaps there is something available for download. I’m not likely to spend time on this before 2021.
Love you work, question: how do I adjust for daylight saving time?
here’s some more specfics
tm_isdst int Daylight Saving Time flag
The Daylight Saving Time flag (tm_isdst) is greater than zero if Daylight Saving Time is in effect, zero if Daylight Saving Time is not in effect, and less than zero if the information is not available
Nov 1, 2020 – Daylight Saving Time Ended
When local daylight time was about to reach
Sunday, November 1, 2020, 2:00:00 am clocks were turned backward 1 hour
Right how if I read
Serial.print(“Structure of flag tm_isdst =”);
Serial.println(timeinfo.tm_isdst);
I get tm_isdst =0, meaning Daylight Savings Time is not in effect but the clock is still reading Daylight saving time. Do i need to do something to get correct time?
high regards, love your work
Tom Kibalo
This is yet another reason why everyone should have moved on to ESP32 boards. I know they’re not perfect, but internal RTC, WiFi and Bluetooth right on board… ? Arduino Uno what? 😉
The last few days I’ve been trying to do exactly this with a DS3231. Connecting with the NTP server to ‘always’ provide correct time, despite DST, is what I’ve been after this past week.
Now, I want to tie this in and have it displayed onto a 1637 4 digit 7 segment LED for my own little digital clock, that is always right.
Please help me resolve this. i set code to
onst char* ntpServer = “pool.ntp.org”;
const long gmtOffset_sec = -14400;
for my location in US –works fine but I can’t compensate for day light saving time
I used
const int daylightOffset_sec = -3600 ;
const int daylightOffset_sec = 3600 ;
const int daylightOffset_sec = 0 ;
and still get the same time using
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
printLocalTime();
please, please advise–what Am I doing wrong???
Hi Thomas,
If you have not gotten your issue resolved, please check out this link.
mischianti.org/2020/08/08/network-time-protocol-ntp-timezone-and-daylight-saving-time-dst-with-esp8266-esp32-or-arduino/
Hi Thomas,
Forget what I said above! I live in USA GMT -8. My gmtOffset_sec = -28800. My daylightOffset_sec = 3600. I know my clock was running correctly several weeks ago during the time change from DST to ST. I recompile the code on this page. I used -3600 as the daylightOffset_sec. The time came back correctly with Standard Time. A question to you is: Do you have the correct time? My GUESS is that the daylightOffset_sec is used only during “time change”.
Hi!
The line 38
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
returns exit status 1 = ‘configTime’ was not declared in this scope
In which library is this function declared?
Thanks in advance
Stephan
Hi.
Are you using our exact code or did you change something?
Make sure you select an ESP32 board in Tools>Board after compiling the code.
Regards,
Sara
Hi Sara!
Yes, copy & paste, but I’m using a so called pretzel board, arduino nano with old bootloader, Esp8266 onboard…
Hi.
I’m not familiar with that board. But, does it use an ESP8266 chip?
This tutorial is compatible with the ESP32. If that board is not ESP32 compatible, that’s probably your issue.
Regards,
Sara
Was only wrong writing…
Hi,
Unfortunately, no code works on ESP32 Devkit v1. Keeps writing “Failed to obtain time”. Tried all the suggestions on the internet (with and without static IP and daylight saving rules)?
Hello!! I’m Giovane (brazilian) and I need a big help!!
For me it works different.
It is printing in monitor serial:
”
ets Jun 8 2016 00:22:57
rest:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip:0, SPIWP:0xee
clk_drv:0x00, q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load: 0x40078000,len:10124
load:0x40080400,len5856
entry 0x400806a8
”
And I don’t know its!!! I started with ESP32 a short time ago. I work a lot with ESP8266 but with ESP32 it’s being bad!
Help!!
Hi.
Do you get that message over and over again?
Regards,
Sara
What is with the change to Summertime/Wintertime? My clock changed today which would be correct in the USA but not in Germany where it should change at the 28.3. Where can you change this.
Hi,
I think i found a solution for europe dst issue. but i will know for sure after 28th of march..
try this:
put this line on top of your sketch.
const char * defaultTimezone = “CET-1CEST,M3.5.0/2:00:00,M10.5.0/3:00:00”;
(the -1 corresponds to utc plus 1 and you should change this to your timeZone).
and set this
const int gmtOffset_sec = 0;
const int daylightOffset_sec = 0;
now it should work ok.
forgot to mention that you should also ad this line to your main code:
configTime(0,0, ntpServer);
configTzTime(defaultTimezone, ntpServer);
That’s it! I was looking for hours for a working example. With these lines i cloud compile it and get correct german time:
#define MY_NTP_SERVER “fritz.box” //”de.pool.ntp.org”
#define MY_TZ “CET-1CEST,M3.5.0/02,M10.5.0/03” //Timezone: Germany
// Init and get the time
configTime(0,0, MY_NTP_SERVER);
configTzTime(MY_TZ, MY_NTP_SERVER);
printLocalTime();
If copy and pasting some the strings here for various time zone info ( and other code )
You will need to retype the Quote characters once pasted in to your sketch
Otherwise you will end up with an error like this – I did !
Stray \342 in program
Hi All,
Reading through code I saw that we can extract the time and date using method below:
Serial.println(“Time variables”);
char timeHour[3];
strftime(timeHour,3, “%H”, &timeinfo);
Serial.println(timeHour);
However, This is nice; but how would I reload the RTC on the ESP32; Above shows config, get and print. but no RTC load. It must be in the libraries. The code that initializes the registers for the time and date are where? If I don’t have internet I still would like to re-load the real time clock and let it RTC still run my timing. This would be useful as BT and WIFI don’t work together so far. I went to Expressif Tech docs nothing on RTC.
Phil
I am using the following with my esp32 solar powered weather station to get the UTC time once a week and reset my RTC with it:
#define NTP_SERVER_POOL “pool.ntp.org” // NTP pool
…
const char* ntpServer = NTP_SERVER_POOL;
struct tm timeinfo;
…
bool SetTimeFromNTPServer() {
bool ReturnValue = false;
configTime(0, 0, ntpServer); // get the UTC time from an internet ntp server (try 2)
if (getLocalTime(&timeinfo)) {
if (DEBUG_ENABLED) {
Serial.println("Setting time from NTP server");
Serial.print("NTP UTC server time: ");
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}
int y = timeinfo.tm_year + 1900;
int mo = timeinfo.tm_mon + 1;
int d = timeinfo.tm_mday;
int h = timeinfo.tm_hour;
int m = timeinfo.tm_min;
int s = timeinfo.tm_sec;
setTime(h, m, s, d, mo, y);
ReturnValue = (rtc.set(now()) == 0);
};
if (DEBUG_ENABLED)
if (ReturnValue)
Serial.println(“RTC set from NTP server”);
else
Serial.println(“Failed to set RTC from NTP server”);
return ReturnValue;
}
Which works sometimes but not always, for some reason it sometimes sets the time but the time is off by several minutes (like between 5 and 15).
Any ideas on what I may be doing wrong?
I see this too. Immediately after initialisation the time is a few minutes out but then corrects itself:
This is from info logged to ESP32 flash. Each log entry has a time stamp, but before NTP is working the time stamp is all question marks:
????-??-?? ??:??:?? File:”Main.cpp” Line:73 INF: Initialising
????-??-?? ??:??:?? File:”MyEeprom.cpp” Line:37 DBG: EEPROM signature correct 0xface0ff0
????-??-?? ??:??:?? File:”Mywifi.cpp” Line:14 DBG: Connecting
????-??-?? ??:??:?? File:”Mywifi.cpp” Line:26 DBG: WiFi connected.
????-??-?? ??:??:?? File:”Mywifi.cpp” Line:27 INF: IP address: 192.168.0.72
????-??-?? ??:??:?? File:”Mywifi.cpp” Line:28 INF: Mac address: 24:6F:28:79:DC:74
????-??-?? ??:??:?? File:”Main.cpp” Line:95 DBG: Calling ntp.init()
2021-08-25 17:13:35 File:”Main.cpp” Line:97 DBG: Returned from ntp.init()
2021-08-25 17:04:59 File:”Main.cpp” Line:143 DBG: Exiting setup()
I forgot to say that the last line shows the correct time and the time between the calls in the next to last / last line is probably less than 1 second. Maybe on return from ntp.init() some background code has not completely finished filling out the time structures.
Thank you for the good tutorial. I successfully applied it as a part to update the date and time to an Arduino script for an Arduino Nano RP2040 Connect that I have connected to a DS3231 RTC. Btw: I also live in Portugal (Lisboa).
That’s great!
We are from Porto.
Regards,
Sara
Very strange. At first it worked, then I made a non-blocking version, which also works, but now this code (in setup) doesn’t work anymore while my non-blocking code does (in loop, every 10 sec). There is no difference in operations, except the non-blocking code keeps the loop alive. WiFi connects, but no time is fetched.
I always got the “Failed to obtain time”
Using esp32 wrover with onboard SIM800L.
using 2/3 G network.
Hi.
Does it connect to the internet successfully?
Regards,
Sara
Yup, I got connected to the internet using the SIM800. Just found out that NTP time sync cannot be used if using GPRS. Now I am trying to connect to the internet using wifi, the compiler say ” wifi.h : no such file or directory”.
That’s weird.
Do you have an ESP32 board selected when compiling the codE?
Regards,
Sara
Hello,
the example requires a predefined ntp-server, i.e.
const char* ntpServer = “pool.ntp.org”;
or at least const char* ntpServer = “192.168.0.1”;
I wonder if there is a way to use the ntpserver address provided by the local dhcp server (dhcp option 42).
This could make my life much easier, since internet access is blocked for port 123 by a firewall, and the address of the local ntp changes from time to time.
(admins comment: that’s why you should use dhcp)
Henning
How do I calculate the time difference in seconds between 2 events?
I’m running ESP32 Huzzah , and ntpServer to get the time.
Thanks.
Do you want to use times obtained from NTP or would you be ok using e.g. millis() to get time of 1st event and then using mills() when 2nd event happens?
It’s very easy to get difference in seconds between two events using the values obtained from millis(). For example:
// 1st event happens
unsigned long millis_1st_event = millis()
…
// 2nd event happens
unsigned long millis_2nd_event = millis();
// You can obtain time diff in secs by
unsigned long time_diff secs = (millis_2nd_event – millis 1st event) / 1000;
If you want to find the difference between two times obtained from NTP then I don’t immediately know how to do that. I’d have to google.
I missed out the second underscore in time_diff_secs
One more caveat, using millis as described is good for time differences up to 49.7 days. If you want to get a difference between two times further apart than that then the code I suggested won’t work
Thanks, David. How stupid of me. I should have known to do it with the millis function. I was deep in working with the NTP Time and tottaly fogot about millis. Thanks again.
“%A, %B %d %Y %H:%M:%S”
Do i can add millisecond in there ?
or there’s any possible way to add millisecond or microsecond ? Thank you so much.
would be great if you could include code for handling time functions if NTP fails
Hi Rui,
I’m using your NTP program and trying to display the hour, minutes and seconds to a 6-digit, seven segment display. My question is, how can I convert the %H, %M, %S to integer values? Can you write me a simple code to convert char to integer values?
I look forward to your reply.
Thanks!
I’m not Rui, but I think this will do what you want
https://www.educative.io/edpresso/how-to-convert-a-string-to-an-integer-in-c
On that page there is working code which you can actually run.
You can even edit the example code and see what the edited code outputs when you run it.
Hi Dave,
Thanks for your comment / suggestion. I finally figured it out: I used the tm structure documentation to get the time (hr, min, sec), which were already type integer.
However, you did gave me a new lesson to learn!
Best Regards,
Alberto F
I think I’m having the same issue, I’m really struggling to convert the time into a string that I can use as a filename for photographs taken by the esp32-cam, can anyone give me any pointers?
Hi.
You can use something like this:
struct tm timeinfo;
char now[20];
getLocalTime(&timeinfo);
strftime(now,20,"%Y%m%d_%H%M%S",&timeinfo);
// Path where new picture will be saved in SD Card or other filesystem
String path = "/picture" + String(now) +".jpg";
Serial.printf("Picture file name: %s\n", path.c_str());
I hope this helps.
Regards,
Sara
That works! Brilliant, I’d been trying to figure it out for a few days now but I’d not come across strftime() before. Thank you so much!
Hi All,
Setting the Scene – If I have a ESP32 and it is set as an Access Point, then my phone connects to the ESP32 and displays a basic web page served by the ESP32. So basically the ESP32 Web server knows there has been an external connection.
Can I now initiate a NTP server request to the internet via phone the phone connection?
Idea being to automatically set the RTC either within the ESP32 or an external I2C RTC device.
Thanks,
Neil.
Hi.
The ESP32 needs to be able to connect to the internet to get time from NTP.
If it is set as an access point, it is not connected to the internet. So, you can’t request the time.
Regards,
Sara
great .
how can we request for temperature and humidity from an NTP server
You can’t. NTP only provides information about time/date
For weather data, you can use OpenWeatherMap, for example: https://randomnerdtutorials.com/esp32-http-get-open-weather-map-thingspeak-arduino/
Hi,
i m a hobbist so sorry for my silly questions:
1) does it often ask to NTP server the time?
2) if it doesnt, how can it work offline?
3) in other examples i ve seen
#define MYTZ “CET-1CEST,M3.5.0,M10.5.0/3”
and
configTzTime(MYTZ, “time.google.com”, “time.windows.com”, “pool.ntp.org”);
and later
time_t now = time(nullptr);
struct tm t = *localtime(&now);
what’s the difference between configTzTime and configTime?
configTime specifies time offset and daylight offset in seconds.
configTzTime uses TZ notation instead.
Apart of that both are equivalent
Good evening team,
how can i realise a project like:
humidity and temperature with RTC/NTP wireless emitter and transmitter.
Thank you.
Great, so how about obtaining date/time from an HTML client?
If you are writing the html client code you can get the date/time of the client e.g:
– var now = new Date();
Then you have to send it to the web server, maybe you could do it by encoding the information in a get request, or you could send it using a web socket.
I forgot to say “var now = new Date();” is Java Script.
Hi, thanks for the sketch. I’m trying it with a D1 mini. Getting: ‘getLocalTime’ was not declared in this scope; did you mean ‘printLocalTime’?
Am I doing something wrong?
Paul
Hi.
For ESP8266 boards, follow this tutorial instead:
https://randomnerdtutorials.com/esp8266-nodemcu-date-time-ntp-client-server-arduino/
Regards,
Sara
Hi Sara, congratulations for your work, it is an inexhaustible source of suggestions.
I was trying your https://randomnerdtutorials.com/esp32-date-time-ntp-client-server-arduino/ but it didn’t work properly, so I modified the printLocalTime() and setup() functions slightly.
But in the end I discovered that there would be no problem if the WiFi connection happened in the usual network, while I use the GUEST network which creates a delay and a failure of the first read getLocalTime(&timeinfo)
Good work
#include <WiFi.h>
#include “time.h”
const char * ssid = “Guest”;
const char * password = “@@@@@@@@”;
const char * ntpServer = “pool.ntp.org”;
const long gmtOffset_sec = 3600;
const int daylightOffset_sec = 3600;
bool printLocalTime(){
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println(“Failed to obtain time”);
return false;
}
Serial.println(&timeinfo, “%A, %B %d %Y %H:%M:%S”);
return true;
}
void setup(){
Serial.begin(115200);
// Connect to Wi-Fi
Serial.print(“Connecting to “);
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(“.”);
}
Serial.println(“”);
Serial.println(“WiFi connected. “);
Serial.println(WiFi.localIP());
Serial.println(WiFi.gatewayIP());
Serial.println(WiFi.SSID());
Serial.println(WiFi.macAddress());
// Init and get the time
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
while (!printLocalTime()) {
delay(500);
}
//disconnect WiFi as it’s no longer needed
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
}
void loop(){
delay(1000);
printLocalTime();
}
Hi.
You may also consider taking a look at this project to have the time always synchronized including daylight saving time: https://randomnerdtutorials.com/esp32-ntp-timezones-daylight-saving/
Regards,
Sara
Hi,
After having problems with NTPClient.h, I want to use this sketch to capture the current time.
In my sketch I use in numerous places the string variable ‘formattedDate’ (and substrings) supplied by NTPClient.
Now, I don’t want to change all the places in the code that rely on ‘formattedDate’, but rather convert the contents of ‘&timeinfo’ to the string variable ‘formattedDate’ and then process it as before.
I am not experienced enough on how this can be done. Maybe someone can help me with this.
Hy,
Learning by doing!
Through much trial and error, I found the solution, which is more than simple.
char zw_wert[24];
Sting formmattedDate = “”;
strftime(zw_value,24,”%Y-%m-%dT%H:%M:%SZ”, &timeinfo) ;
formattedDate = zw_wert;
Serial.println(formattedDate);
The result = “2023-08-21T20:42:10Z”
Thank you for your attention
Thanks for sharing the solution.
Regards,
Sara
good job.
do you have solution to convert the month into number, like ‘January’ = 1 ?
Thanks
Adam
Hello,
I tried the example and it works well on ESP32 WROOM 32 but by forcing a static IP address when opening the Internet connection, the connection is well established but access to the ntp server no longer works and I constantly get the message “Failed to obtain time”.
Does anyone have a solution to this problem? I absolutely need a static IP address.
…
WiFi.config(ip, dns, gateway, subnet); // To set a static IP address
WiFi.begin(ssid, password);
…
In setup, these last three lines lines don’t make sense to me:
//disconnect WiFi as it’s no longer needed
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
The ESP32 is still connected to the internet via wifi. How can it be turned off?
Hello Sara.
I like your sketch for the offline time update (main reason). I have a Wemos R1 D32 (with ESP32-WROOM-32) and on top I have a by myself modified W5100 Ethernetshield with SD working (original for Arduino). With Wifi from the ESP32 is it working great but not with the W5100 via cable. Then I get the error “Failed to obtain time”. I assume that “Wifi.h” does the job. But I use “Ethernet.h” instead ofcourse. Proberly I should add some more Ethernet libraries.
So what is the suggestion to get the ESP32 working with a W5100 shield?
Or back using the NTP-version with a timed update?
Have already figured out. Just using the NTP-version and the ESP32time.h library. Directly calculate epoch time to normal time and set the RTC. This is in a void doing every hour a callback for keeping accuracy. Readout the RTC is every second (with millis as delay) on Core1. This is because requesting epoch can take several seconds. Stripped the libraries only to what is necessary to save more memory.
Great.
I’m glad you figured out the issue.
Regards,
Sara
Hi All
Have some experience with Arduino – but new to ESP range.
Having read (lots!) about NTP on the ESP8266 and ESP32 I have a question…
In the 8266 the time lib syncs every 60 mins – unless set differently.
“Another standard value is the NTP polling interval. The default value is 60 minutes. This value can also be changed. You can find an example in the original sketch using the function sntp_update_delay_MS_rfc_not_less_than_15000. You have to return the polling interval in milliseconds:”
You can also set a callback – to show when the time has re syncd.
I’ve tried using this on the ESP32 – but it doesnt work!
Does the time lib not sync automatically on the ESP32?
I think it must sync automatically on the ESP32. I have a couple of always on ESP32 controlled devices in the house. I get the time from NTP in setup()
configTime(0, 0, ntpServer); // Can use 0,0 because using TZ below now
setenv(“TZ”,”GMTGMT-1,M3.4.0/01,M10.4.0/02″,1); // London
tzset();
Then they run for ever without any explicit calls from my code to sync with NTP. My code only calls NTP to get the time.
getLocalTime(&timeinfo)
Their time is always within a second if I check them against an atomic clock web page. I still haven’t worked out how to get the time to change when we change from GMT (no daylight saving) to BST (+1 hour). Both devices are permanently +1. That doesn’t bother me enough to spend more time on working out how to get it to work. Even if I had a good idea about how to fix it, I’d have to set up a local NTP server that I could use to switch daylight saving on and off to test it.
Thanks Dave.
Googling a bit more I found this…
werner.rothschopf.net/microcontroller/202103_arduino_esp32_ntp_en.htm
It shows you how to set a ‘callback’ function which tells you when the ESP has syncd to NTP.
Ref your problem with GMT / BST try replacing your line in setenv(..) following GMT with GMT0BST,M3.5.0/1,M10.5.0.
Look here…. github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
Andy
Hi Andy,
Thanks for the info. I might try it sometime. I’ve not had to touch the code in the devices using NTP for over a year. If I need to modify them for some other reason I may include the suggested change to cater for daylight saving.
Hi Sara,
you say: if you want to save the hour into a variable called timeHour, use this code
char timeWeekDay[10];
strftime(timeWeekDay,10, “%A”, &timeinfo);
Serial.println(timeWeekDay);
Serial.println();
but where put this code because I get only errors i.e redeclaration of ‘char timeWeekDay [10]’,
but there are not any declaration before
Thanks
Renzo
Is there a way to manually set the date as a backup when not connected to the internet?
Hello
I have uploaded, on may occasions, the sketch for your “ESP332_time_date_ntp” project, and have it running now with some mods for ttemp & humidity. However today I tried to verify the code and it gives me the following error:
invalid conversion from ‘const char‘ to ‘char‘ [-fpermissive]
It has also highlighted line 52 “WiFi.begin(ssid,password);.
I have this line in other wifi connection sketches which verify fine, and are identical.
Any ideas please?
Thanks and regards, Bryan
I would appreciate being able to run your code on a WeMos D1 that I found in my workshop. What alterations would you suggest?
Hi.
We have a similar tutorial for ESP8266: https://randomnerdtutorials.com/esp8266-nodemcu-date-time-ntp-client-server-arduino/
Regards,
Sara