Каков идеальный способ проверить, готово ли время на ESP8266 через NTP?

С ESP8266 я заметил, что для первых 1 или 2 циклов localtime возвращает эпоху Unix (дата 1970 г.) до тех пор, пока не завершится получение фактического времени из NTP, после чего я вижу реальное время. дата. Иногда может пройти около 10 секунд, прежде чем NTP станет доступен, в зависимости от того, какой сервер времени я использую и как часто я отправляю к нему запросы (похоже, у большинства серверов времени есть регулирование запросов).

Сейчас я проверяю, верна ли дата, проверяя, равен ли год 70, но это кажется странным и хакерским. Есть ли способ лучше? Например, есть ли функция, которая возвращает true, если обновление NTP прошло успешно, или -1, если нет?

Все примеры localtime, которые я нашел до сих пор, похоже, не проверяют правильность даты, и если я запускаю их код, он почти всегда печатает дату эпохи Unix 1970 года. на первом цикле.

#define TIME_SERVER_1 "time.google.com"
#define TIME_SERVER_2 "time.nist.gov"
#define TIME_SERVER_3 "pool.ntp.org"
#define TIMEZONE TZ_Europe_London

void setup() {

// ..

  configTime(TIMEZONE, TIME_SERVER_1, TIME_SERVER_2, TIME_SERVER_3);

// ..

}

void loop() { 

// ..

      time_t now;
      time(&now);
      struct tm* timeinfo = localtime(&now);

      // TODO: может быть, есть лучший способ проверить неизвестное время?
      if (timeinfo->tm_year == 70) {
        TRACE_LN(F("ntp not yet available"));
      } else {
        epoch = mktime(timeinfo);
      }

//..

}

, 👍1

Обсуждение

Разве time() не возвращает -1, если не может получить время? По крайней мере, это то, что он должен делать., @Edgar Bonet

К сожалению, он не возвращает "-1". Когда год равен «70», результатом «время» будет «18» (я думаю, именно столько секунд устройство было в сети). Когда год правильный, возвращается ожидаемая эпоха, например 1670274493., @Nick Bolton

Я думаю, местное время даже начинается днем 31 декабря 1969 года в западном часовом поясе. Таким образом, сравнение местного года с 70-м действительно странный подход. Скорее проверьте необработанное значение time_t., @DataFiddler


4 ответа


Лучший ответ:

3

Вы можете определить функцию обратного вызова, которая срабатывает, когда SNTP обновляет системное время. Пример этого есть на Проект GitHub esp8266/Arduino с кратким описанием в комментариях. Функция обратного вызова регистрируется в примере вызова функции settimeofday_cb(time_is_set), где time_is_set() — это определяемая пользователем функция.

У меня есть приложение (переключатель времени), которое поддерживает индикатор, показывающий, насколько "свежим" является текущий статус времени. Если оно устарело, источник времени возвращается к RTC до тех пор, пока не будет получено новое время. Для этой цели он использует этот механизм обратного вызова.

,

О круто!! Хорошая находка., @Nick Bolton

В конце концов проверил это сегодня, settimeofday_cb отлично работает., @Nick Bolton


3

Если time() не возвращает -1, как ожидалось, когда он не знает, то я не могу предложить ничего более чистого (менее «хакерского»). Что, как говорится, преобразование скалярного времени в разбитое представление относительно дорогая операция. Я предлагаю избегать этого и просто сравнивать возвращаемое время к произвольному порогу:

// Можем ли мы считать это допустимым, так как "текущий" время?
// Если это слишком далеко в прошлом, это определенно недействительно.
static bool is_time_valid(time_t t) {
    const time_t old_past = 1577836800;  // 2020-01-01T00:00:00Z
    return t >= old_past;
}
,

Да! Проверка того, что год равен «70», действительно казалась странной; Я не был уверен, что могу гарантировать, что 1970 год будет Эпохой, и, как вы правильно заметили в комментариях, Эпохой может быть 1969 год в западном часовом поясе., @Nick Bolton


1

Скорее всего, следующий фрагмент кода — лучший способ обеспечить правильное время от NTP. Если вызов timeSetup(...) выполняется после того, как вы уже подключены к Интернету, то это подключение будет использоваться, в противном случае программа установки подключится к Интернету, используя переданные учетные данные, и после завершения получения времени NTP отключится. Код был вырезан/вставлен из более крупного проекта и не тестировался, поэтому могут быть некоторые синтаксические ошибки.

Материал SNTP:

#include "sntp.h"
#include "time.h"
#include <sys/time.h>
#include <WiFi.h>

int WiFiconnectedhere = 0;
int timeIsSet = 0;

