Time converting - time_t to struct

I'm trying to convert
"2017-12-24T06:11:36"
to
"06:11:36 - 24.12.2017"

I have in a HTML page:

"Last synchronized at: " + String(NTP.getTimeDate(NTP.getLastSync())) + "
"

And "NTP.getTimeDate(NTP.getLastSync())" is showing the time in ISO8601.

I tried:

char buff[20];
time_t lastSync = NTP.getLastSync();
strftime(buff, 20, "%H:%M:%S - %d-%m-%Y ", localtime(&lastSync));

And i know there is something missing like:

struct tm *syncInfo;

But i can't figure it out.

Are you using the standard Arduino time library? Or some other library?

I have not used the standard time library much but NTP strikes me as being from some other library - I don't remember seeing that on the odd occasions I have looked in the Arduino Time library code.

MrGlasspoole:
I tried:

char buff[20];

time_t lastSync = NTP.getLastSync();
strftime(buff, 20, "%H:%M:%S - %d-%m-%Y ", localtime(&lastSync));

Please tell us what happened when you tried that.

localtime() already returns a *tm, you shouldn't need to declare syncInfo.

It is not clear which libraries you are using but I guess you are using this for NTP:

which has a method getTimeDate() defines as

const char *NTPClient::getTimeDate(time_t tm) {
  char *dt = new char[20];
  char buf[20];

  snprintf(buf, sizeof(buf), "%d-%02d-%02dT%02d:%02d:%02d", year(tm), month(tm),
           day(tm), hour(tm), minute(tm), second(tm));
  strcpy(dt, buf);

  return dt;
}

so you can surely hack that to achieve your desired format.
Which timezone library are you using such that localtime() does something meaningful ? Maybe post your entire code.

Ah sorry, yes it is:

He wrote:
getLastSync returns a Time Type (time_t) which can be converted to any format.
You can use the strftime function to do that (you need to convert time_t to struct tm* first).

The error on strftime is:
expected constructor, destructor, or type conversion before '(' token

Oh and merry christmas to all!

Is that your last error in the error listing or your first?

The only

Then post your entire sketch.

It's a first draft:

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPClient.h>
#include <NTPClient.h>
#include <TimeLord.h>

/**************************************************************
* WIFI AND COORDINATES                                        *
**************************************************************/
const char *WIFI_SSID = "xxxxxxxxxx"; //  WiFi SSID
const char *WIFI_PSK = "xxxxxxxx";  // WiFi PSK

long const LONGITUDE = x.xxxxxxx;
long const LATITUDE = xx.xxxxx;

/**************************************************************
* MISC SETUP                                                  *
**************************************************************/
#define DEBUG 1                       // Set to 1 for serial port output
const uint32_t SERIAL_BAUD = 115200;  // Set serial speed

const uint8_t lightOn = 5;            // Relay A2 is connected to D1/GPIO5
const uint8_t lightOff = 4;           // Relay A1 is connected to D2/GPIO4
const uint8_t noWifi = 14;            // Red LED (no WiFi) is connected to D5/GPIO14
const uint8_t noSync = 12;            // Green LED (no time sync) is connected to D6/GPIO12
const uint8_t lightSensor = 13;       // Phototransistor circuit is connected to D7/GPIO13

uint8_t lightOnHour;
uint8_t lightOnMinute;
uint8_t lightOffHour;
uint8_t lightOffMinute;

const int8_t offSetOn = 0;
const int8_t offSetOff = 0;

uint8_t lightState = 0;               // Variable for light sensor
boolean isLightOn = false;            // Current state of Light

ESP8266WebServer webServer(80);

/**************************************************************
* WEBPAGE                                                     *
**************************************************************/

