Update: 2020-09-25

ESP8266 NTP Zeitsynchronisation per WLAN mit Automatischer Sommer- und Winterzeit Umstellung.

Bis EspCoreVersion 2.5.2

Esp8266 NTP Lokalzeit als Arduino Tab.

Lokalzeit.ino

// ****************************************************************
// Sketch Esp8266 Lokalzeit Modular(Tab)
// created: Jens Fleischer, 2018-07-10
// last mod: Jens Fleischer, 2020-09-25
// For more information visit: https://fipsok.de
// ****************************************************************
// Hardware: Esp8266
// Software: Esp8266 Arduino Core 2.4.2 - 2.7.4
// Getestet auf: Nodemcu, Wemos D1 Mini Pro, Sonoff Switch, Sonoff Dual
/******************************************************************
  Copyright (c) 2018 Jens Fleischer. All rights reserved.

  This file is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.
  This file is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
*******************************************************************/
// Diese Version von Lokalzeit sollte als Tab eingebunden werden.
// #include <ESP8266WebServer.h> oder #include <ESP8266WiFi.h> muss im Haupttab aufgerufen werden.
// Funktion "setupTime();" muss im setup() nach dem Verbindungsaufbau aufgerufen werden.
/**************************************************************************************/

#include <time.h>
#include <sntp.h>

const uint32_t SYNC_INTERVAL = 24;                             // NTP Sync Interval in Stunden einstellen

struct tm tm;

const char* const PROGMEM NTP_SERVER[] = {"fritz.box", "de.pool.ntp.org", "at.pool.ntp.org", "ch.pool.ntp.org", "ptbtime1.ptb.de", "europe.pool.ntp.org"};
const char* const PROGMEM DAY_NAMES[] = {"Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"};
const char* const PROGMEM DAY_SHORT[] = {"So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"};
const char* const PROGMEM MONTH_NAMES[] = {"Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"};
const char* const PROGMEM MONTH_SHORT[] = {"Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"};

void setNtp(const char* server1, const char* server2 = nullptr, const char* server3 = nullptr);

void setupTime() {
  setNtp(NTP_SERVER[1], NTP_SERVER[2], NTP_SERVER[3]);         // deinen NTP Server einstellen (von 0 - 5 aus obiger Liste)
  server.on("/time", []() {
    server.send(200, "application/json", localTime());
  });
}

void setNtp(const char* server1, const char* server2, const char* server3) {
  sntp_stop();
  sntp_setservername(0, (char*)server1);
  if (server2) sntp_setservername(1, (char*)server2);
  if (server3) sntp_setservername(2, (char*)server3);
  static bool once {0};
  if (!once++) {
    sntp_set_timezone(0);
    setenv("TZ", "CET-1CEST,M3.5.0/02,M10.5.0/03", 1);         // Zeitzone einstellen https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
  }
  sntp_init();
}

String localTime() {
  static char buf[26];                                         // je nach Format von "strftime" eventuell anpassen
  static time_t lastsec = 0;
  time_t now = time(&now);
  localtime_r(&now, &tm);
  if (tm.tm_sec != lastsec) {
    lastsec = tm.tm_sec;
    strftime (buf, sizeof(buf), R"(["%T","%d.%m.%Y"])", &tm);  // http://www.cplusplus.com/reference/ctime/strftime/
    if (!(time(&now) % (SYNC_INTERVAL * 3600))) {
      setupTime();
    }
  }
  return buf;
}

Die Webseite zur Esp8266 Uhrzeit.

zeit.html

<!DOCTYPE HTML> <!-- For more information visit: https://fipsok.de -->
<html lang="de">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title>Uhrzeit</title>
    <script>
      function renew() {
        fetch('/time').then(function (response) {
          return response.json();
        }).then(function (array) {
          document.querySelector('span').innerHTML = array[0];;
        });
      }
      document.addEventListener('DOMContentLoaded', renew, setInterval(renew, 1000));
    </script>
    <style>
      body {
        padding: 10px;
        font-size: 3.2em;
      }
      main {
		display: flex;
        flex-direction: column;
        align-items: center;
        background-color: black;
        width: 280px;
        height: 100px;
        padding: .2em;
        border: .15em solid #aeaeab;
        box-shadow: 5px 10px 5px rgba(0, 0, 0, 0.7);
        border-radius: .2em;
      }
      span {
        color: #02fc07;
        position: relative;
        top: .5em;
        left: .1em;
        letter-spacing: .1em;
        font-weight: bold
      }
    </style>
  </head>
  <body>
    <main>
      <span></span>
    </main>
  </body>
</html>

Die "struct tm" enthält die Kalenderzeit.
Wenn du in deinem gesamten Sketch auf die Komponenten der Struktur zugreifen willst, verschiebe das includieren der "time.h" und deklarieren der "struct tm" vom Lokalzeit Tab in den Webserver Tab.

Der Aufruf der Funktion "localTime();" ist nach ausführen von "setupTime();" möglich.

Beispiel:

************** Zeitstempel im Setup ******************

void setup() {
 ......
 .........
  setupTime();
  Serial.println("Programmstart: " + localTime());
 ......
}

Du kannst den Aufruf der "localTime();" als Zeitstempel nutzen.

Beispiel:

******* Push Nachricht mit Text und Zeitstempel ******

pushbullet("Füllstand Minimum " + localTime());
Beispiel:

*************** Zeitstempel im Loop ******************

void loop() {
 ......
 .........
  static unsigned long letzteMillis = 0;
  unsigned long aktuelleMillis = millis();
  if (aktuelleMillis - letzteMillis >= 1000) {
    Serial.println(localTime());
    letzteMillis = aktuelleMillis;
  }
 ......
}
Beispiel:

************* Logdatei mit Zeitstempel ***************

File f = SPIFFS.open("/logdatei.txt", "a");
if (f && freeSpace(100)) {      // Anpassen an die zu schreibende Anzahl Byte
  f.printf("%s Event ausgelöst\n", localTime().c_str());
}
f.close();

Die Webseite zur Esp8266 Uhrzeit mit Datum.

zeitdatum.html

<!DOCTYPE HTML> <!-- For more information visit: https://fipsok.de -->
<html lang="de">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title>Uhrzeit</title>
    <script>
      function renew() {
        fetch('/time').then(response => {
          return response.json();
        }).then(array => {
		  document.querySelector('#time').innerHTML = array[0];
          document.querySelector('#date').innerHTML = array[1];
        });
      }
      document.addEventListener('DOMContentLoaded', renew, setInterval(renew, 1000));
    </script>
    <style>
      body {
        padding: 10px;
        font-size: 3.2em;
      }
      main {
		display: flex;
        flex-direction: column;
        align-items: center;
        background-color: black;
        width: 280px;
        height: 140px;
        padding: .2em;
        border: .15em solid #aeaeab;
        box-shadow: 5px 10px 5px rgba(0, 0, 0, 0.7);
        border-radius: .2em;
      }
      span {
        color: #00ff05;
        position: relative;
        top: .3em;
        left: .1em;
        letter-spacing: .1em;
        font-weight: bold
      }
	  #date {
        font-size: .7em;
        margin-top: .5em;
      }
    </style>
  </head>
  <body>
    <main>
      <span id="time"></span>
      <span id="date"></span>
    </main>
  </body>
</html>