From 603e968ec77d31c7f709c20245d6fd5a56e80dfa Mon Sep 17 00:00:00 2001 From: CaCO3 Date: Fri, 23 Dec 2022 22:45:25 +0100 Subject: [PATCH] Improve NTP handling (#1676) * fix special case where number is named "default" (keep all topics in top level instead of in a sub-group) * re-implemented SNTP usage, added way to disable NTP client, added timezone table * minor fixes Co-authored-by: CaCO3 --- .../jomjol_fileserver_ota/server_ota.cpp | 1 + .../jomjol_fileserver_ota/server_ota.h | 1 - .../ClassFlowCNNGeneral.cpp | 2 +- .../jomjol_flowcontroll/ClassFlowControll.cpp | 26 +- code/components/jomjol_helper/Helper.cpp | 10 +- code/components/jomjol_helper/Helper.h | 1 + code/components/jomjol_mqtt/server_mqtt.cpp | 12 +- .../jomjol_tfliteclass/server_tflite.cpp | 4 +- .../jomjol_time_sntp/CMakeLists.txt | 2 +- .../components/jomjol_time_sntp/time_sntp.cpp | 256 +++++---- code/components/jomjol_time_sntp/time_sntp.h | 13 +- code/main/main.cpp | 11 +- code/main/server_main.cpp | 2 +- sd-card/html/edit_config_param.html | 9 +- sd-card/html/timezones.html | 542 ++++++++++++++++++ 15 files changed, 731 insertions(+), 161 deletions(-) create mode 100644 sd-card/html/timezones.html diff --git a/code/components/jomjol_fileserver_ota/server_ota.cpp b/code/components/jomjol_fileserver_ota/server_ota.cpp index af58be04e..faf030426 100644 --- a/code/components/jomjol_fileserver_ota/server_ota.cpp +++ b/code/components/jomjol_fileserver_ota/server_ota.cpp @@ -45,6 +45,7 @@ static char ota_write_data[SERVER_OTA_SCRATCH_BUFSIZE + 1] = { 0 }; static const char *TAG = "OTA"; esp_err_t handler_reboot(httpd_req_t *req); +static bool ota_update_task(std::string fn); std::string _file_name_update; diff --git a/code/components/jomjol_fileserver_ota/server_ota.h b/code/components/jomjol_fileserver_ota/server_ota.h index 1f1ac9025..552588aaa 100644 --- a/code/components/jomjol_fileserver_ota/server_ota.h +++ b/code/components/jomjol_fileserver_ota/server_ota.h @@ -15,6 +15,5 @@ void CheckOTAUpdate(); void doReboot(); void hard_restart(); void CheckUpdate(); -static bool ota_update_task(std::string fn); #endif //SERVEROTA_H \ No newline at end of file diff --git a/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp b/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp index dbf15f8aa..18281b8f8 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp @@ -727,7 +727,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time) GENERAL[n]->ROI[roi]->isReject = true; result = -1; _result_save_file+= 100; // In case fit is not sufficient, the result should still be saved with "-10x.y". - string zw = "Value Rejected due to Threshold (Fit: " + to_string(_fit) + "Threshold: " + to_string(CNNGoodThreshold) + ")"; + string zw = "Value Rejected due to Threshold (Fit: " + to_string(_fit) + ", Threshold: " + to_string(CNNGoodThreshold) + ")"; LogFile.WriteToFile(ESP_LOG_WARN, TAG, zw); } else diff --git a/code/components/jomjol_flowcontroll/ClassFlowControll.cpp b/code/components/jomjol_flowcontroll/ClassFlowControll.cpp index 910a80720..f5ec267ce 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowControll.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowControll.cpp @@ -292,7 +292,7 @@ void ClassFlowControll::doFlowMakeImageOnly(string time){ for (int i = 0; i < FlowControll.size(); ++i) { if (FlowControll[i]->name() == "ClassFlowMakeImage") { - zw_time = gettimestring("%H:%M:%S"); + zw_time = getCurrentTimeString("%H:%M:%S"); std::string flowStatus = TranslateAktstatus(FlowControll[i]->name()); aktstatus = flowStatus + " (" + zw_time + ")"; #ifdef ENABLE_MQTT @@ -315,16 +315,19 @@ bool ClassFlowControll::doFlow(string time) #endif /* Check if we have a valid date/time and if not restart the NTP client */ - if (! getTimeIsSet()) { + /* if (! getTimeIsSet()) { LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Time not set, restarting NTP Client!"); restartNtpClient(); - } + }*/ + + //checkNtpStatus(0); for (int i = 0; i < FlowControll.size(); ++i) { - zw_time = gettimestring("%H:%M:%S"); + zw_time = getCurrentTimeString("%H:%M:%S"); std::string flowStatus = TranslateAktstatus(FlowControll[i]->name()); aktstatus = flowStatus + " (" + zw_time + ")"; + //LogFile.WriteToFile(ESP_LOG_INFO, TAG, aktstatus); #ifdef ENABLE_MQTT MQTTPublish(mqttServer_getMainTopic() + "/" + "status", flowStatus, false); #endif //ENABLE_MQTT @@ -355,9 +358,10 @@ bool ClassFlowControll::doFlow(string time) #endif } - zw_time = gettimestring("%H:%M:%S"); + zw_time = getCurrentTimeString("%H:%M:%S"); std::string flowStatus = "Flow finished"; aktstatus = flowStatus + " (" + zw_time + ")"; + //LogFile.WriteToFile(ESP_LOG_INFO, TAG, aktstatus); #ifdef ENABLE_MQTT MQTTPublish(mqttServer_getMainTopic() + "/" + "status", flowStatus, false); #endif //ENABLE_MQTT @@ -541,17 +545,7 @@ bool ClassFlowControll::ReadParameter(FILE* pfile, string& aktparamgraph) LogFile.SetLogFileRetention(std::stoi(splitted[1])); } - if ((toUpper(splitted[0]) == "TIMEZONE") && (splitted.size() > 1)) - { - string zw = "Set TimeZone: " + splitted[1]; - setTimeZone(splitted[1]); - } - - if ((toUpper(splitted[0]) == "TIMESERVER") && (splitted.size() > 1)) - { - string zw = "Set TimeZone: " + splitted[1]; - reset_servername(splitted[1]); - } + /* TimeServer and TimeZone got already read from the config, see setupTime () */ if ((toUpper(splitted[0]) == "RSSITHREASHOLD") && (splitted.size() > 1)) { diff --git a/code/components/jomjol_helper/Helper.cpp b/code/components/jomjol_helper/Helper.cpp index c52ce02cb..20e67e756 100644 --- a/code/components/jomjol_helper/Helper.cpp +++ b/code/components/jomjol_helper/Helper.cpp @@ -785,11 +785,17 @@ bool isSetSystemStatusFlag(SystemStatusFlag_t flag) { } } + +time_t getUpTime(void) { + return (uint32_t)(esp_timer_get_time()/1000/1000); // in seconds +} + + string getResetReason(void) { std::string reasonText; switch(esp_reset_reason()) { - case ESP_RST_POWERON: reasonText = "Power-on event"; break; //!< Reset due to power-on event + case ESP_RST_POWERON: reasonText = "Power-on event (or reset button)"; break; //!< Reset due to power-on event case ESP_RST_EXT: reasonText = "External pin"; break; //!< Reset by external pin (not applicable for ESP32) case ESP_RST_SW: reasonText = "Via esp_restart"; break; //!< Software reset via esp_restart case ESP_RST_PANIC: reasonText = "Exception/panic"; break; //!< Software reset due to exception/panic @@ -814,7 +820,7 @@ std::string getFormatedUptime(bool compact) { char buf[20]; #pragma GCC diagnostic ignored "-Wformat-truncation" - int uptime = (uint32_t)(esp_timer_get_time()/1000/1000); // in seconds + int uptime = getUpTime(); // in seconds int days = int(floor(uptime / (3600*24))); int hours = int(floor((uptime - days * 3600*24) / (3600))); diff --git a/code/components/jomjol_helper/Helper.h b/code/components/jomjol_helper/Helper.h index f56f6c9b9..482619374 100644 --- a/code/components/jomjol_helper/Helper.h +++ b/code/components/jomjol_helper/Helper.h @@ -85,6 +85,7 @@ void clearSystemStatusFlag(SystemStatusFlag_t flag); int getSystemStatus(void); bool isSetSystemStatusFlag(SystemStatusFlag_t flag); +time_t getUpTime(void); string getResetReason(void); std::string getFormatedUptime(bool compact); diff --git a/code/components/jomjol_mqtt/server_mqtt.cpp b/code/components/jomjol_mqtt/server_mqtt.cpp index 9747c45e4..d8965696d 100644 --- a/code/components/jomjol_mqtt/server_mqtt.cpp +++ b/code/components/jomjol_mqtt/server_mqtt.cpp @@ -91,7 +91,13 @@ void sendHomeAssistantDiscoveryTopic(std::string group, std::string field, } } else { + if (field == "problem") { // Special binary sensor which is based on error topic + payload += "\"state_topic\": \"~/error\"," + nl; + payload += "\"value_template\": \"{{ 'OFF' if 'no error' in value else 'ON'}}\"," + nl; + } + else { payload += "\"state_topic\": \"~/" + field + "\"," + nl; + } } if (unit != "") { @@ -149,7 +155,11 @@ void MQTThomeassistantDiscovery() { for (int i = 0; i < (*NUMBERS).size(); ++i) { - std::string group = (*NUMBERS)[i]->name; + std::string group = (*NUMBERS)[i]->name; + if (group == "default") { + group = ""; + } + // Group | Field | User Friendly Name | Icon | Unit | Device Class | State Class | Entity Category sendHomeAssistantDiscoveryTopic(group, "value", "Value", "gauge", valueUnit, meterType, "total_increasing", ""); sendHomeAssistantDiscoveryTopic(group, "raw", "Raw Value", "raw", valueUnit, "", "total_increasing", "diagnostic"); diff --git a/code/components/jomjol_tfliteclass/server_tflite.cpp b/code/components/jomjol_tfliteclass/server_tflite.cpp index bc5e9766e..ee51f4808 100644 --- a/code/components/jomjol_tfliteclass/server_tflite.cpp +++ b/code/components/jomjol_tfliteclass/server_tflite.cpp @@ -101,7 +101,7 @@ void doInit(void) bool doflow(void) { - std::string zw_time = gettimestring(LOGFILE_TIME_FORMAT); + std::string zw_time = getCurrentTimeString(LOGFILE_TIME_FORMAT); ESP_LOGD(TAG, "doflow - start %s", zw_time.c_str()); flowisrunning = true; tfliteflow.doFlow(zw_time); @@ -787,7 +787,7 @@ void task_autodoFlow(void *pvParameter) auto_isrunning = tfliteflow.isAutoStart(auto_intervall); if (isSetupModusActive()) { auto_isrunning = false; - std::string zw_time = gettimestring(LOGFILE_TIME_FORMAT); + std::string zw_time = getCurrentTimeString(LOGFILE_TIME_FORMAT); tfliteflow.doFlowMakeImageOnly(zw_time); } diff --git a/code/components/jomjol_time_sntp/CMakeLists.txt b/code/components/jomjol_time_sntp/CMakeLists.txt index c57b54d38..6eade8c30 100644 --- a/code/components/jomjol_time_sntp/CMakeLists.txt +++ b/code/components/jomjol_time_sntp/CMakeLists.txt @@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*) idf_component_register(SRCS ${app_sources} INCLUDE_DIRS "." - REQUIRES tflite-lib jomjol_logfile) + REQUIRES tflite-lib jomjol_logfile jomjol_configfile) diff --git a/code/components/jomjol_time_sntp/time_sntp.cpp b/code/components/jomjol_time_sntp/time_sntp.cpp index c539e9708..9be866ce1 100644 --- a/code/components/jomjol_time_sntp/time_sntp.cpp +++ b/code/components/jomjol_time_sntp/time_sntp.cpp @@ -16,18 +16,20 @@ #include "ClassLogFile.h" +#include "configFile.h" +#include "Helper.h" + + static const char *TAG = "SNTP"; -time_t bootTime; +static std::string timeZone = ""; +static std::string timeServer = "undefined"; +static bool useNtp = true; -static bool obtain_time(void); -static void initialize_sntp(void); -static void logNtpStatus(sntp_sync_status_t status); +std::string getNtpStatusText(sntp_sync_status_t status); +static void setTimeZone(std::string _tzstring); +static std::string getServerName(void); -void time_sync_notification_cb(struct timeval *tv) -{ - ESP_LOGI(TAG, "Notification of a time synchronization event"); -} std::string ConvertTimeToString(time_t _time, const char * frm) { @@ -40,7 +42,8 @@ std::string ConvertTimeToString(time_t _time, const char * frm) return result; } -std::string gettimestring(const char * frm) + +std::string getCurrentTimeString(const char * frm) { time_t now; struct tm timeinfo; @@ -53,153 +56,172 @@ std::string gettimestring(const char * frm) return result; } -bool setup_time() + +void time_sync_notification_cb(struct timeval *tv) +{ + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Time is now successfully synced with NTP Server " + + getServerName() + ": " + getCurrentTimeString("%Y-%m-%d %H:%M:%S")); +} + + +void setTimeZone(std::string _tzstring) { + setenv("TZ", _tzstring.c_str(), 1); + tzset(); + _tzstring = "Time zone set to " + _tzstring; + LogFile.WriteToFile(ESP_LOG_INFO, TAG, _tzstring); +} + + +std::string getNtpStatusText(sntp_sync_status_t status) { + if (status == SNTP_SYNC_STATUS_COMPLETED) { + return "Synchronized"; + } + else if (status == SNTP_SYNC_STATUS_IN_PROGRESS) { + return "In Progress"; + } + else { // SNTP_SYNC_STATUS_RESET + return "Reset"; + } +} + + +bool getTimeIsSet(void) { time_t now; struct tm timeinfo; time(&now); localtime_r(&now, &timeinfo); - char strftime_buf[64]; - bool success = true; // Is time set? If not, tm_year will be (1970 - 1900). - if (!getTimeIsSet()) { - initialize_sntp(); - LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Time is not set yet. Getting time over NTP server " + std::string(sntp_getservername(0))); - if (!obtain_time()) { - success = false; - } + if ((timeinfo.tm_year < (2022 - 1900))) { + return false; + } + else { + return true; + } +} + +/*void restartNtpClient(void) { +// sntp_restart(); + // obtain_time(); +}*/ + + +bool getUseNtp(void) { + return useNtp; +} - // update 'now' variable with current time - time(&now); - setTimeZone("CET-1CEST,M3.5.0,M10.5.0/3"); +std::string getServerName(void) { + char buf[100]; - localtime_r(&now, &timeinfo); - strftime(strftime_buf, sizeof(strftime_buf), "%Y-%m-%d_%H:%M:%S", &timeinfo); - ESP_LOGI(TAG, "The current date/time in Berlin is: %s", strftime_buf); + if (sntp_getservername(0)){ + snprintf(buf, sizeof(buf), "%s", sntp_getservername(0)); + return std::string(buf); } - else { - localtime_r(&now, &timeinfo); - strftime(strftime_buf, sizeof(strftime_buf), "%Y-%m-%d_%H:%M:%S", &timeinfo); - ESP_LOGI(TAG, "Time is already set (%s)", strftime_buf); + else { // we have either IPv4 or IPv6 address + ip_addr_t const *ip = sntp_getserver(0); + if (ipaddr_ntoa_r(ip, buf, sizeof(buf)) != NULL) { + return std::string(buf); + } } - return success; + return ""; } -void setTimeZone(std::string _tzstring) -{ - setenv("TZ", _tzstring.c_str(), 1); - tzset(); - _tzstring = "Time zone set to " + _tzstring; - LogFile.WriteToFile(ESP_LOG_INFO, TAG, _tzstring); -} -static bool obtain_time(void) -{ - time_t now = 0; - struct tm timeinfo = {}; - int retry = 0; - const int retry_count = 10; - bool success = true; +/** + * Load the TimeZone and TimeServer from the config file and initialize the NTP client + */ +bool setupTime() { + time_t now; + struct tm timeinfo; + char strftime_buf[64]; - time(&now); - localtime_r(&now, &timeinfo); + ConfigFile configFile = ConfigFile(CONFIG_FILE); - LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Waiting until we get a time from the NTP server " + std::string(sntp_getservername(0))); - while (true) { - retry++; + std::vector splitted; + std::string line = ""; + bool disabledLine = false; + bool eof = false; - if (retry == retry_count) { - ESP_LOGW(TAG, "NTP time fetching seems to take longer, will check again on next round!"); // The NTP client will automatically retry periodically! - success = false; - break; - } + /* Load config from config file */ + while ((!configFile.GetNextParagraph(line, disabledLine, eof) || + (line.compare("[System]") != 0)) && !eof) {} + if (eof) { + return false; + } - sntp_sync_status_t status = sntp_get_sync_status(); - logNtpStatus(status); - if (status == SNTP_SYNC_STATUS_COMPLETED) { - LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Time is synced with NTP Server " + std::string(sntp_getservername(0))); - break; + if (disabledLine) { + return false; + } + + while (configFile.getNextLine(&line, disabledLine, eof) && + !configFile.isNewParagraph(line)) { + splitted = ZerlegeZeile(line); + + if (toUpper(splitted[0]) == "TIMEZONE") { + timeZone = splitted[1]; } - vTaskDelay(2000 / portTICK_PERIOD_MS); + if (toUpper(splitted[0]) == "TIMESERVER") { + if (splitted.size() <= 1) { // Key has no value => we use this to show it as disabled + timeServer = ""; + } + else { + timeServer = splitted[1]; + } + } } - - time(&now); - localtime_r(&now, &timeinfo); - return success; -} -void logNtpStatus(sntp_sync_status_t status) { - if (status == SNTP_SYNC_STATUS_COMPLETED) { - LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Status OK"); + /* Setup NTP Server and Timezone */ + if (timeServer == "undefined") { + timeServer = "pool.ntp.org"; + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "TimeServer not defined, using default: " + timeServer); } - else if (status == SNTP_SYNC_STATUS_IN_PROGRESS) { - LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Status: In Progress"); + else if (timeServer == "") { + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "TimeServer config empty, disabling NTP"); + useNtp = false; } - else { // SNTP_SYNC_STATUS_RESET - LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Status: Reset"); + else { + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "TimeServer: " + timeServer); + } + + if (timeZone == "") { + timeZone = "CET-1CEST,M3.5.0,M10.5.0/3"; + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "TimeZone not set, using default: " + timeZone); } -} -void reset_servername(std::string _servername) -{ - sntp_stop(); - sntp_setoperatingmode(SNTP_OPMODE_POLL); - sntp_setservername(0, _servername.c_str()); - LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Set SNTP-Server to " + std::string(sntp_getservername(0))); - sntp_init(); - obtain_time(); - std::string zw = gettimestring("%Y%m%d-%H%M%S"); - ESP_LOGD(TAG, "Time ist %s", zw.c_str()); -} + if (useNtp) { + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Configuring NTP Client..."); + sntp_setoperatingmode(SNTP_OPMODE_POLL); + sntp_setservername(0, timeServer.c_str()); + sntp_init(); -static void initialize_sntp(void) -{ - ESP_LOGI(TAG, "Initializing SNTP"); - sntp_setoperatingmode(SNTP_OPMODE_POLL); - sntp_setservername(0, "pool.ntp.org"); -// sntp_set_time_sync_notification_cb(time_sync_notification_cb); - sntp_init(); -} + sntp_set_time_sync_notification_cb(time_sync_notification_cb); -void setBootTime() -{ - time(&bootTime); -} + setTimeZone(timeZone); + } -time_t getUpTime() -{ - time_t now; - time(&now); - return now - bootTime; -} + /* The RTC keeps the time after a restart (Except on Power On or Pin Reset) + * There should only be a minor correction through NTP */ -bool getTimeIsSet(void) { - time_t now; - struct tm timeinfo; + // Get current time from RTC time(&now); localtime_r(&now, &timeinfo); - char strftime_buf[64]; - - localtime_r(&now, &timeinfo); - strftime(strftime_buf, sizeof(strftime_buf), "%Y-%m-%d_%H:%M:%S", &timeinfo); - ESP_LOGD(TAG, "The current date/time in Berlin is: %s", strftime_buf); + strftime(strftime_buf, sizeof(strftime_buf), "%Y-%m-%d %H:%M:%S", &timeinfo); - // Is time set? If not, tm_year will be (1970 - 1900). - if ((timeinfo.tm_year < (2022 - 1900))) { - return false; + if (getTimeIsSet()) { + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Time is already set: " + std::string(strftime_buf)); } else { - return true; + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "The local time is unknown, starting with " + std::string(strftime_buf)); + if (useNtp) { + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Once the NTP server provides a time, we will switch to that one"); + } } -} -void restartNtpClient(void) { - sntp_restart(); - obtain_time(); + return true; } diff --git a/code/components/jomjol_time_sntp/time_sntp.h b/code/components/jomjol_time_sntp/time_sntp.h index 7b1685ddf..99f5ba1e0 100644 --- a/code/components/jomjol_time_sntp/time_sntp.h +++ b/code/components/jomjol_time_sntp/time_sntp.h @@ -15,20 +15,15 @@ #include "esp_log.h" #include "esp_attr.h" #include "esp_sleep.h" -// #include "nvs_flash.h" #include "esp_sntp.h" -bool setup_time(void); - -std::string gettimestring(const char * frm); +std::string getCurrentTimeString(const char * frm); std::string ConvertTimeToString(time_t _time, const char * frm); -void setTimeZone(std::string _tzstring); -void reset_servername(std::string _servername); -void setBootTime(); -time_t getUpTime(); bool getTimeIsSet(void); -void restartNtpClient(void); + +bool getUseNtp(void); +bool setupTime(); #endif //TIMESNTP_H \ No newline at end of file diff --git a/code/main/main.cpp b/code/main/main.cpp index b495b0d03..e425c3698 100644 --- a/code/main/main.cpp +++ b/code/main/main.cpp @@ -156,6 +156,8 @@ extern "C" void app_main(void) return; // No way to continue without SD-Card! } + setupTime(); + string versionFormated = getFwVersion() + ", Date/Time: " + std::string(BUILD_TIME) + \ ", Web UI: " + getHTMLversion(); @@ -207,13 +209,6 @@ extern "C" void app_main(void) ESP_LOGD(TAG, "main: sleep for: %ldms", (long) xDelay); vTaskDelay( xDelay ); - if (!setup_time()) { - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "NTP Initialization failed!"); - setSystemStatusFlag(SYSTEM_STATUS_NTP_BAD); - } - - setBootTime(); - LogFile.WriteToFile(ESP_LOG_INFO, TAG, "================================================="); LogFile.WriteToFile(ESP_LOG_INFO, TAG, "================== Main Started ================="); LogFile.WriteToFile(ESP_LOG_INFO, TAG, "================================================="); @@ -222,7 +217,7 @@ extern "C" void app_main(void) LogFile.WriteToFile(ESP_LOG_WARN, TAG, std::string("Web UI version (") + getHTMLcommit() + ") does not match firmware version (" + std::string(GIT_REV) + ") !"); } - std::string zw = gettimestring("%Y%m%d-%H%M%S"); + std::string zw = getCurrentTimeString("%Y%m%d-%H%M%S"); ESP_LOGD(TAG, "time %s", zw.c_str()); /* Check if PSRAM can be initalized */ diff --git a/code/main/server_main.cpp b/code/main/server_main.cpp index f028a6484..f86fd3adc 100644 --- a/code/main/server_main.cpp +++ b/code/main/server_main.cpp @@ -468,7 +468,7 @@ httpd_handle_t start_webserver(void) // config.uri_match_fn = NULL; config.uri_match_fn = httpd_uri_match_wildcard; - starttime = gettimestring("%Y%m%d-%H%M%S"); + starttime = getCurrentTimeString("%Y%m%d-%H%M%S"); // Start the httpd server ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port); diff --git a/sd-card/html/edit_config_param.html b/sd-card/html/edit_config_param.html index 2176d5f70..ba44fd12e 100644 --- a/sd-card/html/edit_config_param.html +++ b/sd-card/html/edit_config_param.html @@ -1345,7 +1345,8 @@
Enabling GPIO handler, disable by default integrated flash light.
Please - Time zone in POSIX syntax (Europe/Berlin = "CET-1CEST,M3.5.0,M10.5.0/3" - incl. daylight saving) + Time zone in POSIX syntax (Europe/Berlin = "CET-1CEST,M3.5.0,M10.5.0/3" - incl. daylight saving)
+ Use this table to find the settings for your region. @@ -1357,7 +1358,11 @@
Enabling GPIO handler, disable by default integrated flash light.
Please - Time server to synchronize system time (default: "pool.ntp.org" - used if nothing is specified) + Time server to synchronize system time. If it is disabled or "undefined", "pool.ntp.org" will be used.
+ You can also set it to the IP of your router. Many routers like + Fritzboxes can act as a local NTP server.
+ To disable NTP, you need to activate it but set the TimeServer config to be empty. In such case the time always starts at 01.01.1970 after each power cycle! diff --git a/sd-card/html/timezones.html b/sd-card/html/timezones.html new file mode 100644 index 000000000..90cd52494 --- /dev/null +++ b/sd-card/html/timezones.html @@ -0,0 +1,542 @@ + + + + + + + + +

Timezones

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
RegionCode
Africa/AbidjanGMT0
Africa/AccraGMT0
Africa/Addis_AbabaEAT-3
Africa/AlgiersCET-1
Africa/AsmaraEAT-3
Africa/BamakoGMT0
Africa/BanguiWAT-1
Africa/BanjulGMT0
Africa/BissauGMT0
Africa/BlantyreCAT-2
Africa/BrazzavilleWAT-1
Africa/BujumburaCAT-2
Africa/CairoEET-2
Africa/Casablanca<+01>-1
Africa/CeutaCET-1CEST,M3.5.0,M10.5.0/3
Africa/ConakryGMT0
Africa/DakarGMT0
Africa/Dar_es_SalaamEAT-3
Africa/DjiboutiEAT-3
Africa/DoualaWAT-1
Africa/El_Aaiun<+01>-1
Africa/FreetownGMT0
Africa/GaboroneCAT-2
Africa/HarareCAT-2
Africa/JohannesburgSAST-2
Africa/JubaCAT-2
Africa/KampalaEAT-3
Africa/KhartoumCAT-2
Africa/KigaliCAT-2
Africa/KinshasaWAT-1
Africa/LagosWAT-1
Africa/LibrevilleWAT-1
Africa/LomeGMT0
Africa/LuandaWAT-1
Africa/LubumbashiCAT-2
Africa/LusakaCAT-2
Africa/MalaboWAT-1
Africa/MaputoCAT-2
Africa/MaseruSAST-2
Africa/MbabaneSAST-2
Africa/MogadishuEAT-3
Africa/MonroviaGMT0
Africa/NairobiEAT-3
Africa/NdjamenaWAT-1
Africa/NiameyWAT-1
Africa/NouakchottGMT0
Africa/OuagadougouGMT0
Africa/Porto-NovoWAT-1
Africa/Sao_TomeGMT0
Africa/TripoliEET-2
Africa/TunisCET-1
Africa/WindhoekCAT-2
America/AdakHST10HDT,M3.2.0,M11.1.0
America/AnchorageAKST9AKDT,M3.2.0,M11.1.0
America/AnguillaAST4
America/AntiguaAST4
America/Araguaina<-03>3
America/Argentina/Buenos_Aires<-03>3
America/Argentina/Catamarca<-03>3
America/Argentina/Cordoba<-03>3
America/Argentina/Jujuy<-03>3
America/Argentina/La_Rioja<-03>3
America/Argentina/Mendoza<-03>3
America/Argentina/Rio_Gallegos<-03>3
America/Argentina/Salta<-03>3
America/Argentina/San_Juan<-03>3
America/Argentina/San_Luis<-03>3
America/Argentina/Tucuman<-03>3
America/Argentina/Ushuaia<-03>3
America/ArubaAST4
America/Asuncion<-04>4<-03>,M10.1.0/0,M3.4.0/0
America/AtikokanEST5
America/Bahia<-03>3
America/Bahia_BanderasCST6CDT,M4.1.0,M10.5.0
America/BarbadosAST4
America/Belem<-03>3
America/BelizeCST6
America/Blanc-SablonAST4
America/Boa_Vista<-04>4
America/Bogota<-05>5
America/BoiseMST7MDT,M3.2.0,M11.1.0
America/Cambridge_BayMST7MDT,M3.2.0,M11.1.0
America/Campo_Grande<-04>4
America/CancunEST5
America/Caracas<-04>4
America/Cayenne<-03>3
America/CaymanEST5
America/ChicagoCST6CDT,M3.2.0,M11.1.0
America/ChihuahuaMST7MDT,M4.1.0,M10.5.0
America/Costa_RicaCST6
America/CrestonMST7
America/Cuiaba<-04>4
America/CuracaoAST4
America/DanmarkshavnGMT0
America/DawsonMST7
America/Dawson_CreekMST7
America/DenverMST7MDT,M3.2.0,M11.1.0
America/DetroitEST5EDT,M3.2.0,M11.1.0
America/DominicaAST4
America/EdmontonMST7MDT,M3.2.0,M11.1.0
America/Eirunepe<-05>5
America/El_SalvadorCST6
America/Fort_NelsonMST7
America/Fortaleza<-03>3
America/Glace_BayAST4ADT,M3.2.0,M11.1.0
America/Godthab<-03>3<-02>,M3.5.0/-2,M10.5.0/-1
America/Goose_BayAST4ADT,M3.2.0,M11.1.0
America/Grand_TurkEST5EDT,M3.2.0,M11.1.0
America/GrenadaAST4
America/GuadeloupeAST4
America/GuatemalaCST6
America/Guayaquil<-05>5
America/Guyana<-04>4
America/HalifaxAST4ADT,M3.2.0,M11.1.0
America/HavanaCST5CDT,M3.2.0/0,M11.1.0/1
America/HermosilloMST7
America/Indiana/IndianapolisEST5EDT,M3.2.0,M11.1.0
America/Indiana/KnoxCST6CDT,M3.2.0,M11.1.0
America/Indiana/MarengoEST5EDT,M3.2.0,M11.1.0
America/Indiana/PetersburgEST5EDT,M3.2.0,M11.1.0
America/Indiana/Tell_CityCST6CDT,M3.2.0,M11.1.0
America/Indiana/VevayEST5EDT,M3.2.0,M11.1.0
America/Indiana/VincennesEST5EDT,M3.2.0,M11.1.0
America/Indiana/WinamacEST5EDT,M3.2.0,M11.1.0
America/InuvikMST7MDT,M3.2.0,M11.1.0
America/IqaluitEST5EDT,M3.2.0,M11.1.0
America/JamaicaEST5
America/JuneauAKST9AKDT,M3.2.0,M11.1.0
America/Kentucky/LouisvilleEST5EDT,M3.2.0,M11.1.0
America/Kentucky/MonticelloEST5EDT,M3.2.0,M11.1.0
America/KralendijkAST4
America/La_Paz<-04>4
America/Lima<-05>5
America/Los_AngelesPST8PDT,M3.2.0,M11.1.0
America/Lower_PrincesAST4
America/Maceio<-03>3
America/ManaguaCST6
America/Manaus<-04>4
America/MarigotAST4
America/MartiniqueAST4
America/MatamorosCST6CDT,M3.2.0,M11.1.0
America/MazatlanMST7MDT,M4.1.0,M10.5.0
America/MenomineeCST6CDT,M3.2.0,M11.1.0
America/MeridaCST6CDT,M4.1.0,M10.5.0
America/MetlakatlaAKST9AKDT,M3.2.0,M11.1.0
America/Mexico_CityCST6CDT,M4.1.0,M10.5.0
America/Miquelon<-03>3<-02>,M3.2.0,M11.1.0
America/MonctonAST4ADT,M3.2.0,M11.1.0
America/MonterreyCST6CDT,M4.1.0,M10.5.0
America/Montevideo<-03>3
America/MontrealEST5EDT,M3.2.0,M11.1.0
America/MontserratAST4
America/NassauEST5EDT,M3.2.0,M11.1.0
America/New_YorkEST5EDT,M3.2.0,M11.1.0
America/NipigonEST5EDT,M3.2.0,M11.1.0
America/NomeAKST9AKDT,M3.2.0,M11.1.0
America/Noronha<-02>2
America/North_Dakota/BeulahCST6CDT,M3.2.0,M11.1.0
America/North_Dakota/CenterCST6CDT,M3.2.0,M11.1.0
America/North_Dakota/New_SalemCST6CDT,M3.2.0,M11.1.0
America/Nuuk<-03>3<-02>,M3.5.0/-2,M10.5.0/-1
America/OjinagaMST7MDT,M3.2.0,M11.1.0
America/PanamaEST5
America/PangnirtungEST5EDT,M3.2.0,M11.1.0
America/Paramaribo<-03>3
America/PhoenixMST7
America/Port_of_SpainAST4
America/Port-au-PrinceEST5EDT,M3.2.0,M11.1.0
America/Porto_Velho<-04>4
America/Puerto_RicoAST4
America/Punta_Arenas<-03>3
America/Rainy_RiverCST6CDT,M3.2.0,M11.1.0
America/Rankin_InletCST6CDT,M3.2.0,M11.1.0
America/Recife<-03>3
America/ReginaCST6
America/ResoluteCST6CDT,M3.2.0,M11.1.0
America/Rio_Branco<-05>5
America/Santarem<-03>3
America/Santiago<-04>4<-03>,M9.1.6/24,M4.1.6/24
America/Santo_DomingoAST4
America/Sao_Paulo<-03>3
America/Scoresbysund<-01>1<+00>,M3.5.0/0,M10.5.0/1
America/SitkaAKST9AKDT,M3.2.0,M11.1.0
America/St_BarthelemyAST4
America/St_JohnsNST3:30NDT,M3.2.0,M11.1.0
America/St_KittsAST4
America/St_LuciaAST4
America/St_ThomasAST4
America/St_VincentAST4
America/Swift_CurrentCST6
America/TegucigalpaCST6
America/ThuleAST4ADT,M3.2.0,M11.1.0
America/Thunder_BayEST5EDT,M3.2.0,M11.1.0
America/TijuanaPST8PDT,M3.2.0,M11.1.0
America/TorontoEST5EDT,M3.2.0,M11.1.0
America/TortolaAST4
America/VancouverPST8PDT,M3.2.0,M11.1.0
America/WhitehorseMST7
America/WinnipegCST6CDT,M3.2.0,M11.1.0
America/YakutatAKST9AKDT,M3.2.0,M11.1.0
America/YellowknifeMST7MDT,M3.2.0,M11.1.0
Antarctica/Casey<+11>-11
Antarctica/Davis<+07>-7
Antarctica/DumontDUrville<+10>-10
Antarctica/MacquarieAEST-10AEDT,M10.1.0,M4.1.0/3
Antarctica/Mawson<+05>-5
Antarctica/McMurdoNZST-12NZDT,M9.5.0,M4.1.0/3
Antarctica/Palmer<-03>3
Antarctica/Rothera<-03>3
Antarctica/Syowa<+03>-3
Antarctica/Troll<+00>0<+02>-2,M3.5.0/1,M10.5.0/3
Antarctica/Vostok<+06>-6
Arctic/LongyearbyenCET-1CEST,M3.5.0,M10.5.0/3
Asia/Aden<+03>-3
Asia/Almaty<+06>-6
Asia/AmmanEET-2EEST,M2.5.4/24,M10.5.5/1
Asia/Anadyr<+12>-12
Asia/Aqtau<+05>-5
Asia/Aqtobe<+05>-5
Asia/Ashgabat<+05>-5
Asia/Atyrau<+05>-5
Asia/Baghdad<+03>-3
Asia/Bahrain<+03>-3
Asia/Baku<+04>-4
Asia/Bangkok<+07>-7
Asia/Barnaul<+07>-7
Asia/BeirutEET-2EEST,M3.5.0/0,M10.5.0/0
Asia/Bishkek<+06>-6
Asia/Brunei<+08>-8
Asia/Chita<+09>-9
Asia/Choibalsan<+08>-8
Asia/Colombo<+0530>-5:30
Asia/DamascusEET-2EEST,M3.5.5/0,M10.5.5/0
Asia/Dhaka<+06>-6
Asia/Dili<+09>-9
Asia/Dubai<+04>-4
Asia/Dushanbe<+05>-5
Asia/FamagustaEET-2EEST,M3.5.0/3,M10.5.0/4
Asia/GazaEET-2EEST,M3.4.4/48,M10.5.5/1
Asia/HebronEET-2EEST,M3.4.4/48,M10.5.5/1
Asia/Ho_Chi_Minh<+07>-7
Asia/Hong_KongHKT-8
Asia/Hovd<+07>-7
Asia/Irkutsk<+08>-8
Asia/JakartaWIB-7
Asia/JayapuraWIT-9
Asia/JerusalemIST-2IDT,M3.4.4/26,M10.5.0
Asia/Kabul<+0430>-4:30
Asia/Kamchatka<+12>-12
Asia/KarachiPKT-5
Asia/Kathmandu<+0545>-5:45
Asia/Khandyga<+09>-9
Asia/KolkataIST-5:30
Asia/Krasnoyarsk<+07>-7
Asia/Kuala_Lumpur<+08>-8
Asia/Kuching<+08>-8
Asia/Kuwait<+03>-3
Asia/MacauCST-8
Asia/Magadan<+11>-11
Asia/MakassarWITA-8
Asia/ManilaPST-8
Asia/Muscat<+04>-4
Asia/NicosiaEET-2EEST,M3.5.0/3,M10.5.0/4
Asia/Novokuznetsk<+07>-7
Asia/Novosibirsk<+07>-7
Asia/Omsk<+06>-6
Asia/Oral<+05>-5
Asia/Phnom_Penh<+07>-7
Asia/PontianakWIB-7
Asia/PyongyangKST-9
Asia/Qatar<+03>-3
Asia/Qyzylorda<+05>-5
Asia/Riyadh<+03>-3
Asia/Sakhalin<+11>-11
Asia/Samarkand<+05>-5
Asia/SeoulKST-9
Asia/ShanghaiCST-8
Asia/Singapore<+08>-8
Asia/Srednekolymsk<+11>-11
Asia/TaipeiCST-8
Asia/Tashkent<+05>-5
Asia/Tbilisi<+04>-4
Asia/Tehran<+0330>-3:30<+0430>,J79/24,J263/24
Asia/Thimphu<+06>-6
Asia/TokyoJST-9
Asia/Tomsk<+07>-7
Asia/Ulaanbaatar<+08>-8
Asia/Urumqi<+06>-6
Asia/Ust-Nera<+10>-10
Asia/Vientiane<+07>-7
Asia/Vladivostok<+10>-10
Asia/Yakutsk<+09>-9
Asia/Yangon<+0630>-6:30
Asia/Yekaterinburg<+05>-5
Asia/Yerevan<+04>-4
Atlantic/Azores<-01>1<+00>,M3.5.0/0,M10.5.0/1
Atlantic/BermudaAST4ADT,M3.2.0,M11.1.0
Atlantic/CanaryWET0WEST,M3.5.0/1,M10.5.0
Atlantic/Cape_Verde<-01>1
Atlantic/FaroeWET0WEST,M3.5.0/1,M10.5.0
Atlantic/MadeiraWET0WEST,M3.5.0/1,M10.5.0
Atlantic/ReykjavikGMT0
Atlantic/South_Georgia<-02>2
Atlantic/St_HelenaGMT0
Atlantic/Stanley<-03>3
Australia/AdelaideACST-9:30ACDT,M10.1.0,M4.1.0/3
Australia/BrisbaneAEST-10
Australia/Broken_HillACST-9:30ACDT,M10.1.0,M4.1.0/3
Australia/CurrieAEST-10AEDT,M10.1.0,M4.1.0/3
Australia/DarwinACST-9:30
Australia/Eucla<+0845>-8:45
Australia/HobartAEST-10AEDT,M10.1.0,M4.1.0/3
Australia/LindemanAEST-10
Australia/Lord_Howe<+1030>-10:30<+11>-11,M10.1.0,M4.1.0
Australia/MelbourneAEST-10AEDT,M10.1.0,M4.1.0/3
Australia/PerthAWST-8
Australia/SydneyAEST-10AEDT,M10.1.0,M4.1.0/3
Etc/GMTGMT0
Etc/GMT-0GMT0
Etc/GMT-1<+01>-1
Etc/GMT-10<+10>-10
Etc/GMT-11<+11>-11
Etc/GMT-12<+12>-12
Etc/GMT-13<+13>-13
Etc/GMT-14<+14>-14
Etc/GMT-2<+02>-2
Etc/GMT-3<+03>-3
Etc/GMT-4<+04>-4
Etc/GMT-5<+05>-5
Etc/GMT-6<+06>-6
Etc/GMT-7<+07>-7
Etc/GMT-8<+08>-8
Etc/GMT-9<+09>-9
Etc/GMT+0GMT0
Etc/GMT+1<-01>1
Etc/GMT+10<-10>10
Etc/GMT+11<-11>11
Etc/GMT+12<-12>12
Etc/GMT+2<-02>2
Etc/GMT+3<-03>3
Etc/GMT+4<-04>4
Etc/GMT+5<-05>5
Etc/GMT+6<-06>6
Etc/GMT+7<-07>7
Etc/GMT+8<-08>8
Etc/GMT+9<-09>9
Etc/GMT0GMT0
Etc/GreenwichGMT0
Etc/UCTUTC0
Etc/UniversalUTC0
Etc/UTCUTC0
Etc/ZuluUTC0
Europe/AmsterdamCET-1CEST,M3.5.0,M10.5.0/3
Europe/AndorraCET-1CEST,M3.5.0,M10.5.0/3
Europe/Astrakhan<+04>-4
Europe/AthensEET-2EEST,M3.5.0/3,M10.5.0/4
Europe/BelgradeCET-1CEST,M3.5.0,M10.5.0/3
Europe/BerlinCET-1CEST,M3.5.0,M10.5.0/3
Europe/BratislavaCET-1CEST,M3.5.0,M10.5.0/3
Europe/BrusselsCET-1CEST,M3.5.0,M10.5.0/3
Europe/BucharestEET-2EEST,M3.5.0/3,M10.5.0/4
Europe/BudapestCET-1CEST,M3.5.0,M10.5.0/3
Europe/BusingenCET-1CEST,M3.5.0,M10.5.0/3
Europe/ChisinauEET-2EEST,M3.5.0,M10.5.0/3
Europe/CopenhagenCET-1CEST,M3.5.0,M10.5.0/3
Europe/DublinIST-1GMT0,M10.5.0,M3.5.0/1
Europe/GibraltarCET-1CEST,M3.5.0,M10.5.0/3
Europe/GuernseyGMT0BST,M3.5.0/1,M10.5.0
Europe/HelsinkiEET-2EEST,M3.5.0/3,M10.5.0/4
Europe/Isle_of_ManGMT0BST,M3.5.0/1,M10.5.0
Europe/Istanbul<+03>-3
Europe/JerseyGMT0BST,M3.5.0/1,M10.5.0
Europe/KaliningradEET-2
Europe/KievEET-2EEST,M3.5.0/3,M10.5.0/4
Europe/Kirov<+03>-3
Europe/LisbonWET0WEST,M3.5.0/1,M10.5.0
Europe/LjubljanaCET-1CEST,M3.5.0,M10.5.0/3
Europe/LondonGMT0BST,M3.5.0/1,M10.5.0
Europe/LuxembourgCET-1CEST,M3.5.0,M10.5.0/3
Europe/MadridCET-1CEST,M3.5.0,M10.5.0/3
Europe/MaltaCET-1CEST,M3.5.0,M10.5.0/3
Europe/MariehamnEET-2EEST,M3.5.0/3,M10.5.0/4
Europe/Minsk<+03>-3
Europe/MonacoCET-1CEST,M3.5.0,M10.5.0/3
Europe/MoscowMSK-3
Europe/OsloCET-1CEST,M3.5.0,M10.5.0/3
Europe/ParisCET-1CEST,M3.5.0,M10.5.0/3
Europe/PodgoricaCET-1CEST,M3.5.0,M10.5.0/3
Europe/PragueCET-1CEST,M3.5.0,M10.5.0/3
Europe/RigaEET-2EEST,M3.5.0/3,M10.5.0/4
Europe/RomeCET-1CEST,M3.5.0,M10.5.0/3
Europe/Samara<+04>-4
Europe/San_MarinoCET-1CEST,M3.5.0,M10.5.0/3
Europe/SarajevoCET-1CEST,M3.5.0,M10.5.0/3
Europe/Saratov<+04>-4
Europe/SimferopolMSK-3
Europe/SkopjeCET-1CEST,M3.5.0,M10.5.0/3
Europe/SofiaEET-2EEST,M3.5.0/3,M10.5.0/4
Europe/StockholmCET-1CEST,M3.5.0,M10.5.0/3
Europe/TallinnEET-2EEST,M3.5.0/3,M10.5.0/4
Europe/TiraneCET-1CEST,M3.5.0,M10.5.0/3
Europe/Ulyanovsk<+04>-4
Europe/UzhgorodEET-2EEST,M3.5.0/3,M10.5.0/4
Europe/VaduzCET-1CEST,M3.5.0,M10.5.0/3
Europe/VaticanCET-1CEST,M3.5.0,M10.5.0/3
Europe/ViennaCET-1CEST,M3.5.0,M10.5.0/3
Europe/VilniusEET-2EEST,M3.5.0/3,M10.5.0/4
Europe/Volgograd<+03>-3
Europe/WarsawCET-1CEST,M3.5.0,M10.5.0/3
Europe/ZagrebCET-1CEST,M3.5.0,M10.5.0/3
Europe/ZaporozhyeEET-2EEST,M3.5.0/3,M10.5.0/4
Europe/ZurichCET-1CEST,M3.5.0,M10.5.0/3
Indian/AntananarivoEAT-3
Indian/Chagos<+06>-6
Indian/Christmas<+07>-7
Indian/Cocos<+0630>-6:30
Indian/ComoroEAT-3
Indian/Kerguelen<+05>-5
Indian/Mahe<+04>-4
Indian/Maldives<+05>-5
Indian/Mauritius<+04>-4
Indian/MayotteEAT-3
Indian/Reunion<+04>-4
Pacific/Apia<+13>-13
Pacific/AucklandNZST-12NZDT,M9.5.0,M4.1.0/3
Pacific/Bougainville<+11>-11
Pacific/Chatham<+1245>-12:45<+1345>,M9.5.0/2:45,M4.1.0/3:45
Pacific/Chuuk<+10>-10
Pacific/Easter<-06>6<-05>,M9.1.6/22,M4.1.6/22
Pacific/Efate<+11>-11
Pacific/Enderbury<+13>-13
Pacific/Fakaofo<+13>-13
Pacific/Fiji<+12>-12<+13>,M11.2.0,M1.2.3/99
Pacific/Funafuti<+12>-12
Pacific/Galapagos<-06>6
Pacific/Gambier<-09>9
Pacific/Guadalcanal<+11>-11
Pacific/GuamChST-10
Pacific/HonoluluHST10
Pacific/Kiritimati<+14>-14
Pacific/Kosrae<+11>-11
Pacific/Kwajalein<+12>-12
Pacific/Majuro<+12>-12
Pacific/Marquesas<-0930>9:30
Pacific/MidwaySST11
Pacific/Nauru<+12>-12
Pacific/Niue<-11>11
Pacific/Norfolk<+11>-11<+12>,M10.1.0,M4.1.0/3
Pacific/Noumea<+11>-11
Pacific/Pago_PagoSST11
Pacific/Palau<+09>-9
Pacific/Pitcairn<-08>8
Pacific/Pohnpei<+11>-11
Pacific/Port_Moresby<+10>-10
Pacific/Rarotonga<-10>10
Pacific/SaipanChST-10
Pacific/Tahiti<-10>10
Pacific/Tarawa<+12>-12
Pacific/Tongatapu<+13>-13
Pacific/Wake<+12>-12
Pacific/Wallis<+12>-12
+ +

Source: https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv

+ + + + + + \ No newline at end of file