// функция time available() не может быть в классе должна быть статической
//функция обратного вызова, когда установлено время
void timeavailable(struct timeval *t)  
{
  struct tm timeinfo;
  Serial.println("NTP notification that time is set");

  if (!getLocalTime(&timeinfo)){
    Serial.println("Using getLocalTime()No time available (yet)");
    return;
  }
  Serial.println(&timeinfo, "using getLocalTime() = %A, %B %d %Y   H:%M:%S");

  if (WiFiconnectedhere == 1) {
    WiFi.disconnect(true, true);  // WiFi выключен, стереть точку доступа
    WiFiconnectedhere = 0;
    Serial.println("WiFi has been disconnected");
  }
  timeIsSet = 1;
}


void ESP32Time::timeSetup(
    char *ssid, 
    char *password, 
    char *ntpServer1,   
    char *ntpServer2, 
    char *timezone)
{
  timeIsSet = 0;
  // подключаемся к WiFi, если еще не подключены
  if (! WiFi.isConnected()) {  //стандартный вызов WiFi для проверки наличия соединения
    sntp_servermode_dhcp(1);    // (необязательный)
    Serial.printf("Connecting to %s in time module\r\n", ssid);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.printf(" CONNECTED to internet %s\r\n", ssid);
    WiFiconnectedhere = 1; // поэтому мы знаем, что нужно отключиться после того, как с ним покончено
  }
  else {
    Serial.println("WiFi is already connected");    
  } 

  // получить обратный вызов, когда время было получено локально
  sntp_set_time_sync_notification_cb( timeavailable ); 

  configTzTime(timezone, ntpServer1, ntpServer2);
  Serial.println("Getting localtime");
  setenv("TZ", timezone, 1);
  tzset();

}

Использование:

ESP32Time esptime;  // Создаем экземпляр класса

В Arduino setup()

//инициализировать время.
esptime.timeSetup(ssid, password, ntpserver1, ntpserver2, timezone);

Получить местное время:

  struct tm timeinfo;
  time_t now;
  time(&now);
  localtime_r(&now, &timeinfo);
  time_t tt = mktime (&timeinfo);

Часовые пояса в используемом программой массиве (извините, что он такой длинный):

#ifndef TZDB_H
#define TZDB_H

typedef struct {
  char tzlit[35];
  char tzzone[45];
} tTimezones;


#ifndef TZARRAY
#define TZARRAY

