Arduino ESP32 Synchronize Time and Date using NTP Protocol (Arduino IDE)

In this tutorial I will show you how to synchronize time and date from internet using NTP (Network Time Protocol) Protocol on ESP32.

Let us first understand what is NTP Protocol,


Network Time Protocol (NTP)

Network Time Protocol (NTP) is a protocol that helps hundreds of millions of computer devices to synchronize their clocks over internet. It was developed by David Mills in 1981 at University of Delaware. It uses UDP port 123 for communication.


Benefits of NTP :

> NTP Servers use atomic clocks which are most accurate in the world.

> Uses UTC as its time unit and it detects changes in 1 milliseconds in LAN and in tens of milliseconds in broader network.

> Provides consistent timekeeping for file servers


Prerequisite

You should have installed Arduino IDE with ESP32 add-on in it.


Hardware Used

In this tutorial we are using ESP32-C6 Dev Kit. You can use any ESP32 based board with this code.

ESP32-C3-DevKitC-02 is an entry-level development board based on ESP32-C3-WROOM-02 or ESP32-C3-WROOM-02U, general-purpose modules with 4 MB SPI flash. This board integrates complete Wi-Fi and Bluetooth® Low Energy functions.


Code


/*
  Complete project details at https://ecprojectsforyou.blogspot.com/
  
  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"
#include "sntp.h"

#define CONFIG_TIME_USING_TIMEZONE 1

/* Wi-Fi Credentials */
const char* ssid       = "WRITE_YOUR_WIFI_SSID_HERE";
const char* password   = "WRITE_YOUR_WIFI_PASS_HERE";

/* List of NTP Servers */
const char* ntpServer1 = "pool.ntp.org";
const char* ntpServer2 = "time.nist.gov";

/* Timezone Corrections Variables */
const int   daylightOffset_sec = 0;

/* Timezone for India */
const long  gmtOffset_sec = 19800;
const char* time_zone = "IST-5:30"; 

void setup()
{
  Serial.begin(115200);

  // set notification call-back function
  sntp_set_time_sync_notification_cb( timeavailable );

  /**
   * NTP server address could be aquired via DHCP,
   *
   * NOTE: This call should be made BEFORE esp32 aquires IP address via DHCP,
   * otherwise SNTP option 42 would be rejected by default.
   * NOTE: configTime() function call if made AFTER DHCP-client run
   * will OVERRIDE aquired NTP server address
   */
  sntp_servermode_dhcp(1);    // (optional)

#if CONFIG_TIME_USING_TIMEZONE
  /**
   * A more convenient approach to handle TimeZones with daylightOffset 
   * would be to specify a environmnet variable with TimeZone definition including daylight adjustmnet rules.
   * A list of rules for your zone could be obtained from https://github.com/esp8266/Arduino/blob/master/cores/esp8266/TZ.h
   */
  configTzTime(time_zone, ntpServer1, ntpServer2);
#else
  /**
   * This will set configured ntp servers and constant TimeZone/daylightOffset
   * should be OK if your time zone does not need to adjust daylightOffset twice a year,
   * in such a case time adjustment won't be handled automagicaly.
   */
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2);
#endif

  //connect to WiFi
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }
  Serial.println(" CONNECTED");

}

void loop()
{
  delay(10000);
  printLocalTime();     // it will take some time to sync time :)
}

void printLocalTime()
{
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("No time available (yet)");
    return;
  }
  
  // Print individual members of struct tm
  Serial.printf("Seconds (tm_sec): %d\n", timeinfo.tm_sec);
  Serial.printf("Minutes (tm_min): %d\n", timeinfo.tm_min);
  Serial.printf("Hours (tm_hour): %d\n", timeinfo.tm_hour);
  Serial.printf("Day of Month (tm_mday): %d\n", timeinfo.tm_mday);
  Serial.printf("Month (tm_mon): %d (0=Jan, 11=Dec)\n", timeinfo.tm_mon);
  Serial.printf("Year (tm_year): %d (years since 1900)\n", timeinfo.tm_year);
  Serial.printf("Day of Week (tm_wday): %d (0=Sun, 6=Sat)\n", timeinfo.tm_wday);
  Serial.printf("Day of Year (tm_yday): %d (days since Jan 1)\n", timeinfo.tm_yday);
  Serial.printf("Daylight Saving Time (tm_isdst): %d (-1=unknown, 0=no, 1=yes)\n", timeinfo.tm_isdst);

  // You can also use strftime for a more formatted output
  char buffer[80];
  strftime(buffer, sizeof(buffer), "Current date and time: %Y-%m-%d %H:%M:%S", &timeinfo);
  
  Serial.printf("%s\n\n", buffer);
}

// Callback function (get's called when time adjusts via NTP)
void timeavailable(struct timeval *t)
{
  Serial.println("Got time adjustment from NTP!\n\n");
  printLocalTime();
}


Explanation of Code

In below section I will explain how code works,

First, all required libraries are included.
#include <WiFi.h>
#include "time.h"
#include "sntp.h"

Change below macro value to 0 if you want to change time value manually based on gmtOffset_sec 
variable.
#define CONFIG_TIME_USING_TIMEZONE 1

Modify below variables to match your Wi-Fi Credentials,
/* Wi-Fi Credentials */
const char* ssid       = "WRITE_YOUR_WIFI_SSID_HERE";
const char* password   = "WRITE_YOUR_WIFI_PASS_HERE";

