Getting name of day from NTP server

In the following code,
the last line is Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
This prints day of week, month of year, day of month, year, hour, minutes, seconds in the Serial Monitor.I know that the individual numbers are stored in a structure - struct tm. But I would need the verbose name of the current day in a char variable. Like for example Monday, Thursday, Sunday...
Is there any function how I could get it from NTP server?

#include <WiFi.h>
#include "time.h"

const char* ssid       = "SSID_NAME";   //Replace with your own SSID
const char* password   = "YOUR_PASSWORD";  //Replace with your own password

const char* NTPServer = "pool.ntp.org";
const long  GMTOffset_sec = 3600;   //Replace with your GMT offset (seconds)
const int   DayLightOffset_sec = 0;  //Replace with your daylight offset (seconds)

void setup()
{
  Serial.begin(115200);
  
  //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 to WIFI");
  
  //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");
}

As you may know, time on computers is based on the number of seconds since Jan 1 1970, UTC: 55 years and about 21 hours ago. That number is what NTP gives you.

From that you have to consider your timezone. An NTP server may know its own timezone, but does not know yours. Once you have the number of seconds, you can calculate the time locally, and therefore what day it is at the moment.

How does Serial.println do it? Once you have successfully compiled your sketch, right-click on println and Go to Definition. That should take you to Print.cpp

size_t Print::println(struct tm *timeinfo, const char *format) {
  size_t n = print(timeinfo, format);
  n += println();
  return n;
}

which simply uses print and then tacks on the line break. Going to print

size_t Print::print(struct tm *timeinfo, const char *format) {
  const char *f = format;
  if (!f) {
    f = "%c";
  }
  char buf[64];
  size_t written = strftime(buf, 64, f, timeinfo);
  if (written == 0) {
    return written;
  }
  return print(buf);
}

There it is: strftime into an arbitrarily-sized array of char

1 Like

To convert to a character string you need to do it yourself. Create an array of the day names and use the day of the week number as an index to get the day string.

1 Like

Untested...

#include <WiFi.h>
#include "time.h"

const char* ssid       = "SSID_NAME";   //Replace with your own SSID
const char* password   = "YOUR_PASSWORD";  //Replace with your own password

const char* NTPServer = "pool.ntp.org";
const long  GMTOffset_sec = 3600;   //Replace with your GMT offset (seconds)
const int   DayLightOffset_sec = 0;  //Replace with your daylight offset (seconds)

void setup()
{
  Serial.begin(115200);
  
  //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 to WIFI");
  
  //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();
}

char *weekday[7] = ("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

void printLocalTime()
{
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("Failed to obtain time");
    return;
  }
  Serial.print("%s, ", weekday[timeinfo.tm_wday]);
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}
1 Like

Doing it manually with your own array of day names will save a good chunk of memory versus using strftime. But if the sketch is already using related code, you've paid that cost already. And maybe your sketch fits with room to spare, so your code will be simpler.

Compare the program storage space used, with and without it:

#include <time.h>
tm t;

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

  Serial.println(t.tm_wday);  // don't "optimize away" the variable
  char buf[16];
  if (strftime(buf, sizeof(buf), "%A", &t)) Serial.println(buf); // try commenting this out
}

void loop() {}
1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.