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 😀
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
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.
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)?