Then, list of NTP Servers are added which will be used when synchronize time,
/* List of NTP Servers */
const char* ntpServer1 = "pool.ntp.org";
const char* ntpServer2 = "time.nist.gov";

The daylightOffset_sec variable is used to define offset in seconds for daylight saving. 
/* Timezone Corrections Variables */
const int   daylightOffset_sec = 0;

The gmtOffset_sec  variable is used when timezone correction is done manually. Add time difference in seconds for your region. The time_zone variable is used when timezone correction is done from library. Mention timezone string for your region. You can find timezone string for your region at here
/* Timezone for India */
const long  gmtOffset_sec = 19800;
const char* time_zone = "IST-5:30";


setup()

Init serial com port with 115200 baud rate,
Serial.begin(115200);

Below set of code sets callback function which will be called when time is synchronized from NTP and enables dhcp mode for NTP server.
// set notification call-back function
sntp_set_time_sync_notification_cb( timeavailable );
/**
* NTP server address could be aquired via DHCP,
*
* NOTE: This call should be made BEFORE esp32 aquires IP address via DHCP,
* otherwise SNTP option 42 would be rejected by default.
* NOTE: configTime() function call if made AFTER DHCP-client run
* will OVERRIDE aquired NTP server address
*/
sntp_servermode_dhcp(1);    // (optional)

To adjust time value for your region below code is used,
#if CONFIG_TIME_USING_TIMEZONE
  /**
   * A more convenient approach to handle TimeZones with daylightOffset 
   * would be to specify a environmnet variable with TimeZone definition including daylight adjustmnet rules.
   * A list of rules for your zone could be obtained from https://github.com/esp8266/Arduino/blob/master/cores/esp8266/TZ.h
   */
  configTzTime(time_zone, ntpServer1, ntpServer2);
#else
  /**
   * This will set configured ntp servers and constant TimeZone/daylightOffset
   * should be OK if your time zone does not need to adjust daylightOffset twice a year,
   * in such a case time adjustment won't be handled automagicaly.
   */
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2);
#endif

Below code connects device to Wi-Fi network using provided Crednetials,
  //connect to WiFi
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }
  Serial.println(" CONNECTED");

printLocalTime function,

This function is used to print current time after synchronizing from NTP server.
void printLocalTime()
{
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("No time available (yet)");
    return;
  }
  // Print individual members of struct tm
  Serial.printf("Seconds (tm_sec): %d\n", timeinfo.tm_sec);
  Serial.printf("Minutes (tm_min): %d\n", timeinfo.tm_min);
  Serial.printf("Hours (tm_hour): %d\n", timeinfo.tm_hour);
  Serial.printf("Day of Month (tm_mday): %d\n", timeinfo.tm_mday);
  Serial.printf("Month (tm_mon): %d (0=Jan, 11=Dec)\n", timeinfo.tm_mon);
  Serial.printf("Year (tm_year): %d (years since 1900)\n", timeinfo.tm_year);
  Serial.printf("Day of Week (tm_wday): %d (0=Sun, 6=Sat)\n", timeinfo.tm_wday);
  Serial.printf("Day of Year (tm_yday): %d (days since Jan 1)\n", timeinfo.tm_yday);
  Serial.printf("Daylight Saving Time (tm_isdst): %d (-1=unknown, 0=no, 1=yes)\n", timeinfo.tm_isdst);

  // You can also use strftime for a more formatted output
  char buffer[80];
  strftime(buffer, sizeof(buffer), "Current date and time: %Y-%m-%d %H:%M:%S", &timeinfo);
  Serial.printf("%s\n\n", buffer);
}


Working of Code

entry 0x403cc710
Connecting to SPiDiGO2 . CONNECTED
Got time adjustment from NTP!
Seconds (tm_sec): 40
Minutes (tm_min): 39
Hours (tm_hour): 18
Day of Month (tm_mday): 23
Month (tm_mon): 10 (0=Jan, 11=Dec)
Year (tm_year): 125 (years since 1900)
Day of Week (tm_wday): 0 (0=Sun, 6=Sat)
Day of Year (tm_yday): 326 (days since Jan 1)
Daylight Saving Time (tm_isdst): 0 (-1=unknown, 0=no, 1=yes)
Current date and time: 2025-11-23 18:39:40
Seconds (tm_sec): 49
Minutes (tm_min): 39
Hours (tm_hour): 18
Day of Month (tm_mday): 23
Month (tm_mon): 10 (0=Jan, 11=Dec)
Year (tm_year): 125 (years since 1900)
Day of Week (tm_wday): 0 (0=Sun, 6=Sat)
Day of Year (tm_yday): 326 (days since Jan 1)
Daylight Saving Time (tm_isdst): 0 (-1=unknown, 0=no, 1=yes)
Current date and time: 2025-11-23 18:39:49
Seconds (tm_sec): 59
Minutes (tm_min): 39
Hours (tm_hour): 18
Day of Month (tm_mday): 23
Month (tm_mon): 10 (0=Jan, 11=Dec)
Year (tm_year): 125 (years since 1900)
Day of Week (tm_wday): 0 (0=Sun, 6=Sat)
Day of Year (tm_yday): 326 (days since Jan 1)
Daylight Saving Time (tm_isdst): 0 (-1=unknown, 0=no, 1=yes)
Current date and time: 2025-11-23 18:39:59


Wrapping Up

In todays tutorial you have learned how to use NTP protocol to synchronize time. NTP protocol can be used with other devices too.

Please leave a comment if you have a question or you found this helpful.

Post a Comment

0 Comments