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);
}
//..
}
4 Answers 4
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.
-
Oh awesome!! Nice find.Nick Bolton– Nick Bolton2022年12月08日 13:02:08 +00:00Commented Dec 8, 2022 at 13:02
-
Eventually tested this today,
settimeofday_cb
works great.Nick Bolton– Nick Bolton2023年02月02日 17:06:42 +00:00Commented Feb 2, 2023 at 17:06
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月01日T00:00:00Z
return t >= old_past;
}
-
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.Nick Bolton– Nick Bolton2022年12月06日 11:06:08 +00:00Commented Dec 6, 2022 at 11:06
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"},
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
-
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– shumifan492023年04月07日 13:32:31 +00:00Commented Apr 7, 2023 at 13:32
time()
return −1 if it cannot get the time? At least that is what it is supposed to do.-1
. When the year is70
, the result fromtime
is18
(I guess that's how many seconds the device has been online). When the year is valid, it returns expected epoch, e.g.1670274493
.