1

With ESP8266, I noticed that for the first 1 or 2 loops, localtime returns Unix epoch (1970 date) until it has finished getting the actual time from NTP, after which point I see the real date. Sometimes it can take 10 seconds or so before NTP is available, depending on what time server I use and how frequently I make requests to it (most time servers have request throttling, it seems).

Right now, I'm checking whether the date is valid by testing if the year is 70 but this seems weird and hacky. Is there a better way? For instance, is there a function that returns true if the NTP update has been successful or -1 if not?

All of the examples of localtime that I have found so far don't seem to check if the date is valid, and if I run their code, it almost always prints the 1970 Unix epoch date on the first loop.

#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: maybe there's a better way to check unknown time?
      if (timeinfo->tm_year == 70) {
        TRACE_LN(F("ntp not yet available"));
      } else {
        epoch = mktime(timeinfo);
      }

//..

}
3
  • Doesn't time() return −1 if it cannot get the time? At least that is what it is supposed to do. Dec 5, 2022 at 21:01
  • Unfortunately, it doesn't seem to return -1. When the year is 70, the result from time is 18 (I guess that's how many seconds the device has been online). When the year is valid, it returns expected epoch, e.g. 1670274493. Dec 5, 2022 at 21:09
  • I guess, localtime even starts at 31-Dec-1969 afternoon in a western time zone. Thus comparing the local year with 70 is really a strange approach. Rather test the raw time_t value. Dec 5, 2022 at 22:05

4 Answers 4

3

You can define a call back function which is triggered when SNTP updates the system time. There is an example of it on the GitHub esp8266/Arduino project with a short description in the comments. The call back function is registered by the example function call settimeofday_cb(time_is_set) where time_is_set() is a user defined funtion.

I have an application (a timeswitch) which maintains an indicator to show how 'fresh' the current time status is. If it is stale, the time source reverts to an RTC until a new time can be fetched. It uses this callback mechanism for that purpose.

2
  • Oh awesome!! Nice find. Dec 8, 2022 at 13:02
  • Eventually tested this today, settimeofday_cb works great. Feb 2, 2023 at 17:06
3

If time() doesn't return -1 as expected when it doesn't know, then I have nothing cleaner (less “hacky”) to suggest. That being said, converting the scalar time to a broken-down representation is a relatively expensive operation. I suggest avoiding it and just comparing the returned time to an arbitrary threshold:

// May we consider this valid as the "current" time?
// If it is too far in the past, it is centainly not valid.
static bool is_time_valid(time_t t) {
    const time_t old_past = 1577836800;  // 2020-01-01T00:00:00Z
    return t >= old_past;
}
1
  • Yes! Checking if year is 70 did feel really strange indeed; I wasn't convinced that I could guarantee 1970 being Epoch, and as you rightly say in the comments, Epoch could be 1969 in a western time zone. Dec 6, 2022 at 11:06
1

The following code snippet is most likely the best way of ensuring valid time from NTP. If the call to timeSetup(...) is made after already connected to the internet, then that connection will be used, otherwise the setup will connect to internet, using passed in credetials, and when finished getting NTP time, will disconnect. The code has been cut/pasted from a much bigger project and has not been tested, so there might be some syntax errors.

The SNTP stuff:

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

int WiFiconnectedhere = 0;
int timeIsSet = 0;

// timeavailable() cannot be in a class has to be static
//callback function when time has been set
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 off, erase AP
    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;
  //connect to WiFi if not already connected
  if (! WiFi.isConnected()) {  //standard WiFi call to check if connected
    sntp_servermode_dhcp(1);    // (optional)
    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; // so we know to disconnect after done with it
  }
  else {
    Serial.println("WiFi is already connected");    
  } 

  // get a callback when time has been received locally
  sntp_set_time_sync_notification_cb( timeavailable ); 

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

}

Usage:

ESP32Time esptime;  // Instantiate the class

In arduino setup()

//initialise the time.
esptime.timeSetup(ssid, password, ntpserver1, ntpserver2, timezone);

Retrieve local time:

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

The timezones in a program usable array (sorry it is so long):

#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

Continuation of timezones:

        {"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
1
  • Why the markdown. This database is the authoritative database. Please note that the array starts in the previous post. I don't know how to add it as a downloadable file and had to split it to fit the post size limitations.
    – shumifan49
    Apr 7, 2023 at 13:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.