From 2331525a328eef63d1f31f69ccf2daa4ac6bcde2 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 24 Feb 2022 12:19:51 +0800 Subject: [PATCH] timezone --- include/common/tglobal.h | 1 - include/common/tmsg.h | 6 +- include/dnode/mgmt/dnode.h | 6 +- include/libs/config/config.h | 1 + include/os/os.h | 1 + include/os/osEnv.h | 18 ++- include/os/osSysinfo.h | 8 +- include/os/osTimezone.h | 30 +++++ source/client/src/clientEnv.c | 14 +- source/common/src/tglobal.c | 1 - source/dnode/mgmt/daemon/src/dmnCfg.c | 10 +- source/dnode/mgmt/impl/src/dndMgmt.c | 6 +- source/libs/parser/src/insertParser.c | 2 +- source/libs/parser/src/parserImpl.c | 2 +- source/libs/parser/src/parserUtil.c | 2 +- source/os/src/osEnv.c | 56 ++++---- source/os/src/osSysinfo.c | 138 ++----------------- source/os/src/osTimeZone.c | 187 ++++++++++++++++++++++---- 18 files changed, 275 insertions(+), 214 deletions(-) create mode 100644 include/os/osTimezone.h diff --git a/include/common/tglobal.h b/include/common/tglobal.h index 8d73ea005d..bb704f1536 100644 --- a/include/common/tglobal.h +++ b/include/common/tglobal.h @@ -23,7 +23,6 @@ extern "C" { #include "tdef.h" // common -extern int8_t tsDaylight; extern int32_t tsCompressMsgSize; extern int32_t tsCompressColData; extern int32_t tsMaxNumOfDistinctResults; diff --git a/include/common/tmsg.h b/include/common/tmsg.h index ae3586e735..9ab78f3c96 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -656,9 +656,9 @@ int32_t tDeserializeSRetrieveFuncRsp(void* buf, int32_t bufLen, SRetrieveFuncRsp typedef struct { int32_t statusInterval; int64_t checkTime; // 1970-01-01 00:00:00.000 - char timezone[TSDB_TIMEZONE_LEN]; // tsTimezone - char locale[TSDB_LOCALE_LEN]; // tsLocale - char charset[TSDB_LOCALE_LEN]; // tsCharset + char timezone[TD_TIMEZONE_LEN]; // tsTimezone + char locale[TD_LOCALE_LEN]; // tsLocale + char charset[TD_LOCALE_LEN]; // tsCharset } SClusterCfg; typedef struct { diff --git a/include/dnode/mgmt/dnode.h b/include/dnode/mgmt/dnode.h index 5d6c869b4d..d630fd0b1a 100644 --- a/include/dnode/mgmt/dnode.h +++ b/include/dnode/mgmt/dnode.h @@ -34,9 +34,9 @@ typedef struct { bool printAuth; int32_t rpcTimer; int32_t rpcMaxTime; - char timezone[TSDB_TIMEZONE_LEN]; - char locale[TSDB_LOCALE_LEN]; - char charset[TSDB_LOCALE_LEN]; + char timezone[TD_TIMEZONE_LEN]; + char locale[TD_LOCALE_LEN]; + char charset[TD_LOCALE_LEN]; char buildinfo[64]; char gitinfo[48]; } SDnodeEnvCfg; diff --git a/include/libs/config/config.h b/include/libs/config/config.h index 3c9ec1e3bf..594c258648 100644 --- a/include/libs/config/config.h +++ b/include/libs/config/config.h @@ -80,6 +80,7 @@ int32_t cfgGetSize(SConfig *pCfg); SConfigItem *cfgIterate(SConfig *pCfg, SConfigItem *pIter); void cfgCancelIterate(SConfig *pCfg, SConfigItem *pIter); SConfigItem *cfgGetItem(SConfig *pCfg, const char *name); +int32_t cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcType stype); int32_t cfgAddBool(SConfig *pCfg, const char *name, bool defaultVal); int32_t cfgAddInt32(SConfig *pCfg, const char *name, int32_t defaultVal, int64_t minval, int64_t maxval); diff --git a/include/os/os.h b/include/os/os.h index 023d2b0470..7b478c3137 100644 --- a/include/os/os.h +++ b/include/os/os.h @@ -73,6 +73,7 @@ extern "C" { #include "osThread.h" #include "osTime.h" #include "osTimer.h" +#include "osTimezone.h" void osInit(); diff --git a/include/os/osEnv.h b/include/os/osEnv.h index ba3dbcbc83..ca38ca19fb 100644 --- a/include/os/osEnv.h +++ b/include/os/osEnv.h @@ -26,10 +26,14 @@ typedef struct SEnvVar { char dataDir[PATH_MAX]; char logDir[PATH_MAX]; char tempDir[PATH_MAX]; - char osName[16]; SDiskSpace dataSpace; SDiskSpace logSpace; SDiskSpace tempSpace; + char osName[16]; + char timezone[TD_TIMEZONE_LEN]; + char locale[TD_LOCALE_LEN]; + char charset[TD_CHARSET_LEN]; + int8_t daylight; } SEnvVar; extern char configDir[]; @@ -38,10 +42,14 @@ void osInit(); SEnvVar *osEnv(); void osUpdate(); bool osLogSpaceAvailable(); -char * osLogDir(); -char * osTempDir(); -char * osDataDir(); -char * osName(); +char *osLogDir(); +char *osTempDir(); +char *osDataDir(); +char *osName(); +char *osTimezone(); +int8_t osDaylight(); + +void osSetTimezone(const char*timezone); #ifdef __cplusplus } diff --git a/include/os/osSysinfo.h b/include/os/osSysinfo.h index 6ab2a104df..3780131cda 100644 --- a/include/os/osSysinfo.h +++ b/include/os/osSysinfo.h @@ -21,9 +21,10 @@ extern "C" { #endif #include "os.h" - -#define TSDB_LOCALE_LEN 64 -#define TSDB_TIMEZONE_LEN 96 + +#define TD_LOCALE_LEN 64 +#define TD_CHARSET_LEN 64 +#define TD_TIMEZONE_LEN 96 typedef struct { int64_t total; @@ -41,7 +42,6 @@ extern int64_t tsOpenMax; extern int64_t tsStreamMax; extern int32_t tsNumOfCores; extern int32_t tsTotalMemoryMB; -extern char tsTimezone[]; extern char tsLocale[]; extern char tsCharset[]; // default encode string diff --git a/include/os/osTimezone.h b/include/os/osTimezone.h new file mode 100644 index 0000000000..6bf52a4108 --- /dev/null +++ b/include/os/osTimezone.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef _TD_OS_TIMEZONE_H_ +#define _TD_OS_TIMEZONE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void osGetSystemTimezone(char *outTimezone); +void osSetSystemTimezone(const char *inTimezone, char *outTimezone, int8_t *outDaylight); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_OS_SOCKET_H_*/ diff --git a/source/client/src/clientEnv.c b/source/client/src/clientEnv.c index 1ab05f53f3..eeb9b110c5 100644 --- a/source/client/src/clientEnv.c +++ b/source/client/src/clientEnv.c @@ -300,7 +300,7 @@ int taos_options_imp(TSDB_OPTION option, const char *str) { assert(cfg != NULL); size_t len = strlen(str); - if (len == 0 || len > TSDB_LOCALE_LEN) { + if (len == 0 || len > TD_LOCALE_LEN) { tscInfo("Invalid locale:%s, use default", str); return -1; } @@ -318,7 +318,7 @@ int taos_options_imp(TSDB_OPTION option, const char *str) { return -1; } - tstrncpy(tsLocale, defaultLocale, TSDB_LOCALE_LEN); + tstrncpy(tsLocale, defaultLocale, TD_LOCALE_LEN); } // set the user specified locale @@ -332,7 +332,7 @@ int taos_options_imp(TSDB_OPTION option, const char *str) { tscInfo("failed to set locale:%s, current locale:%s", str, tsLocale); } - tstrncpy(tsLocale, locale, TSDB_LOCALE_LEN); + tstrncpy(tsLocale, locale, TD_LOCALE_LEN); char *charset = strrchr(tsLocale, sep); if (charset != NULL) { @@ -347,7 +347,7 @@ int taos_options_imp(TSDB_OPTION option, const char *str) { tscInfo("charset changed from %s to %s", tsCharset, charset); } - tstrncpy(tsCharset, charset, TSDB_LOCALE_LEN); + tstrncpy(tsCharset, charset, TD_LOCALE_LEN); cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION; } else { @@ -371,7 +371,7 @@ int taos_options_imp(TSDB_OPTION option, const char *str) { assert(cfg != NULL); size_t len = strlen(str); - if (len == 0 || len > TSDB_LOCALE_LEN) { + if (len == 0 || len > TD_LOCALE_LEN) { tscInfo("failed to set charset:%s", str); return -1; } @@ -384,7 +384,7 @@ int taos_options_imp(TSDB_OPTION option, const char *str) { tscInfo("charset changed from %s to %s", tsCharset, str); } - tstrncpy(tsCharset, str, TSDB_LOCALE_LEN); + tstrncpy(tsCharset, str, TD_LOCALE_LEN); cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION; } else { tscInfo("charset:%s not valid", str); @@ -402,7 +402,7 @@ int taos_options_imp(TSDB_OPTION option, const char *str) { assert(cfg != NULL); if (cfg->cfgStatus <= TAOS_CFG_CSTATUS_OPTION) { - tstrncpy(tsTimezone, str, TSDB_TIMEZONE_LEN); + tstrncpy(tsTimezone, str, TD_TIMEZONE_LEN); tsSetTimeZone(); cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION; tscDebug("timezone set:%s, input:%s by taos_options", tsTimezone, str); diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 25da197b87..5946232c85 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -29,7 +29,6 @@ // common -int8_t tsDaylight = 0; int32_t tsMaxBinaryDisplayWidth = 30; int8_t tsEnableSlaveQuery = 1; int8_t tsEnableAdjustMaster = 1; diff --git a/source/dnode/mgmt/daemon/src/dmnCfg.c b/source/dnode/mgmt/daemon/src/dmnCfg.c index 83bc66ab84..b09866fa7b 100644 --- a/source/dnode/mgmt/daemon/src/dmnCfg.c +++ b/source/dnode/mgmt/daemon/src/dmnCfg.c @@ -87,17 +87,25 @@ static int32_t dmnAddDnodeCfg(SConfig *pCfg) { return 0; } +static void dmnSetDnodeCfg(SConfig *pCfg) { + SConfigItem *pItem = cfgGetItem(pCfg, "timezone"); + osSetTimezone(pItem->str); + uDebug("timezone format changed from %s to %s", pItem->str, osTimezone()); + cfgSetItem(pCfg, "timezone", osTimezone(), pItem->stype); +} + static int32_t dmnCheckCfg(SConfig *pCfg) { bool enableCore = cfgGetItem(pCfg, "enableCoreFile")->bval; taosSetCoreDump(enableCore); + dmnSetDnodeCfg(pCfg); + if (dmnCheckDirCfg(pCfg) != 0) { return -1; } taosGetSystemInfo(); - tsSetTimeZone(); tsSetLocale(); if (tsNumOfCores <= 0) { diff --git a/source/dnode/mgmt/impl/src/dndMgmt.c b/source/dnode/mgmt/impl/src/dndMgmt.c index 1748c52c66..b7f42fb465 100644 --- a/source/dnode/mgmt/impl/src/dndMgmt.c +++ b/source/dnode/mgmt/impl/src/dndMgmt.c @@ -371,9 +371,9 @@ void dndSendStatusReq(SDnode *pDnode) { req.clusterCfg.checkTime = 0; char timestr[32] = "1970-01-01 00:00:00.00"; (void)taosParseTime(timestr, &req.clusterCfg.checkTime, (int32_t)strlen(timestr), TSDB_TIME_PRECISION_MILLI, 0); - memcpy(req.clusterCfg.timezone, pDnode->env.timezone, TSDB_TIMEZONE_LEN); - memcpy(req.clusterCfg.locale, pDnode->env.locale, TSDB_LOCALE_LEN); - memcpy(req.clusterCfg.charset, pDnode->env.charset, TSDB_LOCALE_LEN); + memcpy(req.clusterCfg.timezone, pDnode->env.timezone, TD_TIMEZONE_LEN); + memcpy(req.clusterCfg.locale, pDnode->env.locale, TD_LOCALE_LEN); + memcpy(req.clusterCfg.charset, pDnode->env.charset, TD_LOCALE_LEN); taosRUnLockLatch(&pMgmt->latch); req.pVloads = taosArrayInit(TSDB_MAX_VNODES, sizeof(SVnodeLoad)); diff --git a/source/libs/parser/src/insertParser.c b/source/libs/parser/src/insertParser.c index 745982e869..a88f679655 100644 --- a/source/libs/parser/src/insertParser.c +++ b/source/libs/parser/src/insertParser.c @@ -204,7 +204,7 @@ static int parseTime(char **end, SToken *pToken, int16_t timePrec, int64_t *time bool isSigned = false; toInteger(pToken->z, pToken->n, 10, &ts, &isSigned); } else { // parse the RFC-3339/ISO-8601 timestamp format string - if (taosParseTime(pToken->z, time, pToken->n, timePrec, tsDaylight) != TSDB_CODE_SUCCESS) { + if (taosParseTime(pToken->z, time, pToken->n, timePrec, osDaylight()) != TSDB_CODE_SUCCESS) { return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z); } diff --git a/source/libs/parser/src/parserImpl.c b/source/libs/parser/src/parserImpl.c index ef040fdff4..8e29f66c57 100644 --- a/source/libs/parser/src/parserImpl.c +++ b/source/libs/parser/src/parserImpl.c @@ -578,7 +578,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) { return DEAL_RES_ERROR; } int32_t len = trimStringCopy(pVal->literal, n, tmp); - if (taosParseTime(tmp, &pVal->datum.i, len, pVal->node.resType.precision, tsDaylight) != TSDB_CODE_SUCCESS) { + if (taosParseTime(tmp, &pVal->datum.i, len, pVal->node.resType.precision, osDaylight()) != TSDB_CODE_SUCCESS) { tfree(tmp); generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); return DEAL_RES_ERROR; diff --git a/source/libs/parser/src/parserUtil.c b/source/libs/parser/src/parserUtil.c index ec68980c44..2647806e03 100644 --- a/source/libs/parser/src/parserUtil.c +++ b/source/libs/parser/src/parserUtil.c @@ -1639,7 +1639,7 @@ static int parseTime(char **end, SToken *pToken, int16_t timePrec, int64_t *time bool isSigned = false; toInteger(pToken->z, pToken->n, 10, &ts, &isSigned); } else { // parse the RFC-3339/ISO-8601 timestamp format string - if (taosParseTime(pToken->z, time, pToken->n, timePrec, tsDaylight) != TSDB_CODE_SUCCESS) { + if (taosParseTime(pToken->z, time, pToken->n, timePrec, osDaylight()) != TSDB_CODE_SUCCESS) { return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z); } diff --git a/source/os/src/osEnv.c b/source/os/src/osEnv.c index 7949eb053e..1c85a6aac2 100644 --- a/source/os/src/osEnv.c +++ b/source/os/src/osEnv.c @@ -15,12 +15,41 @@ #define _DEFAULT_SOURCE #include "osEnv.h" -#include "os.h" -#include "osSysinfo.h" SEnvVar env = {0}; char configDir[PATH_MAX] = {0}; +SEnvVar *osEnv() { return &env; } + +void osInitImp() { + osGetSystemTimezone(env.timezone); + osSetTimezone(env.timezone); +} + +void osUpdate() { + if (env.logDir[0] != 0) { + taosGetDiskSize(env.logDir, &env.logSpace.size); + } + if (env.dataDir[0] != 0) { + taosGetDiskSize(env.dataDir, &env.dataSpace.size); + } + if (env.tempDir[0] != 0) { + taosGetDiskSize(env.tempDir, &env.tempSpace.size); + } +} + +bool osLogSpaceAvailable() { return env.logSpace.reserved < env.logSpace.size.avail; } + +char *osLogDir() { return env.logDir; } +char *osTempDir() { return env.tempDir; } +char *osDataDir() { return env.dataDir; } +char *osName() { return env.osName; } +char *osTimezone() { return env.timezone; } + +int8_t osDaylight() { return env.daylight; } + +void osSetTimezone(const char *timezone) { osSetSystemTimezone(timezone, env.timezone, &env.daylight); } + #if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) extern taosWinSocketInit(); @@ -65,25 +94,4 @@ void osInit() { strcpy(env.osName, "Linux"); } -#endif - -SEnvVar *osEnv() { return &env; } - -void osUpdate() { - if (env.logDir[0] != 0) { - taosGetDiskSize(env.logDir, &env.logSpace.size); - } - if (env.dataDir[0] != 0) { - taosGetDiskSize(env.dataDir, &env.dataSpace.size); - } - if (env.tempDir[0] != 0) { - taosGetDiskSize(env.tempDir, &env.tempSpace.size); - } -} - -bool osLogSpaceAvailable() { return env.logSpace.reserved < env.logSpace.size.avail; } - -char *osLogDir() { return env.logDir; } -char *osTempDir() { return env.tempDir; } -char *osDataDir() { return env.dataDir; } -char *osName() { return env.osName; } +#endif \ No newline at end of file diff --git a/source/os/src/osSysinfo.c b/source/os/src/osSysinfo.c index d223a3d5a6..439a8146ab 100644 --- a/source/os/src/osSysinfo.c +++ b/source/os/src/osSysinfo.c @@ -21,9 +21,8 @@ int64_t tsPageSize = 0; int64_t tsOpenMax = 0; int64_t tsStreamMax = 0; int32_t tsNumOfCores = 1; -char tsTimezone[TSDB_TIMEZONE_LEN] = {0}; -char tsLocale[TSDB_LOCALE_LEN] = {0}; -char tsCharset[TSDB_LOCALE_LEN] = {0}; // default encode string +char tsLocale[TD_LOCALE_LEN] = {0}; +char tsCharset[TD_LOCALE_LEN] = {0}; // default encode string #if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) @@ -89,21 +88,13 @@ bool taosGetProcMemory(float *memoryUsedMB) { return true; } -static void taosGetSystemTimezone() { - // get and set default timezone - char *tz = getenv("TZ"); - if (tz == NULL || strlen(tz) == 0) { - strcpy(tsTimezone, "not configured"); - } else { - strcpy(tsTimezone, tz); - } -} + static void taosGetSystemLocale() { // get and set default locale char *locale = setlocale(LC_CTYPE, "chs"); if (locale != NULL) { - tstrncpy(tsLocale, locale, TSDB_LOCALE_LEN); + tstrncpy(tsLocale, locale, TD_LOCALE_LEN); } strcpy(tsCharset, "cp936"); @@ -200,7 +191,6 @@ void taosGetSystemInfo() { taosGetCpuUsage(&tmp1, &tmp2); taosGetProcIO(&tmp1, &tmp2); - taosGetSystemTimezone(); taosGetSystemLocale(); } @@ -273,57 +263,6 @@ char *taosGetCmdlineByPID(int pid) { return ""; } #include #include -static void taosGetSystemTimezone() { - /* load time zone string from /etc/localtime */ - char buf[4096]; - char *tz = NULL; - { - int n = readlink("/etc/localtime", buf, sizeof(buf)); - if (n < 0) { - //printf("read /etc/localtime error, reason:%s", strerror(errno)); - return; - } - buf[n] = '\0'; - for (int i = n - 1; i >= 0; --i) { - if (buf[i] == '/') { - if (tz) { - tz = buf + i + 1; - break; - } - tz = buf + i + 1; - } - } - if (!tz || 0 == strchr(tz, '/')) { - //printf("parsing /etc/localtime failed"); - return; - } - - setenv("TZ", tz, 1); - tzset(); - } - - /* - * NOTE: do not remove it. - * Enforce set the correct daylight saving time(DST) flag according - * to current time - */ - time_t tx1 = time(NULL); - struct tm tm1; - localtime_r(&tx1, &tm1); - - /* - * format example: - * - * Asia/Shanghai (CST, +0800) - * Europe/London (BST, +0100) - */ - snprintf(tsTimezone, TSDB_TIMEZONE_LEN, "%s (%s, %+03ld00)", tz, tm1.tm_isdst ? tzname[daylight] : tzname[0], - -timezone / 3600); - - // cfg_timezone->cfgStatus = TAOS_CFG_CSTATUS_DEFAULT; - //printf("timezone not configured, set to system default:%s", tsTimezone); -} - /* * originally from src/os/src/detail/osSysinfo.c * POSIX format locale string: @@ -351,7 +290,7 @@ static void taosGetSystemLocale() { // get and set default locale //printf("can't get locale from system, set it to en_US.UTF-8 since error:%d:%s", errno, strerror(errno)); strcpy(tsLocale, "en_US.UTF-8"); } else { - tstrncpy(tsLocale, locale, TSDB_LOCALE_LEN); + tstrncpy(tsLocale, locale, TD_LOCALE_LEN); //printf("locale not configured, set to system default:%s", tsLocale); } @@ -361,7 +300,7 @@ static void taosGetSystemLocale() { // get and set default locale str++; char *revisedCharset = taosCharsetReplace(str); - tstrncpy(tsCharset, revisedCharset, TSDB_LOCALE_LEN); + tstrncpy(tsCharset, revisedCharset, TD_LOCALE_LEN); free(revisedCharset); //printf("charset not configured, set to system default:%s", tsCharset); @@ -387,7 +326,6 @@ void taosGetSystemInfo() { tsTotalMemoryMB = physical_pages * page_size / (1024 * 1024); tsPageSize = page_size; - taosGetSystemTimezone(); taosGetSystemLocale(); } @@ -625,65 +563,6 @@ static bool taosGetProcCpuInfo(ProcCpuInfo *cpuInfo) { return true; } -static void taosGetSystemTimezone() { - /* - * NOTE: do not remove it. - * Enforce set the correct daylight saving time(DST) flag according - * to current time - */ - time_t tx1 = time(NULL); - struct tm tm1; - localtime_r(&tx1, &tm1); - - /* load time zone string from /etc/timezone */ - FILE *f = fopen("/etc/timezone", "r"); - char buf[68] = {0}; - if (f != NULL) { - int len = fread(buf, 64, 1, f); - if (len < 64 && ferror(f)) { - fclose(f); - //printf("read /etc/timezone error, reason:%s", strerror(errno)); - return; - } - - fclose(f); - - buf[sizeof(buf) - 1] = 0; - char *lineEnd = strstr(buf, "\n"); - if (lineEnd != NULL) { - *lineEnd = 0; - } - - // for CentOS system, /etc/timezone does not exist. Ignore the TZ environment variables - if (strlen(buf) > 0) { - setenv("TZ", buf, 1); - } - } - // get and set default timezone - tzset(); - - /* - * get CURRENT time zone. - * system current time zone is affected by daylight saving time(DST) - * - * e.g., the local time zone of London in DST is GMT+01:00, - * otherwise is GMT+00:00 - */ - int32_t tz = (-timezone * MILLISECOND_PER_SECOND) / MILLISECOND_PER_HOUR; - tz += daylight; - - /* - * format example: - * - * Asia/Shanghai (CST, +0800) - * Europe/London (BST, +0100) - */ - snprintf(tsTimezone, TSDB_TIMEZONE_LEN, "%s (%s, %s%02d00)", buf, tzname[daylight], tz >= 0 ? "+" : "-", abs(tz)); - - // cfg_timezone->cfgStatus = TAOS_CFG_CSTATUS_DEFAULT; - //printf("timezone not configured, set to system default:%s", tsTimezone); -} - /* * POSIX format locale string: * (Language Strings)_(Country/Region Strings).(code_page) @@ -710,7 +589,7 @@ static void taosGetSystemLocale() { // get and set default locale //printf("can't get locale from system, set it to en_US.UTF-8 since error:%d:%s", errno, strerror(errno)); strcpy(tsLocale, "en_US.UTF-8"); } else { - tstrncpy(tsLocale, locale, TSDB_LOCALE_LEN); + tstrncpy(tsLocale, locale, TD_LOCALE_LEN); //printf("locale not configured, set to system default:%s", tsLocale); } @@ -720,7 +599,7 @@ static void taosGetSystemLocale() { // get and set default locale str++; char *revisedCharset = taosCharsetReplace(str); - tstrncpy(tsCharset, revisedCharset, TSDB_LOCALE_LEN); + tstrncpy(tsCharset, revisedCharset, TD_LOCALE_LEN); free(revisedCharset); //printf("charset not configured, set to system default:%s", tsCharset); @@ -957,7 +836,6 @@ void taosGetSystemInfo() { taosGetCpuUsage(&tmp1, &tmp2); taosGetProcIO(&tmp1, &tmp2); - taosGetSystemTimezone(); taosGetSystemLocale(); } diff --git a/source/os/src/osTimeZone.c b/source/os/src/osTimeZone.c index da40e14389..84e86662d3 100644 --- a/source/os/src/osTimeZone.c +++ b/source/os/src/osTimeZone.c @@ -15,40 +15,59 @@ #define _DEFAULT_SOURCE #include "os.h" -// #include "ulog.h" -// #include "tglobal.h" -// #include "tutil.h" -// TODO refactor to set the tz value through parameter -void tsSetTimeZone() { -#if 0 - SGlobalCfg *cfg_timezone = taosGetConfigOption("timezone"); - if (cfg_timezone != NULL) { - uInfo("timezone is set to %s by %s", tsTimezone, tsCfgStatusStr[cfg_timezone->cfgStatus]); - } +#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) +#if (_WIN64) +#include +#include +#include +#include +#include +#include +#pragma comment(lib, "Mswsock.lib ") +#endif +#include +#pragma warning(push) +#pragma warning(disable : 4091) +#include +#pragma warning(pop) +#elif defined(_TD_DARWIN_64) +#include +#include +#else +#include +#include +#include +#include +#include +#include +#include +#include +#endif +void osSetSystemTimezone(const char *inTimezone, char *outTimezone, int8_t *outDaylight) { #ifdef WINDOWS - char winStr[TSDB_LOCALE_LEN * 2]; - sprintf(winStr, "TZ=%s", tsTimezone); + char winStr[TD_LOCALE_LEN * 2]; + sprintf(winStr, "TZ=%s", inTimezone); putenv(winStr); #else - setenv("TZ", tsTimezone, 1); + setenv("TZ", inTimezone, 1); #endif tzset(); /* - * get CURRENT time zone. - * system current time zone is affected by daylight saving time(DST) - * - * e.g., the local time zone of London in DST is GMT+01:00, - * otherwise is GMT+00:00 - */ + * get CURRENT time zone. + * system current time zone is affected by daylight saving time(DST) + * + * e.g., the local time zone of London in DST is GMT+01:00, + * otherwise is GMT+00:00 + */ #ifdef _MSC_VER #if _MSC_VER >= 1900 // see https://docs.microsoft.com/en-us/cpp/c-runtime-library/daylight-dstbias-timezone-and-tzname?view=vs-2019 int64_t timezone = _timezone; int32_t daylight = _daylight; - char **tzname = _tzname; + char **tzname = _tzname; #endif #endif @@ -56,14 +75,124 @@ void tsSetTimeZone() { tz += daylight; /* - * format: - * (CST, +0800) - * (BST, +0100) - */ - sprintf(tsTimezone, "(%s, %s%02d00)", tzname[daylight], tz >= 0 ? "+" : "-", abs(tz)); - tsDaylight = daylight; + * format: + * (CST, +0800) + * (BST, +0100) + */ - uInfo("timezone format changed to %s", tsTimezone); - -#endif + sprintf(outTimezone, "(%s, %s%02d00)", tzname[daylight], tz >= 0 ? "+" : "-", abs(tz)); + *outDaylight = daylight; +} + +void osGetSystemTimezone(char *outTimezone) { +#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) + char *tz = getenv("TZ"); + if (tz == NULL || strlen(tz) == 0) { + strcpy(outTimezone, "not configured"); + } else { + strcpy(outTimezone, tz); + } + +#elif defined(_TD_DARWIN_64) + char buf[4096] = {0}; + char *tz = NULL; + { + int n = readlink("/etc/localtime", buf, sizeof(buf)); + if (n < 0) { + printf("read /etc/localtime error, reason:%s", strerror(errno)); + return; + } + buf[n] = '\0'; + for (int i = n - 1; i >= 0; --i) { + if (buf[i] == '/') { + if (tz) { + tz = buf + i + 1; + break; + } + tz = buf + i + 1; + } + } + if (!tz || 0 == strchr(tz, '/')) { + printf("parsing /etc/localtime failed"); + return; + } + + setenv("TZ", tz, 1); + tzset(); + } + + /* + * NOTE: do not remove it. + * Enforce set the correct daylight saving time(DST) flag according + * to current time + */ + time_t tx1 = time(NULL); + struct tm tm1; + localtime_r(&tx1, &tm1); + + /* + * format example: + * + * Asia/Shanghai (CST, +0800) + * Europe/London (BST, +0100) + */ + snprintf(outTimezone, TD_TIMEZONE_LEN, "%s (%s, %+03ld00)", tz, tm1.tm_isdst ? tzname[daylight] : tzname[0], + -timezone / 3600); + +#else + /* + * NOTE: do not remove it. + * Enforce set the correct daylight saving time(DST) flag according + * to current time + */ + time_t tx1 = time(NULL); + struct tm tm1; + localtime_r(&tx1, &tm1); + + /* load time zone string from /etc/timezone */ + FILE *f = fopen("/etc/timezone", "r"); + char buf[68] = {0}; + if (f != NULL) { + int len = fread(buf, 64, 1, f); + if (len < 64 && ferror(f)) { + fclose(f); + // printf("read /etc/timezone error, reason:%s", strerror(errno)); + return; + } + + fclose(f); + + buf[sizeof(buf) - 1] = 0; + char *lineEnd = strstr(buf, "\n"); + if (lineEnd != NULL) { + *lineEnd = 0; + } + + // for CentOS system, /etc/timezone does not exist. Ignore the TZ environment variables + if (strlen(buf) > 0) { + setenv("TZ", buf, 1); + } + } + // get and set default timezone + tzset(); + + /* + * get CURRENT time zone. + * system current time zone is affected by daylight saving time(DST) + * + * e.g., the local time zone of London in DST is GMT+01:00, + * otherwise is GMT+00:00 + */ + int32_t tz = (-timezone * MILLISECOND_PER_SECOND) / MILLISECOND_PER_HOUR; + tz += daylight; + + /* + * format example: + * + * Asia/Shanghai (CST, +0800) + * Europe/London (BST, +0100) + */ + snprintf(outTimezone, TD_TIMEZONE_LEN, "%s (%s, %s%02d00)", buf, tzname[daylight], tz >= 0 ? "+" : "-", abs(tz)); + +#endif }