ESP32 NTP Client-Server: Get Date and Time (Arduino IDE)

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

ESP32 NTP Client-Server Get Date and Time Arduino IDE

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

NTP Network Time Protocol ESP32 Request time and date

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();
}

View raw code

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:

%AFull weekday name
%BFull month name
%dDay of the month
%YYear
%HHour in 24h format
%IHour in 12h format
%MMinute
%SSecond

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.

ESP32 Get Date and Time NTP Client-Server Arduino IDE Serial Monitor demonstration

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.


Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »

Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »


Enjoyed this project? Stay updated by subscribing our weekly newsletter!

33 thoughts on “ESP32 NTP Client-Server: Get Date and Time (Arduino IDE)”

    • 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.

      Reply
    • 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!

      Reply
  1. 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.

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

    Reply
    • 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

      Reply
  3. the code wont compile for me at configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);

    Said configTime ‘was not declared’

    Reply
  4. Hello there!
    How can I store the entire “Serial.println(&timeinfo, “%A, %B %d %Y %H:%M:%S”);” into a single variable?

    Reply
  5. 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.

    Reply
    • 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”);
      // }
      // });

      Reply

Leave a Comment

Download our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.