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

In this tutorial you’ll learn how to get date and time from an NTP server using the ESP8266 NodeMCU with Arduino IDE. Getting date and time is useful in data logging projects to timestamp readings. To get time from an NTP Server, the ESP8266 needs to have an Internet connection and you don’t need additional hardware (like an RTC clock).

ESP8266 NodeMCU NTP Client-Server: Get Date and Time Arduino IDE

Before proceeding make sure you have the ESP8266 board installed in Arduino IDE:

Recommended: Get Date and Time with ESP32 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 ESP8266 is an NTP Client that requests time from an NTP Server (pool.ntp.org).

NTP Network Time Protocol ESP8266 NodeMCU Request time and date

Installing the NTPClient Library

We’ll use the NTPClient library to get time. In your Arduino IDE, go to Sketch > Library > Manage Libraries. The Library Manager should open.

Search for NTPClient and install the library by Fabrice Weinber as shown in the following image.

Install NTPClient Library ESP8266 NodeMCU

NTPClient Library Time Functions

The NTPClient Library comes with the following functions to return time:

getDay() – returns an int number that corresponds to the the week day (0 to 6) starting on Sunday;

getHours() – returns an int number with the current hour (0 to 23) in 24 hour format;

getMinutes() – returns an int number with the current minutes (0 to 59);

getSeconds() – returns an int number with the current second;