const String HTTP_HEAD_EXPIRE = "<meta http - equiv = \"cache-control\" content=\"max-age=0\" /><meta http-equiv=\"cache-control\" content=\"no-cache\" /><meta http-equiv=\"expires\" content=\"0\" /><meta http-equiv=\"expires\" content=\"Tue, 01 Jan 1980 1:00:00 GMT\" /><meta http-equiv=\"pragma\" content=\"no-cache\" />";
const String HTTP_HEAD = "<!DOCTYPE html><html lang=\"en\"><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/>" + HTTP_HEAD_EXPIRE + "<title>Astronomical Staircase Light</title>";
const String HTTP_STYLE = "<style>div,input{padding:5px;font-size:1em;} input{width:95%;} body{text-align: center;} button{border:0;border-radius:0.3rem;background-color:#1fa3ec;color:#fff;line-height:2.4rem;font-size:1.2rem;width:100%;} input[type=\"submit\"]{border:0;border-radius:0.3rem;background-color:#1fa3ec;color:#fff;line-height:2.4rem;font-size:1.2rem;width:100%;}</style>";
const String HTTP_HEAD_END = "</head><body><div style='font-family: verdana; text-align: left; display: inline-block;'><h1>Astronomical Staircase Light</h1>";
const String HTTP_END = "</div></body></html>";
const String HTTP_BEGIN = HTTP_HEAD + HTTP_STYLE + HTTP_HEAD_END;





// Event Handler when an IP address has been assigned
// Once connected to WiFi, start the NTP Client
void onSTAGotIP(WiFiEventStationModeGotIP event) {
  #ifdef DEBUG
    Serial.printf("Got IP: %s\n", event.ip.toString().c_str());
  #endif // END DEBUG
  NTP.init((char *)"10.1.0.2", UTC0100);
  NTP.setPollingInterval(43200); // Poll every 12H
}

// Event Handler when WiFi is disconnected
void onSTADisconnected(WiFiEventStationModeDisconnected event) {
  #ifdef DEBUG
    Serial.printf("WiFi connection (%s) dropped.\n", event.ssid.c_str());
    Serial.printf("Reason: %d\n", event.reason);
  #endif // END DEBUG
}

void setup() {

  pinMode(lightOn, OUTPUT);    // Set Relay pin (D1/GPIO5) as output
  digitalWrite(lightOn, LOW);  // Set Relay to off

  pinMode(lightOff, OUTPUT);   // Set Relay pin (D2/GPIO4) as output
  digitalWrite(lightOff, LOW); // Set Relay to off

  pinMode(noWifi, OUTPUT);     // Set no WiFi LED pin (D5/GPIO14) as output
  digitalWrite(noWifi, LOW);   // Set no WiFi LED to off

  pinMode(noSync, OUTPUT);     // Set no time sync LED pin (D6/GPIO12) as output
  digitalWrite(noSync, LOW);   // Set no time sync LED to off

  pinMode(lightSensor, INPUT); // Set light sensor pin (D7/GPIO13) as input

  static WiFiEventHandler gotIpEventHandler, disconnectedEventHandler;

  #ifdef DEBUG
    Serial.begin(SERIAL_BAUD); // Initialize serial communications
    while (!Serial) {;}        // Wait for serial port to connect
  #endif // END DEBUG

  NTP.onSyncEvent([](NTPSyncEvent_t ntpEvent) {
    switch (ntpEvent) {
    case NTP_EVENT_INIT:
      break;
    case NTP_EVENT_STOP:
      break;
    case NTP_EVENT_NO_RESPONSE:
      Serial.printf("NTP server not reachable.\n");
      break;
    case NTP_EVENT_SYNCHRONIZED:
      Serial.printf("Got NTP time: %s\n", NTP.getTimeDate(NTP.getLastSync()));
      break;
    }
  });

  gotIpEventHandler = WiFi.onStationModeGotIP(onSTAGotIP);
  disconnectedEventHandler = WiFi.onStationModeDisconnected(onSTADisconnected);

  // Connecting to a WiFi network
  #ifdef DEBUG
    Serial.printf("Connecting to WiFi network: %s \n", WIFI_SSID);
  #endif // END DEBUG
  WiFi.begin(WIFI_SSID, WIFI_PSK);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  #ifdef DEBUG
    Serial.print(".");
  #endif // END DEBUG
  }

  TimeLord tardis; 
  tardis.TimeZone(1 * 60); // tell TimeLord what timezone your RTC is synchronized to. You can ignore DST
  // as long as the RTC never changes back and forth between DST and non-DST
  tardis.Position(LATITUDE, LONGITUDE); // tell TimeLord where in the world we are
  
  byte today[] = {  0, 0, 12, 20, 12, 2017    }; // store today's date (at noon) in an array for TimeLord to use

  if (tardis.SunRise(today)) { // if the sun will rise today (it might not, in the [ant]arctic)
    Serial.print("Sunrise: ");
    Serial.print((int) today[tl_hour]);
    Serial.print(":");
    Serial.println((int) today[tl_minute]);
  }
   
  if (tardis.SunSet(today)) { // if the sun will set today (it might not, in the [ant]arctic)
    Serial.print("Sunset: ");
    Serial.print((int) today[tl_hour]);
    Serial.print(":");
    Serial.println((int) today[tl_minute]);
  }
  Serial.println(); 


  // Match the request for the web server
  webServer.onNotFound(mainHTMLPage);
  webServer.on("/", mainHTMLPage);

  webServer.begin(); // Start the web server

}
  