tTimezones tz[470] =
{
{"TZ_Africa_Abidjan ","GMT0"},
{"TZ_Africa_Accra   " , "GMT0"},
{"TZ_Africa_Addis_Ababa ","EAT-3"},
{"TZ_Africa_Algiers ","CET-1"},
{"TZ_Africa_Asmara  ","EAT-3"},
{"TZ_Africa_Bamako  ","GMT0"},
{"TZ_Africa_Bangui  ","WAT-1"},
{"TZ_Africa_Banjul  ","GMT0"},
{"TZ_Africa_Bissau  ","GMT0"},
{"TZ_Africa_Blantyre    ","CAT-2"},
{"TZ_Africa_Brazzaville ","WAT-1"},
{"TZ_Africa_Bujumbura   ","CAT-2"},
{"TZ_Africa_Cairo   ","EET-2"},
{"TZ_Africa_Casablanca  ","<+01>-1"},
{"TZ_Africa_Ceuta   ","CET-1CEST,M3.5.0,M10.5.0/3"},
{"TZ_Africa_Conakry ","GMT0"},
{"TZ_Africa_Dakar   ","GMT0"},
{"TZ_Africa_Dar_es_Salaam   ","EAT-3"},
{"TZ_Africa_Djibouti    ","EAT-3"},
{"TZ_Africa_Douala  ","WAT-1"},
{"TZ_Africa_El_Aaiun    ","<+01>-1"},
{"TZ_Africa_Freetown    ","GMT0"},
{"TZ_Africa_Gaborone    ","CAT-2"},
{"TZ_Africa_Harare  ","CAT-2"},
{"TZ_Africa_Johannesburg    ","SAST-2"},
{"TZ_Africa_Juba    ","CAT-2"},
{"TZ_Africa_Kampala ","EAT-3"},
{"TZ_Africa_Khartoum    ","CAT-2"},
{"TZ_Africa_Kigali  ","CAT-2"},
{"TZ_Africa_Kinshasa    ","WAT-1"},
{"TZ_Africa_Lagos   ","WAT-1"},
{"TZ_Africa_Libreville  ","WAT-1"},
{"TZ_Africa_Lome    ","GMT0"},
{"TZ_Africa_Luanda  ","WAT-1"},
{"TZ_Africa_Lubumbashi  ","CAT-2"},
{"TZ_Africa_Lusaka  ","CAT-2"},
{"TZ_Africa_Malabo  ","WAT-1"},
{"TZ_Africa_Maputo  ","CAT-2"},
{"TZ_Africa_Maseru  ","SAST-2"},
{"TZ_Africa_Mbabane ","SAST-2"},
{"TZ_Africa_Mogadishu   ","EAT-3"},
{"TZ_Africa_Monrovia    ","GMT0"},
{"TZ_Africa_Nairobi ","EAT-3"},
{"TZ_Africa_Ndjamena    ","WAT-1"},
{"TZ_Africa_Niamey  ","WAT-1"},
{"TZ_Africa_Nouakchott  ","GMT0"},
{"TZ_Africa_Ouagadougou ","GMT0"},
{"TZ_Africa_PortomNovo  ","WAT-1"},
{"TZ_Africa_Sao_Tome    ","GMT0"},
{"TZ_Africa_Tripoli ","EET-2"},
{"TZ_Africa_Tunis   ","CET-1"},
{"TZ_Africa_Windhoek    ","CAT-2"},
{"TZ_America_Adak   ","HST10HDT,M3.2.0,M11.1.0"},
{"TZ_America_Anchorage  ","AKST9AKDT,M3.2.0,M11.1.0"},
{"TZ_America_Anguilla   ","AST4"},
{"TZ_America_Antigua    ","AST4"},
{"TZ_America_Araguaina  ","<-03>3"},
{"TZ_America_Argentina_Buenos_Aires ","<-03>3"},
{"TZ_America_Argentina_Catamarca    ","<-03>3"},
{"TZ_America_Argentina_Cordoba  ","<-03>3"},
{"TZ_America_Argentina_Jujuy    ","<-03>3"},
{"TZ_America_Argentina_La_Rioja ","<-03>3"},
{"TZ_America_Argentina_Mendoza  ","<-03>3"},
{"TZ_America_Argentina_Rio_Gallegos ","<-03>3"},
{"TZ_America_Argentina_Salta    ","<-03>3"},
{"TZ_America_Argentina_San_Juan ","<-03>3"},
{"TZ_America_Argentina_San_Luis ","<-03>3"},
{"TZ_America_Argentina_Tucuman  ","<-03>3"},
{"TZ_America_Argentina_Ushuaia  ","<-03>3"},
{"TZ_America_Aruba  ","AST4"},
{"TZ_America_Asuncion   ","<-04>4<-03>,M10.1.0/0,M3.4.0/0"},
{"TZ_America_Atikokan   ","EST5"},
{"TZ_America_Bahia  ","<-03>3"},
{"TZ_America_Bahia_Banderas ","CST6"},
{"TZ_America_Barbados   ","AST4"},
{"TZ_America_Belem  ","<-03>3"},
{"TZ_America_Belize ","CST6"},
{"TZ_America_BlancmSablon   ","AST4"},
{"TZ_America_Boa_Vista  ","<-04>4"},
{"TZ_America_Bogota ","<-05>5"},
{"TZ_America_Boise  ","MST7MDT,M3.2.0,M11.1.0"},
{"TZ_America_Cambridge_Bay  ","MST7MDT,M3.2.0,M11.1.0"},
{"TZ_America_Campo_Grande   ","<-04>4"},
{"TZ_America_Cancun ","EST5"},
{"TZ_America_Caracas    ","<-04>4"},
{"TZ_America_Cayenne    ","<-03>3"},
{"TZ_America_Cayman ","EST5"},
{"TZ_America_Chicago    ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_Chihuahua  ","CST6"},
{"TZ_America_Costa_Rica ","CST6"},
{"TZ_America_Creston    ","MST7"},
{"TZ_America_Cuiaba ","<-04>4"},
{"TZ_America_Curacao    ","AST4"},
{"TZ_America_Danmarkshavn   ","GMT0"},
{"TZ_America_Dawson ","MST7"},
{"TZ_America_Dawson_Creek   ","MST7"},
{"TZ_America_Denver ","MST7MDT,M3.2.0,M11.1.0"},
{"TZ_America_Detroit    ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Dominica   ","AST4"},
{"TZ_America_Edmonton   ","MST7MDT,M3.2.0,M11.1.0"},
{"TZ_America_Eirunepe   ","<-05>5"},
{"TZ_America_El_Salvador    ","CST6"},
{"TZ_America_Fortaleza  ","<-03>3"},
{"TZ_America_Fort_Nelson    ","MST7"},
{"TZ_America_Glace_Bay  ","AST4ADT,M3.2.0,M11.1.0"},
{"TZ_America_Godthab    ","<-02>2"},
{"TZ_America_Goose_Bay  ","AST4ADT,M3.2.0,M11.1.0"},
{"TZ_America_Grand_Turk ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Grenada    ","AST4"},
{"TZ_America_Guadeloupe ","AST4"},
{"TZ_America_Guatemala  ","CST6"},
{"TZ_America_Guayaquil  ","<-05>5"},
{"TZ_America_Guyana ","<-04>4"},
{"TZ_America_Halifax    ","AST4ADT,M3.2.0,M11.1.0"},
{"TZ_America_Havana ","CST5CDT,M3.2.0/0,M11.1.0/1"},
{"TZ_America_Hermosillo ","MST7"},
{"TZ_America_Indiana_Indianapolis   ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Indiana_Knox   ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_Indiana_Marengo    ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Indiana_Petersburg ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Indiana_Tell_City  ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_Indiana_Vevay  ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Indiana_Vincennes  ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Indiana_Winamac    ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Inuvik ","MST7MDT,M3.2.0,M11.1.0"},
{"TZ_America_Iqaluit    ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Jamaica    ","EST5"},
{"TZ_America_Juneau ","AKST9AKDT,M3.2.0,M11.1.0"},
{"TZ_America_Kentucky_Louisville    ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Kentucky_Monticello    ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Kralendijk ","AST4"},
{"TZ_America_La_Paz ","<-04>4"},
{"TZ_America_Lima   ","<-05>5"},
{"TZ_America_Los_Angeles    ","PST8PDT,M3.2.0,M11.1.0"},
{"TZ_America_Lower_Princes  ","AST4"},
{"TZ_America_Maceio ","<-03>3"},
{"TZ_America_Managua    ","CST6"},
{"TZ_America_Manaus ","<-04>4"},
{"TZ_America_Marigot    ","AST4"},
{"TZ_America_Martinique ","AST4"},
{"TZ_America_Matamoros  ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_Mazatlan   ","MST7"},
{"TZ_America_Menominee  ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_Merida ","CST6"},
{"TZ_America_Metlakatla ","AKST9AKDT,M3.2.0,M11.1.0"},
{"TZ_America_Mexico_City    ","CST6"},
{"TZ_America_Miquelon   ","<-03>3<-02>,M3.2.0,M11.1.0"},
{"TZ_America_Moncton    ","AST4ADT,M3.2.0,M11.1.0"},
{"TZ_America_Monterrey  ","CST6"},
{"TZ_America_Montevideo ","<-03>3"},
{"TZ_America_Montreal   ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Montserrat ","AST4"},
{"TZ_America_Nassau ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_New_York   ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Nipigon    ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Nome   ","AKST9AKDT,M3.2.0,M11.1.0"},
{"TZ_America_Noronha    ","<-02>2"},
{"TZ_America_North_Dakota_Beulah    ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_North_Dakota_Center    ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_North_Dakota_New_Salem ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_Nuuk   ","<-02>2"},
{"TZ_America_Ojinaga    ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_Panama ","EST5"},
{"TZ_America_Pangnirtung    ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Paramaribo ","<-03>3"},
{"TZ_America_Phoenix    ","MST7"},
{"TZ_America_PortmaumPrince ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Port_of_Spain  ","AST4"},
{"TZ_America_Porto_Velho    ","<-04>4"},
{"TZ_America_Puerto_Rico    ","AST4"},
{"TZ_America_Punta_Arenas   ","<-03>3"},
{"TZ_America_Rainy_River    ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_Rankin_Inlet   ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_Recife ","<-03>3"},
{"TZ_America_Regina ","CST6"},
{"TZ_America_Resolute   ","CST6CDT,M3.2.0,M11.1.0"},             
,

-1

Продолжение часовых поясов:

        {"TZ_America_Santarem   ","<-03>3"},
        {"TZ_America_Santiago   ","<-04>4<-03>,M9.1.6/24,M4.1.6/24"},
        {"TZ_America_Santo_Domingo  ","AST4"},
        {"TZ_America_Sao_Paulo  ","<-03>3"},
        {"TZ_America_Scoresbysund   ","<-01>1<+00>,M3.5.0/0,M10.5.0/1"},
        {"TZ_America_Sitka  ","AKST9AKDT,M3.2.0,M11.1.0"},
        {"TZ_America_St_Barthelemy  ","AST4"},
        {"TZ_America_St_Johns   ","NST3:30NDT,M3.2.0,M11.1.0"},
        {"TZ_America_St_Kitts   ","AST4"},
        {"TZ_America_St_Lucia   ","AST4"},
        {"TZ_America_St_Thomas  ","AST4"},
        {"TZ_America_St_Vincent ","AST4"},
        {"TZ_America_Swift_Current  ","CST6"},
        {"TZ_America_Tegucigalpa    ","CST6"},
        {"TZ_America_Thule  ","AST4ADT,M3.2.0,M11.1.0"},
        {"TZ_America_Thunder_Bay    ","EST5EDT,M3.2.0,M11.1.0"},
        {"TZ_America_Tijuana    ","PST8PDT,M3.2.0,M11.1.0"},
        {"TZ_America_Toronto    ","EST5EDT,M3.2.0,M11.1.0"},
        {"TZ_America_Tortola    ","AST4"},
        {"TZ_America_Vancouver  ","PST8PDT,M3.2.0,M11.1.0"},
        {"TZ_America_Whitehorse ","MST7"},
        {"TZ_America_Winnipeg   ","CST6CDT,M3.2.0,M11.1.0"},
        {"TZ_America_Yakutat    ","AKST9AKDT,M3.2.0,M11.1.0"},
        {"TZ_America_Yellowknife    ","MST7MDT,M3.2.0,M11.1.0"},
        {"TZ_Antarctica_Casey   ","<+11>-11"},
        {"TZ_Antarctica_Davis   ","<+07>-7"},
        {"TZ_Antarctica_DumontDUrville  ","<+10>-10"},
        {"TZ_Antarctica_Macquarie   ","AEST-10AEDT,M10.1.0,M4.1.0/3"},
        {"TZ_Antarctica_Mawson  ","<+05>-5"},
        {"TZ_Antarctica_McMurdo ","NZST-12NZDT,M9.5.0,M4.1.0/3"},
        {"TZ_Antarctica_Palmer  ","<-03>3"},
        {"TZ_Antarctica_Rothera ","<-03>3"},
        {"TZ_Antarctica_Syowa   ","<+03>-3"},
        {"TZ_Antarctica_Troll   ","<+00>0<+02>-2,M3.5.0/1,M10.5.0/3"},
        {"TZ_Antarctica_Vostok  ","<+06>-6"},
        {"TZ_Arctic_Longyearbyen    ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Asia_Aden  ","<+03>-3"},
        {"TZ_Asia_Almaty    ","<+06>-6"},
        {"TZ_Asia_Amman ","<+03>-3"},
        {"TZ_Asia_Anadyr    ","<+12>-12"},
        {"TZ_Asia_Aqtau ","<+05>-5"},
        {"TZ_Asia_Aqtobe    ","<+05>-5"},
        {"TZ_Asia_Ashgabat  ","<+05>-5"},
        {"TZ_Asia_Atyrau    ","<+05>-5"},
        {"TZ_Asia_Baghdad   ","<+03>-3"},
        {"TZ_Asia_Bahrain   ","<+03>-3"},
        {"TZ_Asia_Baku  ","<+04>-4"},
        {"TZ_Asia_Bangkok   ","<+07>-7"},
        {"TZ_Asia_Barnaul   ","<+07>-7"},
        {"TZ_Asia_Beirut    ","EET-2EEST,M3.5.0/0,M10.5.0/0"},
        {"TZ_Asia_Bishkek   ","<+06>-6"},
        {"TZ_Asia_Brunei    ","<+08>-8"},
        {"TZ_Asia_Chita ","<+09>-9"},
        {"TZ_Asia_Choibalsan    ","<+08>-8"},
        {"TZ_Asia_Colombo   ","<+0530>-5:30"},
        {"TZ_Asia_Damascus  ","<+03>-3"},
        {"TZ_Asia_Dhaka ","<+06>-6"},
        {"TZ_Asia_Dili  ","<+09>-9"},
        {"TZ_Asia_Dubai ","<+04>-4"},
        {"TZ_Asia_Dushanbe  ","<+05>-5"},
        {"TZ_Asia_Famagusta ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Asia_Gaza  ","EET-2EEST,M3.4.4/50,M10.4.4/50"},
        {"TZ_Asia_Hebron    ","EET-2EEST,M3.4.4/50,M10.4.4/50"},
        {"TZ_Asia_Ho_Chi_Minh   ","<+07>-7"},
        {"TZ_Asia_Hong_Kong ","HKT-8"},
        {"TZ_Asia_Hovd  ","<+07>-7"},
        {"TZ_Asia_Irkutsk   ","<+08>-8"},
        {"TZ_Asia_Jakarta   ","WIB-7"},
        {"TZ_Asia_Jayapura  ","WIT-9"},
        {"TZ_Asia_Jerusalem ","IST-2IDT,M3.4.4/26,M10.5.0"},
        {"TZ_Asia_Kabul ","<+0430>-4:30"},
        {"TZ_Asia_Kamchatka ","<+12>-12"},
        {"TZ_Asia_Karachi   ","PKT-5"},
        {"TZ_Asia_Kathmandu ","<+0545>-5:45"},
        {"TZ_Asia_Khandyga  ","<+09>-9"},
        {"TZ_Asia_Kolkata   ","IST-5:30"},
        {"TZ_Asia_Krasnoyarsk   ","<+07>-7"},
        {"TZ_Asia_Kuala_Lumpur  ","<+08>-8"},
        {"TZ_Asia_Kuching   ","<+08>-8"},
        {"TZ_Asia_Kuwait    ","<+03>-3"},
        {"TZ_Asia_Macau ","CST-8"},
        {"TZ_Asia_Magadan   ","<+11>-11"},
        {"TZ_Asia_Makassar  ","WITA-8"},
        {"TZ_Asia_Manila    ","PST-8"},
        {"TZ_Asia_Muscat    ","<+04>-4"},
        {"TZ_Asia_Nicosia   ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Asia_Novokuznetsk  ","<+07>-7"},
        {"TZ_Asia_Novosibirsk   ","<+07>-7"},
        {"TZ_Asia_Omsk  ","<+06>-6"},
        {"TZ_Asia_Oral  ","<+05>-5"},
        {"TZ_Asia_Phnom_Penh    ","<+07>-7"},
        {"TZ_Asia_Pontianak ","WIB-7"},
        {"TZ_Asia_Pyongyang ","KST-9"},
        {"TZ_Asia_Qatar ","<+03>-3"},
        {"TZ_Asia_Qyzylorda ","<+05>-5"},
        {"TZ_Asia_Riyadh    ","<+03>-3"},
        {"TZ_Asia_Sakhalin  ","<+11>-11"},
        {"TZ_Asia_Samarkand ","<+05>-5"},
        {"TZ_Asia_Seoul ","KST-9"},
        {"TZ_Asia_Shanghai  ","CST-8"},
        {"TZ_Asia_Singapore ","<+08>-8"},
        {"TZ_Asia_Srednekolymsk ","<+11>-11"},
        {"TZ_Asia_Taipei    ","CST-8"},
        {"TZ_Asia_Tashkent  ","<+05>-5"},
        {"TZ_Asia_Tbilisi   ","<+04>-4"},
        {"TZ_Asia_Tehran    ","<+0330>-3:30"},
        {"TZ_Asia_Thimphu   ","<+06>-6"},
        {"TZ_Asia_Tokyo ","JST-9"},
        {"TZ_Asia_Tomsk ","<+07>-7"},
        {"TZ_Asia_Ulaanbaatar   ","<+08>-8"},
        {"TZ_Asia_Urumqi    ","<+06>-6"},
        {"TZ_Asia_UstmNera  ","<+10>-10"},
        {"TZ_Asia_Vientiane ","<+07>-7"},
        {"TZ_Asia_Vladivostok   ","<+10>-10"},
        {"TZ_Asia_Yakutsk   ","<+09>-9"},
        {"TZ_Asia_Yangon    ","<+0630>-6:30"},
        {"TZ_Asia_Yekaterinburg ","<+05>-5"},
        {"TZ_Asia_Yerevan   ","<+04>-4"},
        {"TZ_Atlantic_Azores    ","<-01>1<+00>,M3.5.0/0,M10.5.0/1"},
        {"TZ_Atlantic_Bermuda   ","AST4ADT,M3.2.0,M11.1.0"},
        {"TZ_Atlantic_Canary    ","WET0WEST,M3.5.0/1,M10.5.0"},
        {"TZ_Atlantic_Cape_Verde    ","<-01>1"},
        {"TZ_Atlantic_Faroe ","WET0WEST,M3.5.0/1,M10.5.0"},
        {"TZ_Atlantic_Madeira   ","WET0WEST,M3.5.0/1,M10.5.0"},
        {"TZ_Atlantic_Reykjavik ","GMT0"},
        {"TZ_Atlantic_South_Georgia ","<-02>2"},
        {"TZ_Atlantic_Stanley   ","<-03>3"},
        {"TZ_Atlantic_St_Helena ","GMT0"},
        {"TZ_Australia_Adelaide ","ACST-9:30ACDT,M10.1.0,M4.1.0/3"},
        {"TZ_Australia_Brisbane ","AEST-10"},
        {"TZ_Australia_Broken_Hill  ","ACST-9:30ACDT,M10.1.0,M4.1.0/3"},
        {"TZ_Australia_Currie   ","AEST-10AEDT,M10.1.0,M4.1.0/3"},
        {"TZ_Australia_Darwin   ","ACST-9:30"},
        {"TZ_Australia_Eucla    ","<+0845>-8:45"},
        {"TZ_Australia_Hobart   ","AEST-10AEDT,M10.1.0,M4.1.0/3"},
        {"TZ_Australia_Lindeman ","AEST-10"},
        {"TZ_Australia_Lord_Howe    ","<+1030>-10:30<+11>-11,M10.1.0,M4.1.0"},
        {"TZ_Australia_Melbourne    ","AEST-10AEDT,M10.1.0,M4.1.0/3"},
        {"TZ_Australia_Perth    ","AWST-8"},
        {"TZ_Australia_Sydney   ","AEST-10AEDT,M10.1.0,M4.1.0/3"},
        {"TZ_Europe_Amsterdam   ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Andorra ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Astrakhan   ","<+04>-4"},
        {"TZ_Europe_Athens  ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Belgrade    ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Berlin  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Bratislava  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Brussels    ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Bucharest   ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Budapest    ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Busingen    ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Chisinau    ","EET-2EEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Copenhagen  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Dublin  ","IST-1GMT0,M10.5.0,M3.5.0/1"},
        {"TZ_Europe_Gibraltar   ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Guernsey    ","GMT0BST,M3.5.0/1,M10.5.0"},
        {"TZ_Europe_Helsinki    ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Isle_of_Man ","GMT0BST,M3.5.0/1,M10.5.0"},
        {"TZ_Europe_Istanbul    ","<+03>-3"},
        {"TZ_Europe_Jersey  ","GMT0BST,M3.5.0/1,M10.5.0"},
        {"TZ_Europe_Kaliningrad ","EET-2"},
        {"TZ_Europe_Kiev    ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Kirov   ","<+03>-3"},
        {"TZ_Europe_Lisbon  ","WET0WEST,M3.5.0/1,M10.5.0"},
        {"TZ_Europe_Ljubljana   ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_London  ","GMT0BST,M3.5.0/1,M10.5.0"},
        {"TZ_Europe_Luxembourg  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Madrid  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Malta   ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Mariehamn   ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Minsk   ","<+03>-3"},
        {"TZ_Europe_Monaco  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Moscow  ","MSK-3"},
        {"TZ_Europe_Oslo    ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Paris   ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Podgorica   ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Prague  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Riga    ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Rome    ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Samara  ","<+04>-4"},
        {"TZ_Europe_San_Marino  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Sarajevo    ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Saratov ","<+04>-4"},
        {"TZ_Europe_Simferopol  ","MSK-3"},
        {"TZ_Europe_Skopje  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Sofia   ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Stockholm   ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Tallinn ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Tirane  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Ulyanovsk   ","<+04>-4"},
        {"TZ_Europe_Uzhgorod    ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Vaduz   ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Vatican ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Vienna  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Vilnius ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Volgograd   ","<+03>-3"},
        {"TZ_Europe_Warsaw  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Zagreb  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Zaporozhye  ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Zurich  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Indian_Antananarivo    ","EAT-3"},
        {"TZ_Indian_Chagos  ","<+06>-6"},
        {"TZ_Indian_Christmas   ","<+07>-7"},
        {"TZ_Indian_Cocos   ","<+0630>-6:30"},
        {"TZ_Indian_Comoro  ","EAT-3"},
        {"TZ_Indian_Kerguelen   ","<+05>-5"},
        {"TZ_Indian_Mahe    ","<+04>-4"},
        {"TZ_Indian_Maldives    ","<+05>-5"},
        {"TZ_Indian_Mauritius   ","<+04>-4"},
        {"TZ_Indian_Mayotte ","EAT-3"},
        {"TZ_Indian_Reunion ","<+04>-4"},
        {"TZ_Pacific_Apia   ","<+13>-13"},
        {"TZ_Pacific_Auckland   ","NZST-12NZDT,M9.5.0,M4.1.0/3"},
        {"TZ_Pacific_Bougainville   ","<+11>-11"},
        {"TZ_Pacific_Chatham    ","<+1245>-12:45<+1345>,M9.5.0/2:45,M4.1.0/3:45"},
        {"TZ_Pacific_Chuuk  ","<+10>-10"},
        {"TZ_Pacific_Easter ","<-06>6<-05>,M9.1.6/22,M4.1.6/22"},
        {"TZ_Pacific_Efate  ","<+11>-11"},
        {"TZ_Pacific_Enderbury  ","<+13>-13"},
        {"TZ_Pacific_Fakaofo    ","<+13>-13"},
        {"TZ_Pacific_Fiji   ","<+12>-12"},
        {"TZ_Pacific_Funafuti   ","<+12>-12"},
        {"TZ_Pacific_Galapagos  ","<-06>6"},
        {"TZ_Pacific_Gambier    ","<-09>9"},
        {"TZ_Pacific_Guadalcanal    ","<+11>-11"},
        {"TZ_Pacific_Guam   ","ChST-10"},
        {"TZ_Pacific_Honolulu   ","HST10"},
        {"TZ_Pacific_Kiritimati ","<+14>-14"},
        {"TZ_Pacific_Kosrae ","<+11>-11"},
        {"TZ_Pacific_Kwajalein  ","<+12>-12"},
        {"TZ_Pacific_Majuro ","<+12>-12"},
        {"TZ_Pacific_Marquesas  ","<-0930>9:30"},
        {"TZ_Pacific_Midway ","SST11"},
        {"TZ_Pacific_Nauru  ","<+12>-12"},
        {"TZ_Pacific_Niue   ","<-11>11"},
        {"TZ_Pacific_Norfolk    ","<+11>-11<+12>,M10.1.0,M4.1.0/3"},
        {"TZ_Pacific_Noumea ","<+11>-11"},
        {"TZ_Pacific_Pago_Pago  ","SST11"},
        {"TZ_Pacific_Palau  ","<+09>-9"},
        {"TZ_Pacific_Pitcairn   ","<-08>8"},
        {"TZ_Pacific_Pohnpei    ","<+11>-11"},
        {"TZ_Pacific_Port_Moresby   ","<+10>-10"},
        {"TZ_Pacific_Rarotonga  ","<-10>10"},
        {"TZ_Pacific_Saipan ","ChST-10"},
        {"TZ_Pacific_Tahiti ","<-10>10"},
        {"TZ_Pacific_Tarawa ","<+12>-12"},
        {"TZ_Pacific_Tongatapu  ","<+13>-13"},
        {"TZ_Pacific_Wake   ","<+12>-12"},
        {"TZ_Pacific_Wallis ","<+12>-12"},
        {"TZ_Etc_GMT    ","GMT0"},
        {"TZ_Etc_GMTm0  ","GMT0"},
        {"TZ_Etc_GMTm1  ","<+01>-1"},
        {"TZ_Etc_GMTm2  ","<+02>-2"},
        {"TZ_Etc_GMTm3  ","<+03>-3"},
        {"TZ_Etc_GMTm4  ","<+04>-4"},
        {"TZ_Etc_GMTm5  ","<+05>-5"},
        {"TZ_Etc_GMTm6  ","<+06>-6"},
        {"TZ_Etc_GMTm7  ","<+07>-7"},
        {"TZ_Etc_GMTm8  ","<+08>-8"},
        {"TZ_Etc_GMTm9  ","<+09>-9"},
        {"TZ_Etc_GMTm10 ","<+10>-10"},
        {"TZ_Etc_GMTm11 ","<+11>-11"},
        {"TZ_Etc_GMTm12 ","<+12>-12"},
        {"TZ_Etc_GMTm13 ","<+13>-13"},
        {"TZ_Etc_GMTm14 ","<+14>-14"},
        {"TZ_Etc_GMT0   ","GMT0"},
        {"TZ_Etc_GMTp0  ","GMT0"},
        {"TZ_Etc_GMTp1  ","<-01>1"},
        {"TZ_Etc_GMTp2  ","<-02>2"},
        {"TZ_Etc_GMTp3  ","<-03>3"},
        {"TZ_Etc_GMTp4  ","<-04>4"},
        {"TZ_Etc_GMTp5  ","<-05>5"},
        {"TZ_Etc_GMTp6  ","<-06>6"},
        {"TZ_Etc_GMTp7  ","<-07>7"},
        {"TZ_Etc_GMTp8  ","<-08>8"},
        {"TZ_Etc_GMTp9  ","<-09>9"},
        {"TZ_Etc_GMTp10 ","<-10>10"},
        {"TZ_Etc_GMTp11 ","<-11>11"},
        {"TZ_Etc_GMTp12 ","<-12>12"},
        {"TZ_Etc_UCT    ","UTC0"},
        {"TZ_Etc_UTC    ","UTC0"},
        {"TZ_Etc_Greenwich  ","GMT0"},
        {"TZ_Etc_Universal  ","UTC0"},
        {"TZ_Etc_Zulu   ","UTC0"},
        {"EOF", "eof"}
        };

        char *getTimeZoneLit(int tzindex) {
          return(tz[tzindex].tzlit);
        }
        char *getTimeZone(int tzindex) {
          return(tz[tzindex].tzzone);
        }

        #endif // TZDB_H
        #endif
,

Почему уценка. Эта база данных является авторитетной базой данных. Обратите внимание, что массив начинается в предыдущем посте. Я не знаю, как добавить его в качестве загружаемого файла, и мне пришлось разделить его, чтобы он соответствовал ограничениям размера сообщения., @shumifan49