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
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
#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";
setup()
Serial.begin(115200);// set notification call-back functionsntp_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");printLocalTime function,
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
0 Comments