void loop() {
  webServer.handleClient();

  lightState = digitalRead(lightSensor);

  if(lightState == HIGH) {      // If light state is high
    isLightOn = true;           // current state of Light
  } else {                      // If light state is low
    isLightOn = false;          // current state of Light
  }
  
  static int previousMillis = 0;

  // Update time status every 5 seconds
  if ((millis() - previousMillis) > 5000) {
    previousMillis = millis();

    // Output only when time is set
    if (timeStatus() != timeSet) {
      return;
    }
    Serial.printf("Current time: %s - First synchronized at: %s.\n", NTP.getTimeDate(now()), NTP.getTimeDate(NTP.getFirstSync()));
  }
}


char buff[20];
time_t lastSync = NTP.getLastSync();
strftime(buff, 20, "%Y-%m-%d %H:%M:%S", localtime(&lastSync));

void mainHTMLPage() {
  String page = HTTP_BEGIN;

  page += "RSSI: " + String(WiFi.RSSI()) + " dBm
";
  page += "The time is: " + String(hour()) + ":" + String(niceMinuteSecond(minute())) + ":" + String(niceMinuteSecond(second())) + " - " + String(day()) + "." + String(month()) + "." + String(year()) + "
";
  page += "Last synchronized at: " + String(NTP.getTimeDate(NTP.getLastSync())) + "
";
  page += "The light is now: <b>" + (isLightOn ? String("ON") : String("OFF")) + "</b>
";
  //page += "Light on time: " + String(lightOnHour) + ":" + String(niceMinuteSecond(lightOnMinute)) + "
";
  //page += "Light off time: " + String(lightOffHour) + ":" + String(niceMinuteSecond(lightOffMinute)) + "
";

  // bottom of the html page
  page += HTTP_END;
  webServer.send(200, "text/html", page);
}

String niceMinuteSecond(int m) {
  char sz[4];
  sprintf(sz, "%02d", m);
  return String(sz);
}

void turnLightOn() {
  digitalWrite(lightOn, HIGH);
//  Alarm.delay(100);
  digitalWrite(lightOn, LOW);
  isLightOn = true;
  mainHTMLPage();
}

void turnLightOff() {
  digitalWrite(lightOff, HIGH);
//  Alarm.delay(100);
  digitalWrite(lightOff, LOW);
  isLightOn = false;
  mainHTMLPage();
}
time_t lastSync = NTP.getLastSync();
strftime(buff, 20, "%Y-%m-%d %H:%M:%S", localtime(&lastSync));

These lines are not inside any function.

By the way, great demonstration of why we need full source.

TimeLord.h

why are you using this library at all?

You've got the internet, just use a weather API and you can get everything you need including local time, sunrise/set, DST, etc.

Why use the internet for stuff you can do local?
I want my stuff working without the internet.

MrGlasspoole:
Why use the internet for stuff you can do local?
I want my stuff working without the internet.

Yes, like NTP works without internet.

Yes it does work without internet.
You can use another device in your LAN as timeserver.

I use the timelord library and NTP for ESP8266 based “daylight aware” time switches I built. These also have a ds3231 RTC module. For configuration, setting on/off conditions, geo coordinates etc., the devices create their own wlan and are configured via a web browser. For obtaining the current time via NTP they act as clients of the main, internet connected wlan. They can run autonomously once configured so even if, say, the main wlan fails or password is changed etc. these will function for years with good accuracy, respecting dst and sunrise/sunset changes.
I always intended to publish the design after the final tidying up of the code, but that final tidying up never quite happened.