getEpochTime() – returns an unsigned long with the epoch time (number of seconds that have elapsed since January 1, 1970 (midnight GMT);

getFormattedTime() – returns a String with the time formatted like HH:MM:SS;

This library doesn’t come with functions to return the date, but we’ll show you in the code how to get the date (day, month and year).

ESP8266 NodeMCU Code

The following code connects the ESP8266 to an NTP Server (pool.ntp.org) to request date and time. It displays the current date and time in several formats in the Serial Monitor.

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp8266-nodemcu-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 <ESP8266WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>

// Replace with your network credentials
const char *ssid     = "REPLACE_WITH_YOUR_SSID";
const char *password = "REPLACE_WITH_YOUR_PASSWORD";

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");

//Week Days
String weekDays[7]={"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

//Month names
String months[12]={"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};

void setup() {
  // Initialize Serial Monitor
  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(".");
  }

// Initialize a NTPClient to get time
  timeClient.begin();
  // Set offset time in seconds to adjust for your timezone, for example:
  // GMT +1 = 3600
  // GMT +8 = 28800
  // GMT -1 = -3600
  // GMT 0 = 0
  timeClient.setTimeOffset(0);
}

void loop() {
  timeClient.update();

  unsigned long epochTime = timeClient.getEpochTime();
  Serial.print("Epoch Time: ");
  Serial.println(epochTime);
  
  String formattedTime = timeClient.getFormattedTime();
  Serial.print("Formatted Time: ");
  Serial.println(formattedTime);  

  int currentHour = timeClient.getHours();
  Serial.print("Hour: ");
  Serial.println(currentHour);  

  int currentMinute = timeClient.getMinutes();
  Serial.print("Minutes: ");
  Serial.println(currentMinute); 
   
  int currentSecond = timeClient.getSeconds();
  Serial.print("Seconds: ");
  Serial.println(currentSecond);  

  String weekDay = weekDays[timeClient.getDay()];
  Serial.print("Week Day: ");
  Serial.println(weekDay);    

  //Get a time structure
  struct tm *ptm = gmtime ((time_t *)&epochTime); 

  int monthDay = ptm->tm_mday;
  Serial.print("Month day: ");
  Serial.println(monthDay);

  int currentMonth = ptm->tm_mon+1;
  Serial.print("Month: ");
  Serial.println(currentMonth);

  String currentMonthName = months[currentMonth-1];
  Serial.print("Month name: ");
  Serial.println(currentMonthName);

  int currentYear = ptm->tm_year+1900;
  Serial.print("Year: ");
  Serial.println(currentYear);

  //Print complete date:
  String currentDate = String(currentYear) + "-" + String(currentMonth) + "-" + String(monthDay);
  Serial.print("Current date: ");
  Serial.println(currentDate);

  Serial.println("");

  delay(2000);
}

View raw code

How the Code Works

First, include the necessary libraries.

#include <ESP8266WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>

Insert your network credentials in the following variables so that the ESP8266 can connect to your router to have access to the internet to request date and time from the NTP server.

const char *ssid     = "REPLACE_WITH_YOUR_SSID";
const char *password = "REPLACE_WITH_YOUR_PASSWORD";

Define an NTP client to get date and time.

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");

We’ll request the time from pool.ntp.org, which is a cluster of times servers that anyone can use to request the time.

Next, we create two arrays to hold the days of the week and the month names.

//Week Days
String weekDays[7]={"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

//Month names
String months[12]={"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};

setup()

In the setup(), initialize the Serial Monitor to display the information.

Serial.begin(115200);

Next, connect the ESP8266 to the internet.

// Connect to Wi-Fi
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print(".");
}

Initialize the NTPClient.

timeClient.begin();

Set Timezone

You can use the setTimeOffset() method to adjust the time for your timezone in milliseconds.

timeClient.setTimeOffset(3600);

Here are some examples for different timezones:

  • GMT +1 = 3600
  • GMT +8 = 28800
  • GMT -1 = -3600
  • GMT 0 = 0

We live in Portugal, so we don’t need to adjust the time.

timeClient.setTimeOffset(0);

loop()

In the loop(), call the update() function to get the current date and time from the NTP server.

timeClient.update();

Get Time

Then, we can use the functions provided by the library to get time. For example, to get the epoch time:

unsigned long epochTime = timeClient.getEpochTime();
Serial.print("Epoch Time: ");
Serial.println(epochTime);

The getFormattedTime() function returns the time in HH:MM:SS format.

String formattedTime = timeClient.getFormattedTime();
Serial.print("Formatted Time: ");
Serial.println(formattedTime);  

You can get the hours, minutes or seconds separately using the getHours(), getMinutes() and getSeconds() functions as follows:

int currentHour = timeClient.getHours();
Serial.print("Hour: ");
Serial.println(currentHour);  

int currentMinute = timeClient.getMinutes();
Serial.print("Minutes: ");
Serial.println(currentMinute); 
   
int currentSecond = timeClient.getSeconds();
Serial.print("Seconds: ");
Serial.println(currentSecond);  

Get Date

The getDay() function returns a number from 0 to 6, in which 0 corresponds to Sunday and 6 to Saturday. So, we can access the week day name from the array we’ve created previously as follows

String weekDay = weekDays[timeClient.getDay()];
Serial.print("Week Day: ");
Serial.println(weekDay);  

The NTP Client doesn’t come with functions to get the date. So, we need to create a time structure (struct tm) and then, access its elements to get information about the date.

struct tm *ptm = gmtime ((time_t *)&epochTime);

The time structure contains the following elements:

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

The following lines get the day of the month as follows:

int monthDay = ptm->tm_mday;
Serial.print("Month day: ");
Serial.println(monthDay);

To get the other elements, you use a similar approach. For example, for the month:

int currentMonth = ptm->tm_mon+1;
Serial.print("Month: ");
Serial.println(currentMonth);

Because the tm_mday starts at 0, we add 1 to the month so that January corresponds to 1, February to 2, and so on.

Then, we can get the name of the month using the months array we’ve created previously. The arrays numbering starts at 0, that’s why we subtract 1.

String currentMonthName = months[currentMonth-1];
Serial.print("Month name: ");
Serial.println(currentMonthName);

To get the year, we need to add 1900 because the tm_year saves the number of years after 1900.

int currentYear = ptm->tm_year+1900;
Serial.print("Year: ");
Serial.println(currentYear);

Finally, we create a String called currentDate that holds the current date in the YYYY-MM-DD format.

 String currentDate = String(currentYear) + "-" + String(currentMonth) + "-" + String(monthDay);
 Serial.print("Current date: ");
 Serial.println(currentDate);

Demonstration

After inserting your network credentials and modifying the variables to adjust the time to your timezone, test the example.

Upload the code your ESP8266 board. Make sure you have the right board and COM port selected.

Open the Serial Monitor at a baud rate of 115200. The date and time should be displayed in several formats as shown below.

ESP8266 NodeMCU 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 ESP8266. This is specially useful for data logging projects that have access to the internet.

If you don’t have access to the internet, you can use an RTC module like the DS1307.

If you want to learn more about the ESP8266, 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!

13 thoughts on “ESP8266 NodeMCU NTP Client-Server: Get Date and Time (Arduino IDE)”

  1. Thanks for your project. Because of the summer time next week, I was experimenting and searching for this kind of solution. Do you have an suggestion for switch between normal and summertime?
    Thanks in advantage.
    PS. Timezone Amsterdam

    Reply
      • Hi Rui,

        Thanks for your response and sorry I was not clear enough.
        By the way, your books and examples have helped me a lot with getting started with my smart home.

        I believe I have done all what you wrote.
        Downloaded and installed the lib’s.

        But I get this message:
        exit status 1
        freertos/FreeRTOS.h: No such file or directory

        See:
        De volumenaam van station C is OS_W7
        Het volumenummer is FA0D-EFD7

        Map van C:\Users\Jan\Mijn documenten\Arduino\libraries

        01-04-2020 19:37 .
        01-04-2020 19:37 ..
        19-01-2020 15:30 Adafruit_ADXL343
        01-04-2020 17:45 Adafruit_BME280_Library
        19-01-2020 15:30 Adafruit_Circuit_Playground
        03-02-2020 19:43 Adafruit_Unified_Sensor
        18-11-2019 22:01 Arduino_SigFox_for_MKRFox1200
        01-04-2020 19:35 AsyncTCP
        01-04-2020 19:22 async_mqtt_client
        22-12-2019 18:34 DHT_sensor_library
        13-03-2020 09:45 ESP32_Mail_Client
        22-12-2019 15:46 ESPAsyncTCP
        22-12-2019 15:44 ESPAsyncWebServer
        22-03-2020 18:46 EspMQTTClient
        22-03-2020 18:47 MFUthings
        21-03-2020 22:35 NTPClient
        21-03-2020 22:28 NTPClient-master
        22-12-2019 15:50 NTPClient-oud
        17-01-2018 22:52 NTPClient-Patched
        22-03-2020 18:46 PubSubClient
        18-08-2019 22:16 108 readme.txt
        18-11-2019 22:01 SD
        22-12-2019 15:50 Servo
        22-12-2019 15:50 SpacebrewYun
        1 bestand(en) 108 bytes
        23 map(pen) 2.921.226.240 bytes beschikbaar

        Reply
      • Hi Sara and Rui,

        Sorry, reaction before was a reaction on ESP32 with BME280.

        Correct reaction is; I fixed Summertime with testing for weeknumber , sunday and the time.

        Reply
  2. Hello,
    nice tutorial.
    I have changed this program a little bit.
    I use an ESP32S NodeMCU and added a OLED and a temperature sensor.

    Regards
    Wolfgang

    Reply
  3. Hi , Great Tutorial. is there a way incorporate the timezone /dst/est into the code ?.
    my programing skills are very good.

    Reply
  4. I’m sure I have read somewhere that you shouldn’t continually call an ntp, and that you should only update a clock at interval?

    Have you a tutorial on using an esp 8266 as a clock running on its own, maybe looking to sync on the hour or every couple of hours?

    I know of RTC chips and milli but is there a Clock library you could point me at that you consider to be a good one for a newbie

    Cheers Clive

    Reply
    • Local clock can be probably done with millis as offset to rt clock.

      If you get the RT, the millis() is an offset to add to the UTC time obtained at the powerup of the module.
      Then update every x seconds.

      But as the wifi is connected, it is far more easy to get the RT every x seconds.

      Reply
  5. Thanks very much !
    Correction:
    “Set Timezone: You can use the setTimeOffset() method to adjust the time for your timezone in milliseconds.

    It is ‘seconds’.

    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.