Update: 2021-07-27

ESP8266 NTP Zeitsynchronisation per WLAN.
Alle aktuellen Zeitzonen sind im Webinterface einstellbar.

Esp8266 NTP Weltzeit als Arduino Tab.

Weltzeit.ino

// ****************************************************************
// Sketch Esp8266 Weltzeit Modular(Tab)
// created: Jens Fleischer, 2020-07-09
// last mod: Jens Fleischer, 2020-07-09
// For more information visit: https://fipsok.de
// ****************************************************************
// Hardware: Esp8266
// Software: Esp8266 Arduino Core 2.7.1 - 3.0.2
// Getestet auf: Nodemcu, Wemos D1 Mini Pro
/******************************************************************
  Copyright (c) 2020 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 Weltzeit sollte als Tab eingebunden werden.
// #include <ESP8266WebServer.h> muss im Haupttab aufgerufen werden.
// Funktion "setupTime();" muss im setup() nach dem Verbindungsaufbau aufgerufen werden.
/**************************************************************************************/

#include <time.h>

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"};

void setupTime() {
  static char zone[2][45] = {"356", "CET-1CEST,M3.5.0,M10.5.0/3"};
  configTime(zone[1], NTP_SERVER[1]);                          // deinen NTP Server einstellen (von 0 - 5 aus obiger Liste) alternativ lassen sich durch Komma getrennt bis zu 3 Server angeben
  server.on("/posixTZ", HTTP_POST, [&]() {
    if (server.hasArg("zone")) {
      byte i {0};
      char str[55];
      strcpy (str, server.arg("zone").c_str());
      char* ptr = strtok(str, "[\"");
      while (ptr != NULL) {                                    // Json dekodieren
        if (strcmp(ptr, ",")) strcpy(zone[i++], ptr);
        ptr = strtok(NULL, "\"]");
      }
      setTZ(zone[1]);
    }
    server.send(200, "text/plain", zone[0]);
  });
  server.on("/posixTZ", HTTP_GET, []() {
    struct tm ti;                                              // http://www.cplusplus.com/reference/ctime/tm/
    static char buf[26];                                       // je nach Format von "strftime" eventuell anpassen
    time_t now = time(&now);
    localtime_r(&now, &ti);
    strftime (buf, sizeof(buf), R"(["%T","%d.%m.%Y"])", &ti);  // http://www.cplusplus.com/reference/ctime/strftime/
    server.send(200, "application/json", buf);
  });
}

Die Webseite zur Esp8266 Weltzeit.

weltzeit.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">
    <link rel="stylesheet" href="style.css">
    <title>Weltzeit</title>
    <script>
      document.addEventListener('DOMContentLoaded', () => {
	  	var out, li = document.getElementById('list');
        fetch('https://raw.githubusercontent.com/nayarsystems/posix_tz_db/master/zones.json').then(resp => {
		  if (resp.ok) send();
          return resp.json();
        }).then(obj => {
          for (const [key, value] of Object.entries(obj)) {
            out += `<option value="${value}">${key}</option>`;
          }
		  li.innerHTML = out;
        });
	    li.addEventListener('change', send);
	    renew(), setInterval(renew, 1000);
	    function send() {
	      let formData = new FormData();
		  formData.append('zone', '["' + li.selectedIndex + '","' + li.value + '"]');
          fetch('/posixTZ', {
	        method: 'post',
	        body: li.selectedIndex >= 0 ? formData : ''
          }).then(resp => {
            return resp.text();
          }).then(text => {
		    li.selectedIndex = text;
		  });
	    }
        function renew() {
          fetch('/posixTZ').then(resp => {
            return resp.json();
          }).then(array => {
            document.getElementById('time').innerHTML = array[0];
		    document.getElementById('date').innerHTML = array[1];
          });
        }
	  });
    </script>
    <style>
      body {
        padding: 1em 0;
        font-size: 3em;
      }
	  main {
		display: flex;
        flex-flow: column;
        align-items: center;
        background-color: black;
        padding: .2em;
        border: .15em solid #aeaeab;
		border-radius: .2em;
        box-shadow: 5px 10px 5px rgba(0, 0, 0, 0.7);
	  }
	  select,span {
        margin-top: .5em;
      }
	  select {
	    -webkit-appearance: none;
        appearance: none;
        border: none;
        background: black;
        color: #fff;
        font-family: Sans-serif;
        font-size: .4em;
	  }
      span {
        color: #00ff05;
        font-weight: bold;
      }	  
    </style>
  </head>
  <body>
    <main>
	  <select id="list"></select>
      <span id="time"></span>
      <span id="date"></span>
	</main>
  </body>
</html>