feat:[TD-32642] add timezone logic
This commit is contained in:
parent
3156eed774
commit
7aef49638e
|
@ -635,7 +635,7 @@ if(${TD_LINUX} AND ${BUILD_WITH_S3})
|
|||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND make TZDIR=${SHARE_OUTPUT_PATH}/timezone all posix_only
|
||||
COMMAND make TZDIR=${SHARE_OUTPUT_PATH}/timezone clean all posix_only
|
||||
WORKING_DIRECTORY "${TD_CONTRIB_DIR}/tz"
|
||||
)
|
||||
|
||||
|
|
|
@ -64,6 +64,14 @@ typedef enum {
|
|||
TSDB_MAX_OPTIONS
|
||||
} TSDB_OPTION;
|
||||
|
||||
typedef enum {
|
||||
TSDB_OPTION_CONNECTION_CHARSET, // charset, Same as the scope supported by the system
|
||||
TSDB_OPTION_CONNECTION_TIMEZONE, // timezone, Same as the scope supported by the system
|
||||
TSDB_OPTION_CONNECTION_USER_IP, // user ip
|
||||
TSDB_OPTION_CONNECTION_USER_APP, // user app
|
||||
TSDB_MAX_CONNECTION_OPTIONS = 100
|
||||
} TSDB_OPTION_CONNECTION;
|
||||
|
||||
typedef enum {
|
||||
TSDB_OPTION_CONNECT_CHARSET,
|
||||
TSDB_OPTION_CONNECT_TIMEZONE,
|
||||
|
@ -166,7 +174,7 @@ typedef struct TAOS_STMT_OPTIONS {
|
|||
|
||||
DLL_EXPORT void taos_cleanup(void);
|
||||
DLL_EXPORT int taos_options(TSDB_OPTION option, const void *arg, ...);
|
||||
DLL_EXPORT int taos_options_connect(TAOS *taos, TSDB_OPTION_CONNECT option, const void *arg, ...);
|
||||
DLL_EXPORT int taos_options_connection(TAOS *taos, TSDB_OPTION_CONNECTION option, const void *arg, ...);
|
||||
DLL_EXPORT setConfRet taos_set_config(const char *config);
|
||||
DLL_EXPORT int taos_init(void);
|
||||
DLL_EXPORT TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port);
|
||||
|
|
|
@ -81,7 +81,7 @@ int32_t taosTimeCountIntervalForFill(int64_t skey, int64_t ekey, int64_t interva
|
|||
int32_t parseAbsoluteDuration(const char* token, int32_t tokenlen, int64_t* ts, char* unit, int32_t timePrecision);
|
||||
int32_t parseNatualDuration(const char* token, int32_t tokenLen, int64_t* duration, char* unit, int32_t timePrecision, bool negativeAllow);
|
||||
|
||||
int32_t taosParseTime(const char* timestr, int64_t* pTime, int32_t len, int32_t timePrec, int8_t dayligth);
|
||||
int32_t taosParseTime(const char* timestr, int64_t* pTime, int32_t len, int32_t timePrec);
|
||||
void deltaToUtcInitOnce();
|
||||
char getPrecisionUnit(int32_t precision);
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#define epoll_create EPOLL_CREATE_FUNC_TAOS_FORBID
|
||||
#define epoll_ctl EPOLL_CTL_FUNC_TAOS_FORBID
|
||||
#define epoll_wait EPOLL_WAIT_FUNC_TAOS_FORBID
|
||||
#define inet_addr INET_ADDR_FUNC_TAOS_FORBID
|
||||
#define inet_ntoa INET_NTOA_FUNC_TAOS_FORBID
|
||||
#endif
|
||||
|
||||
|
@ -55,10 +54,11 @@
|
|||
#define __BIG_ENDIAN BIG_ENDIAN
|
||||
#define __LITTLE_ENDIAN LITTLE_ENDIAN
|
||||
#define __PDP_ENDIAN PDP_ENDIAN
|
||||
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#if defined(_TD_DARWIN_64)
|
||||
#include <osEok.h>
|
||||
|
@ -163,7 +163,6 @@ int32_t taosBlockSIGPIPE();
|
|||
int32_t taosGetIpv4FromFqdn(const char *fqdn, uint32_t *ip);
|
||||
int32_t taosGetFqdn(char *);
|
||||
void tinet_ntoa(char *ipstr, uint32_t ip);
|
||||
uint32_t ip2uint(const char *const ip_addr);
|
||||
int32_t taosIgnSIGPIPE();
|
||||
const char *taosInetNtoa(struct in_addr ipInt, char *dstStr, int32_t len);
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ extern "C" {
|
|||
#define MILLISECOND_PER_SECOND ((int64_t)1000LL)
|
||||
#endif
|
||||
|
||||
#include "osTimezone.h"
|
||||
#define MILLISECOND_PER_MINUTE (MILLISECOND_PER_SECOND * 60)
|
||||
#define MILLISECOND_PER_HOUR (MILLISECOND_PER_MINUTE * 60)
|
||||
#define MILLISECOND_PER_DAY (MILLISECOND_PER_HOUR * 24)
|
||||
|
@ -98,6 +99,8 @@ time_t taosMktime(struct tm *timep);
|
|||
int64_t user_mktime64(const uint32_t year, const uint32_t mon, const uint32_t day, const uint32_t hour,
|
||||
const uint32_t min, const uint32_t sec, int64_t time_zone);
|
||||
|
||||
struct tm *taosLocalTimeRz(timezone_t state, const time_t *timep, struct tm *result);
|
||||
time_t taosMktimeRz(timezone_t state, struct tm *timep);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1160,13 +1160,7 @@ struct tzhead {
|
|||
# define TZDEFAULT "/etc/localtime" /* default zone */
|
||||
#endif
|
||||
#ifndef TZDIR
|
||||
# define TZDIR "/usr/local/share/timezone" /* TZif directory */
|
||||
#endif
|
||||
|
||||
// If the error is in a third-party library, place this header file under the third-party library header file.
|
||||
// When you want to use this feature, you should find or add the same function in the following section.
|
||||
#ifndef ALLOW_FORBID_FUNC
|
||||
#define tzset TZSET_FUNC_TAOS_FORBID
|
||||
# define TZDIR "/Users/mingmingwanng/source_code/TDengine/debug/build/share/timezone" /* TZif directory */
|
||||
#endif
|
||||
|
||||
enum TdTimezone {
|
||||
|
@ -1197,9 +1191,13 @@ enum TdTimezone {
|
|||
TdEastZone12
|
||||
};
|
||||
|
||||
int32_t taosGetSystemTimezone(char *outTimezone, enum TdTimezone *tsTimezone);
|
||||
int32_t taosSetSystemTimezone(const char *inTimezone, char *outTimezone, int8_t *outDaylight, enum TdTimezone *tsTimezone);
|
||||
void getTimezoneStr(char *tz);
|
||||
|
||||
|
||||
int32_t taosGetSystemTimezone(char *outTimezone);
|
||||
int32_t taosSetGlobalTimezone(const char *tz);
|
||||
int32_t taosFormatTimezoneStr(time_t t, const char* tzStr, timezone_t sp, char *outTimezoneStr);
|
||||
int32_t taosIsValidateTimezone(const char *tz);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1023,6 +1023,9 @@ int32_t taosGetErrSize();
|
|||
#define TSDB_CODE_AUDIT_FAIL_SEND_AUDIT_RECORD TAOS_DEF_ERROR_CODE(0, 0x6101)
|
||||
#define TSDB_CODE_AUDIT_FAIL_GENERATE_JSON TAOS_DEF_ERROR_CODE(0, 0x6102)
|
||||
|
||||
//TIMEZONE
|
||||
#define TSDB_CODE_INVALID_TIMEZONE TAOS_DEF_ERROR_CODE(0, 0x6200)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -34,7 +34,8 @@ typedef enum {
|
|||
CFG_STYPE_APOLLO_URL,
|
||||
CFG_STYPE_ARG_LIST,
|
||||
CFG_STYPE_TAOS_OPTIONS,
|
||||
CFG_STYPE_ALTER_CMD,
|
||||
CFG_STYPE_ALTER_CLIENT_CMD,
|
||||
CFG_STYPE_ALTER_SERVER_CMD,
|
||||
} ECfgSrcType;
|
||||
|
||||
typedef enum {
|
||||
|
|
|
@ -48,11 +48,6 @@ int32_t taosHexStrToByteArray(char hexstr[], char bytes[]);
|
|||
int32_t tintToHex(uint64_t val, char hex[]);
|
||||
int32_t titoa(uint64_t val, size_t radix, char str[]);
|
||||
|
||||
char *taosIpStr(uint32_t ipInt);
|
||||
uint32_t ip2uint(const char *const ip_addr);
|
||||
void taosIp2String(uint32_t ip, char *str);
|
||||
void taosIpPort2String(uint32_t ip, uint16_t port, char *str);
|
||||
|
||||
void *tmemmem(const char *haystack, int hlen, const char *needle, int nlen);
|
||||
|
||||
int32_t parseCfgReal(const char *str, float *out);
|
||||
|
|
|
@ -149,11 +149,11 @@ typedef struct {
|
|||
} SWhiteListInfo;
|
||||
|
||||
typedef struct {
|
||||
// TIMEZONE *tz;
|
||||
char charset[TD_LOCALE_LEN];
|
||||
timezone_t timezone;
|
||||
char charset[TD_CHARSET_LEN];
|
||||
char app[TSDB_APP_NAME_LEN];
|
||||
uint32_t ip;
|
||||
}optionInfo;
|
||||
}SOptionInfo;
|
||||
|
||||
typedef struct STscObj {
|
||||
char user[TSDB_USER_LEN];
|
||||
|
@ -177,6 +177,7 @@ typedef struct STscObj {
|
|||
SPassInfo passInfo;
|
||||
SWhiteListInfo whiteListInfo;
|
||||
STscNotifyInfo userDroppedInfo;
|
||||
SOptionInfo optionInfo;
|
||||
} STscObj;
|
||||
|
||||
typedef struct STscDbg {
|
||||
|
@ -341,6 +342,7 @@ extern int32_t clientReqRefPool;
|
|||
extern int32_t clientConnRefPool;
|
||||
extern int32_t timestampDeltaLimit;
|
||||
extern int64_t lastClusterId;
|
||||
extern SHashObj* pTimezoneMap;
|
||||
|
||||
__async_send_cb_fn_t getMsgRspHandle(int32_t msgType);
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ int64_t lastClusterId = 0;
|
|||
int32_t clientReqRefPool = -1;
|
||||
int32_t clientConnRefPool = -1;
|
||||
int32_t clientStop = -1;
|
||||
SHashObj* pTimezoneMap = NULL;
|
||||
|
||||
int32_t timestampDeltaLimit = 900; // s
|
||||
|
||||
|
|
|
@ -51,6 +51,103 @@ int taos_options(TSDB_OPTION option, const void *arg, ...) {
|
|||
atomic_store_32(&lock, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t setConnectionOption(TAOS *taos, TSDB_OPTION_CONNECTION option, const char* val){
|
||||
if (taos == NULL) {
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
}
|
||||
|
||||
if (option != TSDB_MAX_CONNECTION_OPTIONS && (option < TSDB_OPTION_CONNECTION_CHARSET && option > TSDB_OPTION_CONNECTION_USER_APP)){
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
}
|
||||
|
||||
STscObj *pObj = acquireTscObj(*(int64_t *)taos);
|
||||
if (NULL == pObj) {
|
||||
tscError("invalid parameter for %s", __func__);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
int32_t code = 0;
|
||||
if (option == TSDB_OPTION_CONNECTION_CHARSET) {
|
||||
if (val != NULL) {
|
||||
if (!taosValidateEncodec(val)) {
|
||||
code = terrno;
|
||||
goto END;
|
||||
}
|
||||
tstrncpy(pObj->optionInfo.charset, val, TD_CHARSET_LEN);
|
||||
}else{
|
||||
pObj->optionInfo.charset[0] = 0;
|
||||
}
|
||||
} else if (option == TSDB_OPTION_CONNECTION_TIMEZONE) {
|
||||
if (val != NULL){
|
||||
if (strlen(val) == 0){
|
||||
code = TSDB_CODE_INVALID_PARA;
|
||||
goto END;
|
||||
}
|
||||
timezone_t *tmp = taosHashGet(pTimezoneMap, val, strlen(val));
|
||||
if (tmp && *tmp){
|
||||
pObj->optionInfo.timezone = *tmp;
|
||||
goto END;
|
||||
}
|
||||
|
||||
tscDebug("set timezone to %s", val);
|
||||
timezone_t tz = tzalloc(val);
|
||||
if (!tz) {
|
||||
tscError("%s unknown timezone %s", __func__, val);
|
||||
code = TAOS_SYSTEM_ERROR(errno);
|
||||
goto END;
|
||||
}
|
||||
code = taosHashPut(pTimezoneMap, val, strlen(val), &tz, sizeof(timezone_t));
|
||||
if (code != 0){
|
||||
tzfree(tz);
|
||||
goto END;
|
||||
}
|
||||
pObj->optionInfo.timezone = tz;
|
||||
} else {
|
||||
pObj->optionInfo.timezone = NULL;
|
||||
}
|
||||
} else if (option == TSDB_OPTION_CONNECTION_USER_APP) {
|
||||
if (val != NULL) {
|
||||
tstrncpy(pObj->optionInfo.app, val, TSDB_APP_NAME_LEN);
|
||||
} else {
|
||||
pObj->optionInfo.app[0] = 0;
|
||||
}
|
||||
} else if (option == TSDB_OPTION_CONNECTION_USER_IP) {
|
||||
if (val != NULL) {
|
||||
pObj->optionInfo.ip = inet_addr(val);
|
||||
} else {
|
||||
pObj->optionInfo.ip = 0;
|
||||
}
|
||||
}
|
||||
|
||||
END:
|
||||
releaseTscObj(*(int64_t *)taos);
|
||||
return code;
|
||||
}
|
||||
|
||||
int taos_options_connection(TAOS *taos, TSDB_OPTION_CONNECTION option, const void *arg, ...){
|
||||
static int32_t lock_c = 0;
|
||||
|
||||
for (int i = 1; atomic_val_compare_exchange_32(&lock_c, 0, 1) != 0; ++i) {
|
||||
if (i % 1000 == 0) {
|
||||
tscInfo("haven't acquire lock after spin %d times.", i);
|
||||
(void)sched_yield();
|
||||
}
|
||||
}
|
||||
|
||||
if (pTimezoneMap == NULL){
|
||||
pTimezoneMap = taosHashInit(0, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
|
||||
if (pTimezoneMap == NULL) {
|
||||
atomic_store_32(&lock_c, 0);
|
||||
return terrno;
|
||||
}
|
||||
taosHashSetFreeFp(pTimezoneMap, (_hash_free_fn_t)tzfree);
|
||||
}
|
||||
int ret = setConnectionOption(taos, option, (const char *)arg);
|
||||
atomic_store_32(&lock_c, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// this function may be called by user or system, or by both simultaneously.
|
||||
void taos_cleanup(void) {
|
||||
tscDebug("start to cleanup client environment");
|
||||
|
|
|
@ -1610,4 +1610,159 @@ TEST(clientCase, timezone_Test) {
|
|||
}
|
||||
}
|
||||
|
||||
time_t time_winter = 1731323281; // 2024-11-11 19:08:01+0800
|
||||
time_t time_summer = 1731323281 - 120 * 24 * 60 * 60;
|
||||
|
||||
struct test_times
|
||||
{
|
||||
const char *name;
|
||||
time_t t;
|
||||
const char *timezone;
|
||||
} test_tz[] = {
|
||||
{"", time_winter, " (UTC, +0000)"},
|
||||
{"America/New_York", time_winter, "America/New_York (EST, -0500)"}, // 2024-11-11 19:08:01+0800
|
||||
{"America/New_York", time_summer, "America/New_York (EDT, -0400)"},
|
||||
{"Asia/Kolkata", time_winter, "Asia/Kolkata (IST, +0530)"},
|
||||
{"Asia/Shanghai", time_winter, "Asia/Shanghai (CST, +0800)"},
|
||||
{"Europe/London", time_winter, "Europe/London (GMT, +0000)"},
|
||||
{"Europe/London", time_summer, "Europe/London (BST, +0100)"}
|
||||
};
|
||||
|
||||
void timezone_str_test(const char* tz, time_t t, const char* tzStr) {
|
||||
int code = setenv("TZ", tz, 1);
|
||||
ASSERT(-1 != code);
|
||||
tzset();
|
||||
|
||||
char str1[TD_TIMEZONE_LEN] = {0};
|
||||
ASSERT(taosFormatTimezoneStr(t, tz, NULL, str1) == 0);
|
||||
ASSERT_STREQ(str1, tzStr);
|
||||
}
|
||||
|
||||
void timezone_rz_str_test(const char* tz, time_t t, const char* tzStr) {
|
||||
timezone_t sp = tzalloc(tz);
|
||||
ASSERT(sp);
|
||||
|
||||
char str1[TD_TIMEZONE_LEN] = {0};
|
||||
ASSERT(taosFormatTimezoneStr(t, tz, sp, str1) == 0);
|
||||
ASSERT_STREQ(str1, tzStr);
|
||||
tzfree(sp);
|
||||
}
|
||||
|
||||
TEST(clientCase, format_timezone_Test) {
|
||||
for (unsigned int i = 0; i < sizeof (test_tz) / sizeof (test_tz[0]); ++i){
|
||||
timezone_str_test(test_tz[i].name, test_tz[i].t, test_tz[i].timezone);
|
||||
timezone_str_test(test_tz[i].name, test_tz[i].t, test_tz[i].timezone);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(clientCase, get_tz_Test) {
|
||||
{
|
||||
char tz[TD_TIMEZONE_LEN] = {0};
|
||||
getTimezoneStr(tz);
|
||||
ASSERT_STREQ(tz, "Asia/Shanghai");
|
||||
|
||||
// getTimezoneStr(tz);
|
||||
// ASSERT_STREQ(tz, "Asia/Shanghai");
|
||||
//
|
||||
// getTimezoneStr(tz);
|
||||
// ASSERT_STREQ(tz, "n/a");
|
||||
}
|
||||
}
|
||||
|
||||
struct {
|
||||
const char * env;
|
||||
time_t expected;
|
||||
} test_mk[] = {
|
||||
{"MST", 832935315},
|
||||
{"", 832910115},
|
||||
{":UTC", 832910115},
|
||||
{"UTC", 832910115},
|
||||
{"UTC0", 832910115}
|
||||
};
|
||||
|
||||
|
||||
TEST(clientCase, mktime_Test){
|
||||
struct tm tm;
|
||||
time_t t;
|
||||
|
||||
memset (&tm, 0, sizeof (tm));
|
||||
tm.tm_isdst = 0;
|
||||
tm.tm_year = 96; /* years since 1900 */
|
||||
tm.tm_mon = 4;
|
||||
tm.tm_mday = 24;
|
||||
tm.tm_hour = 3;
|
||||
tm.tm_min = 55;
|
||||
tm.tm_sec = 15;
|
||||
|
||||
for (unsigned int i = 0; i < sizeof (test_mk) / sizeof (test_mk[0]); ++i)
|
||||
{
|
||||
setenv ("TZ", test_mk[i].env, 1);
|
||||
t = taosMktime (&tm);
|
||||
ASSERT (t == test_mk[i].expected);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(clientCase, mktime_rz_Test){
|
||||
struct tm tm;
|
||||
time_t t;
|
||||
|
||||
memset (&tm, 0, sizeof (tm));
|
||||
tm.tm_isdst = 0;
|
||||
tm.tm_year = 96; /* years since 1900 */
|
||||
tm.tm_mon = 4;
|
||||
tm.tm_mday = 24;
|
||||
tm.tm_hour = 3;
|
||||
tm.tm_min = 55;
|
||||
tm.tm_sec = 15;
|
||||
|
||||
for (unsigned int i = 0; i < sizeof (test_mk) / sizeof (test_mk[0]); ++i)
|
||||
{
|
||||
timezone_t tz = tzalloc(test_mk[i].env);
|
||||
ASSERT(tz);
|
||||
t = taosMktimeRz(tz, &tm);
|
||||
ASSERT (t == test_mk[i].expected);
|
||||
tzfree(tz);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(testCase, localtime_performance_Test) {
|
||||
timezone_t sp = tzalloc("Asia/Shanghai");
|
||||
ASSERT(sp);
|
||||
|
||||
int cnt = 10000000;
|
||||
int times = 10;
|
||||
int64_t time_localtime = 0;
|
||||
int64_t time_localtime_rz = 0;
|
||||
// int cnt = 1000000;
|
||||
for (int i = 0; i < times; ++i) {
|
||||
int64_t t1 = taosGetTimestampNs();
|
||||
for (int j = 0; j < cnt; ++j) {
|
||||
time_t t = time_winter - j;
|
||||
struct tm tm1;
|
||||
ASSERT (taosLocalTime(&t, &tm1, NULL, 0));
|
||||
}
|
||||
int64_t tmp = taosGetTimestampNs() - t1;
|
||||
printf("localtime cost:%" PRId64 " ns, run %" PRId64 " times", tmp, cnt);
|
||||
time_localtime += tmp/cnt;
|
||||
|
||||
timezone;
|
||||
printf("\n");
|
||||
|
||||
|
||||
|
||||
int64_t t2 = taosGetTimestampNs();
|
||||
for (int j = 0; j < cnt; ++j) {
|
||||
time_t t = time_winter - j;
|
||||
struct tm tm1;
|
||||
ASSERT (taosLocalTimeRz(sp, &t, &tm1));
|
||||
}
|
||||
tmp = taosGetTimestampNs() - t2;
|
||||
printf("localtime_rz cost:%" PRId64 " ns, run %" PRId64 " times", tmp, cnt);
|
||||
time_localtime_rz += tmp/cnt;
|
||||
printf("\n\n");
|
||||
}
|
||||
printf("average: localtime cost:%" PRId64 " ns, localtime_rz cost:%" PRId64 " ns", time_localtime/times, time_localtime_rz/times);
|
||||
tzfree(sp);
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
|
|
@ -652,6 +652,7 @@ static int32_t taosAddClientCfg(SConfig *pCfg) {
|
|||
static int32_t taosAddSystemCfg(SConfig *pCfg) {
|
||||
SysNameInfo info = taosGetSysNameInfo();
|
||||
|
||||
(void)taosGetSystemTimezone(tsTimezoneStr);
|
||||
TAOS_CHECK_RETURN(cfgAddTimezone(pCfg, "timezone", tsTimezoneStr, CFG_SCOPE_BOTH, CFG_DYN_CLIENT));
|
||||
TAOS_CHECK_RETURN(cfgAddLocale(pCfg, "locale", tsLocale, CFG_SCOPE_BOTH, CFG_DYN_CLIENT));
|
||||
TAOS_CHECK_RETURN(cfgAddCharset(pCfg, "charset", tsCharset, CFG_SCOPE_BOTH, CFG_DYN_NONE));
|
||||
|
@ -1311,15 +1312,6 @@ static int32_t taosSetClientCfg(SConfig *pCfg) {
|
|||
static int32_t taosSetSystemCfg(SConfig *pCfg) {
|
||||
SConfigItem *pItem = NULL;
|
||||
|
||||
TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, "timezone");
|
||||
if (0 == strlen(pItem->str)) {
|
||||
uError("timezone is not set");
|
||||
} else {
|
||||
TAOS_CHECK_RETURN(osSetTimezone(pItem->str));
|
||||
uDebug("timezone format changed from %s to %s", pItem->str, tsTimezoneStr);
|
||||
}
|
||||
TAOS_CHECK_RETURN(cfgSetItem(pCfg, "timezone", tsTimezoneStr, pItem->stype, true));
|
||||
|
||||
TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, "locale");
|
||||
const char *locale = pItem->str;
|
||||
|
||||
|
@ -2239,13 +2231,7 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) {
|
|||
break;
|
||||
}
|
||||
case 't': {
|
||||
if (strcasecmp("timezone", name) == 0) {
|
||||
TAOS_CHECK_GOTO(osSetTimezone(pItem->str), &lino, _out);
|
||||
uInfo("%s set from %s to %s", name, tsTimezoneStr, pItem->str);
|
||||
|
||||
TAOS_CHECK_GOTO(cfgSetItem(pCfg, "timezone", tsTimezoneStr, pItem->stype, false), &lino, _out);
|
||||
matched = true;
|
||||
} else if (strcasecmp("tempDir", name) == 0) {
|
||||
if (strcasecmp("tempDir", name) == 0) {
|
||||
uInfo("%s set from %s to %s", name, tsTempDir, pItem->str);
|
||||
tstrncpy(tsTempDir, pItem->str, PATH_MAX);
|
||||
TAOS_CHECK_GOTO(taosExpandDir(tsTempDir, tsTempDir, PATH_MAX), &lino, _out);
|
||||
|
|
|
@ -36,7 +36,7 @@ static int32_t parseTimezone(char* str, int64_t* tzOffset);
|
|||
static int32_t (*parseLocaltimeFp[])(char* timestr, int32_t len, int64_t* utime, int32_t timePrec, char delim) = {
|
||||
parseLocaltime, parseLocaltimeDst};
|
||||
|
||||
int32_t taosParseTime(const char* timestr, int64_t* utime, int32_t len, int32_t timePrec, int8_t day_light) {
|
||||
int32_t taosParseTime(const char* timestr, int64_t* utime, int32_t len, int32_t timePrec) {
|
||||
/* parse datatime string in with tz */
|
||||
if (strnchr(timestr, 'T', len, false) != NULL) {
|
||||
if (checkTzPresent(timestr, len)) {
|
||||
|
@ -532,7 +532,7 @@ int32_t convertStringToTimestamp(int16_t type, char* inputData, int64_t timePrec
|
|||
TAOS_RETURN(terrno);
|
||||
}
|
||||
(void)memcpy(newColData, varDataVal(inputData), charLen);
|
||||
int32_t ret = taosParseTime(newColData, timeVal, charLen, (int32_t)timePrec, tsDaylight);
|
||||
int32_t ret = taosParseTime(newColData, timeVal, charLen, (int32_t)timePrec);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
taosMemoryFree(newColData);
|
||||
TAOS_RETURN(TSDB_CODE_INVALID_TIMESTAMP);
|
||||
|
@ -549,7 +549,7 @@ int32_t convertStringToTimestamp(int16_t type, char* inputData, int64_t timePrec
|
|||
TAOS_RETURN(TSDB_CODE_FAILED);
|
||||
}
|
||||
newColData[len] = 0;
|
||||
int32_t ret = taosParseTime(newColData, timeVal, len, (int32_t)timePrec, tsDaylight);
|
||||
int32_t ret = taosParseTime(newColData, timeVal, len, (int32_t)timePrec);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
taosMemoryFree(newColData);
|
||||
TAOS_RETURN(ret);
|
||||
|
|
|
@ -442,15 +442,15 @@ TEST(timeTest, timestamp2tm) {
|
|||
int64_t ts, tmp_ts = 0;
|
||||
struct STm tm;
|
||||
|
||||
ASSERT_EQ(TSDB_CODE_SUCCESS, taosParseTime(ts_str_ns, &ts, strlen(ts_str_ns), TSDB_TIME_PRECISION_NANO, 0));
|
||||
ASSERT_EQ(TSDB_CODE_SUCCESS, taosParseTime(ts_str_ns, &ts, strlen(ts_str_ns), TSDB_TIME_PRECISION_NANO));
|
||||
test_timestamp_tm_conversion(ts, TSDB_TIME_PRECISION_NANO, 2023 - 1900, 9 /* mon start from 0*/, 12, 11, 29, 0,
|
||||
775726171L);
|
||||
|
||||
ASSERT_EQ(TSDB_CODE_SUCCESS, taosParseTime(ts_str_us, &ts, strlen(ts_str_us), TSDB_TIME_PRECISION_MICRO, 0));
|
||||
ASSERT_EQ(TSDB_CODE_SUCCESS, taosParseTime(ts_str_us, &ts, strlen(ts_str_us), TSDB_TIME_PRECISION_MICRO));
|
||||
test_timestamp_tm_conversion(ts, TSDB_TIME_PRECISION_MICRO, 2023 - 1900, 9 /* mon start from 0*/, 12, 11, 29, 0,
|
||||
775726000L);
|
||||
|
||||
ASSERT_EQ(TSDB_CODE_SUCCESS, taosParseTime(ts_str_ms, &ts, strlen(ts_str_ms), TSDB_TIME_PRECISION_MILLI, 0));
|
||||
ASSERT_EQ(TSDB_CODE_SUCCESS, taosParseTime(ts_str_ms, &ts, strlen(ts_str_ms), TSDB_TIME_PRECISION_MILLI));
|
||||
test_timestamp_tm_conversion(ts, TSDB_TIME_PRECISION_MILLI, 2023 - 1900, 9 /* mon start from 0*/, 12, 11, 29, 0,
|
||||
775000000L);
|
||||
|
||||
|
|
|
@ -198,7 +198,7 @@ void dmSendStatusReq(SDnodeMgmt *pMgmt) {
|
|||
req.clusterCfg.monitorParas.tsSlowLogThresholdTest = tsSlowLogThresholdTest;
|
||||
tstrncpy(req.clusterCfg.monitorParas.tsSlowLogExceptDb, tsSlowLogExceptDb, TSDB_DB_NAME_LEN);
|
||||
char timestr[32] = "1970-01-01 00:00:00.00";
|
||||
if (taosParseTime(timestr, &req.clusterCfg.checkTime, (int32_t)strlen(timestr), TSDB_TIME_PRECISION_MILLI, 0) != 0) {
|
||||
if (taosParseTime(timestr, &req.clusterCfg.checkTime, (int32_t)strlen(timestr), TSDB_TIME_PRECISION_MILLI) != 0) {
|
||||
dError("failed to parse time since %s", tstrerror(code));
|
||||
}
|
||||
memcpy(req.clusterCfg.timezone, tsTimezoneStr, TD_TIMEZONE_LEN);
|
||||
|
@ -356,7 +356,7 @@ int32_t dmProcessConfigReq(SDnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
|||
|
||||
SConfig *pCfg = taosGetCfg();
|
||||
|
||||
code = cfgSetItem(pCfg, cfgReq.config, cfgReq.value, CFG_STYPE_ALTER_CMD, true);
|
||||
code = cfgSetItem(pCfg, cfgReq.config, cfgReq.value, CFG_STYPE_ALTER_SERVER_CMD, true);
|
||||
if (code != 0) {
|
||||
if (strncasecmp(cfgReq.config, "resetlog", strlen("resetlog")) == 0) {
|
||||
code = 0;
|
||||
|
|
|
@ -713,7 +713,7 @@ SMnode *mndOpen(const char *path, const SMnodeOpt *pOption) {
|
|||
}
|
||||
|
||||
char timestr[24] = "1970-01-01 00:00:00.00";
|
||||
code = taosParseTime(timestr, &pMnode->checkTime, (int32_t)strlen(timestr), TSDB_TIME_PRECISION_MILLI, 0);
|
||||
code = taosParseTime(timestr, &pMnode->checkTime, (int32_t)strlen(timestr), TSDB_TIME_PRECISION_MILLI);
|
||||
if (code < 0) {
|
||||
mError("failed to parse time since %s", tstrerror(code));
|
||||
(void)taosThreadRwlockDestroy(&pMnode->lock);
|
||||
|
|
|
@ -232,7 +232,7 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) {
|
|||
SConnObj *pConn = NULL;
|
||||
int32_t code = 0;
|
||||
SConnectReq connReq = {0};
|
||||
char ip[24] = {0};
|
||||
char ip[TD_IP_LEN] = {0};
|
||||
const STraceId *trace = &pReq->info.traceId;
|
||||
|
||||
if ((code = tDeserializeSConnectReq(pReq->pCont, pReq->contLen, &connReq)) != 0) {
|
||||
|
@ -244,7 +244,7 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
taosIp2String(pReq->info.conn.clientIp, ip);
|
||||
tinet_ntoa(ip, pReq->info.conn.clientIp);
|
||||
if ((code = mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CONNECT)) != 0) {
|
||||
mGError("user:%s, failed to login from %s since %s", pReq->info.conn.user, ip, tstrerror(code));
|
||||
goto _OVER;
|
||||
|
@ -896,9 +896,10 @@ static int32_t mndRetrieveConns(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBl
|
|||
return code;
|
||||
}
|
||||
|
||||
char endpoint[TSDB_IPv4ADDR_LEN + 6 + VARSTR_HEADER_SIZE] = {0};
|
||||
(void)sprintf(&endpoint[VARSTR_HEADER_SIZE], "%s:%d", taosIpStr(pConn->ip), pConn->port);
|
||||
varDataLen(endpoint) = strlen(&endpoint[VARSTR_HEADER_SIZE]);
|
||||
char endpoint[TD_IP_LEN + 6 + VARSTR_HEADER_SIZE] = {0};
|
||||
tinet_ntoa(varDataVal(endpoint), pConn->ip);
|
||||
(void)sprintf(varDataVal(endpoint) + strlen(varDataVal(endpoint)), ":%d", pConn->port);
|
||||
varDataLen(endpoint) = strlen(varDataVal(endpoint));
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
code = colDataSetVal(pColInfo, numOfRows, (const char *)endpoint, false);
|
||||
if (code != 0) {
|
||||
|
@ -1006,8 +1007,9 @@ static int32_t packQueriesIntoBlock(SShowObj *pShow, SConnObj *pConn, SSDataBloc
|
|||
return code;
|
||||
}
|
||||
|
||||
char endpoint[TSDB_IPv4ADDR_LEN + 6 + VARSTR_HEADER_SIZE] = {0};
|
||||
(void)sprintf(&endpoint[VARSTR_HEADER_SIZE], "%s:%d", taosIpStr(pConn->ip), pConn->port);
|
||||
char endpoint[TD_IP_LEN + 6 + VARSTR_HEADER_SIZE] = {0};
|
||||
tinet_ntoa(varDataVal(endpoint), pConn->ip);
|
||||
(void)sprintf(varDataVal(endpoint) + strlen(varDataVal(endpoint)), ":%d", pConn->port);
|
||||
varDataLen(endpoint) = strlen(&endpoint[VARSTR_HEADER_SIZE]);
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
code = colDataSetVal(pColInfo, curRowIndex, (const char *)endpoint, false);
|
||||
|
@ -1165,9 +1167,9 @@ static int32_t mndRetrieveApps(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlo
|
|||
return code;
|
||||
}
|
||||
|
||||
char ip[TSDB_IPv4ADDR_LEN + 6 + VARSTR_HEADER_SIZE] = {0};
|
||||
(void)sprintf(&ip[VARSTR_HEADER_SIZE], "%s", taosIpStr(pApp->ip));
|
||||
varDataLen(ip) = strlen(&ip[VARSTR_HEADER_SIZE]);
|
||||
char ip[TD_IP_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
tinet_ntoa(varDataVal(ip), pApp->ip);
|
||||
varDataLen(ip) = strlen(varDataVal(ip));
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
code = colDataSetVal(pColInfo, numOfRows, (const char *)ip, false);
|
||||
if (code != 0) {
|
||||
|
|
|
@ -901,7 +901,7 @@ static int32_t execAlterLocal(SAlterLocalStmt* pStmt) {
|
|||
return terrno;
|
||||
}
|
||||
|
||||
if (cfgSetItem(tsCfg, pStmt->config, pStmt->value, CFG_STYPE_ALTER_CMD, true)) {
|
||||
if (cfgSetItem(tsCfg, pStmt->config, pStmt->value, CFG_STYPE_ALTER_CLIENT_CMD, true)) {
|
||||
return terrno;
|
||||
}
|
||||
|
||||
|
|
|
@ -267,7 +267,7 @@ static int parseTimestampOrInterval(const char** end, SToken* pToken, int16_t ti
|
|||
}
|
||||
} else { // parse the RFC-3339/ISO-8601 timestamp format string
|
||||
*isTs = true;
|
||||
if (taosParseTime(pToken->z, ts, pToken->n, timePrec, tsDaylight) != TSDB_CODE_SUCCESS) {
|
||||
if (taosParseTime(pToken->z, ts, pToken->n, timePrec) != TSDB_CODE_SUCCESS) {
|
||||
if ((pToken->n == 0) ||
|
||||
(pToken->type != TK_NK_STRING && pToken->type != TK_NK_HEX && pToken->type != TK_NK_BIN)) {
|
||||
return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
|
||||
|
|
|
@ -1949,7 +1949,7 @@ static int32_t parseTimeFromValueNode(STranslateContext* pCxt, SValueNode* pVal)
|
|||
return TSDB_CODE_SUCCESS;
|
||||
} else if (IS_VAR_DATA_TYPE(pVal->node.resType.type) || TSDB_DATA_TYPE_TIMESTAMP == pVal->node.resType.type) {
|
||||
if (TSDB_CODE_SUCCESS == taosParseTime(pVal->literal, &pVal->datum.i, pVal->node.resType.bytes,
|
||||
pVal->node.resType.precision, tsDaylight)) {
|
||||
pVal->node.resType.precision)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
char* pEnd = NULL;
|
||||
|
|
|
@ -242,7 +242,7 @@ int32_t getVectorBigintValueFn(int32_t srcType, _getBigintValue_fn_t *p) {
|
|||
static FORCE_INLINE int32_t varToTimestamp(char *buf, SScalarParam *pOut, int32_t rowIndex, int32_t *overflow) {
|
||||
int64_t value = 0;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (taosParseTime(buf, &value, strlen(buf), pOut->columnData->info.precision, tsDaylight) != TSDB_CODE_SUCCESS) {
|
||||
if (taosParseTime(buf, &value, strlen(buf), pOut->columnData->info.precision) != TSDB_CODE_SUCCESS) {
|
||||
value = 0;
|
||||
code = TSDB_CODE_SCALAR_CONVERT_ERROR;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ char tsTimezoneStr[TD_TIMEZONE_LEN] = {0};
|
|||
enum TdTimezone tsTimezone = TdZeroZone;
|
||||
char tsLocale[TD_LOCALE_LEN] = {0};
|
||||
char tsCharset[TD_CHARSET_LEN] = {0};
|
||||
int8_t tsDaylight = 0;
|
||||
bool tsEnableCoreFile = 1;
|
||||
int64_t tsPageSizeKB = 0;
|
||||
int64_t tsOpenMax = 0;
|
||||
|
@ -49,14 +48,6 @@ int32_t osDefaultInit() {
|
|||
|
||||
taosSeedRand(taosSafeRand());
|
||||
taosGetSystemLocale(tsLocale, tsCharset);
|
||||
code = taosGetSystemTimezone(tsTimezoneStr, &tsTimezone);
|
||||
if(code != 0) {
|
||||
return code;
|
||||
}
|
||||
if (strlen(tsTimezoneStr) > 0) { // ignore empty timezone
|
||||
if ((code = taosSetSystemTimezone(tsTimezoneStr, tsTimezoneStr, &tsDaylight, &tsTimezone)) != TSDB_CODE_SUCCESS)
|
||||
return code;
|
||||
}
|
||||
|
||||
taosGetSystemInfo();
|
||||
|
||||
|
@ -124,7 +115,7 @@ bool osDataSpaceSufficient() { return tsDataSpace.size.avail > tsDataSpace.reser
|
|||
|
||||
bool osTempSpaceSufficient() { return tsTempSpace.size.avail > tsTempSpace.reserved; }
|
||||
|
||||
int32_t osSetTimezone(const char *tz) { return taosSetSystemTimezone(tz, tsTimezoneStr, &tsDaylight, &tsTimezone); }
|
||||
int32_t osSetTimezone(const char *tz) { return taosSetGlobalTimezone(tz); }
|
||||
|
||||
void osSetSystemLocale(const char *inLocale, const char *inCharSet) {
|
||||
(void)memcpy(tsLocale, inLocale, strlen(inLocale) + 1);
|
||||
|
|
|
@ -384,7 +384,8 @@ int32_t taosGetFqdn(char *fqdn) {
|
|||
}
|
||||
|
||||
void tinet_ntoa(char *ipstr, uint32_t ip) {
|
||||
(void)snprintf(ipstr, TD_IP_LEN, "%d.%d.%d.%d", ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, ip >> 24);
|
||||
unsigned char *bytes = (unsigned char *) &ip;
|
||||
(void)snprintf(ipstr, TD_IP_LEN, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]);
|
||||
}
|
||||
|
||||
int32_t taosIgnSIGPIPE() {
|
||||
|
|
|
@ -539,6 +539,128 @@ struct tm *taosLocalTime(const time_t *timep, struct tm *result, char *buf, int3
|
|||
return result;
|
||||
}
|
||||
|
||||
time_t taosMktimeRz(timezone_t state, struct tm *timep) {
|
||||
#ifdef WINDOWS
|
||||
#if 0
|
||||
struct tm tm1 = {0};
|
||||
LARGE_INTEGER t;
|
||||
FILETIME f;
|
||||
SYSTEMTIME s;
|
||||
FILETIME ff;
|
||||
SYSTEMTIME ss;
|
||||
LARGE_INTEGER offset;
|
||||
|
||||
time_t tt = 0;
|
||||
localtime_s(&tm1, &tt);
|
||||
ss.wYear = tm1.tm_year + 1900;
|
||||
ss.wMonth = tm1.tm_mon + 1;
|
||||
ss.wDay = tm1.tm_mday;
|
||||
ss.wHour = tm1.tm_hour;
|
||||
ss.wMinute = tm1.tm_min;
|
||||
ss.wSecond = tm1.tm_sec;
|
||||
ss.wMilliseconds = 0;
|
||||
SystemTimeToFileTime(&ss, &ff);
|
||||
offset.QuadPart = ff.dwHighDateTime;
|
||||
offset.QuadPart <<= 32;
|
||||
offset.QuadPart |= ff.dwLowDateTime;
|
||||
|
||||
s.wYear = timep->tm_year + 1900;
|
||||
s.wMonth = timep->tm_mon + 1;
|
||||
s.wDay = timep->tm_mday;
|
||||
s.wHour = timep->tm_hour;
|
||||
s.wMinute = timep->tm_min;
|
||||
s.wSecond = timep->tm_sec;
|
||||
s.wMilliseconds = 0;
|
||||
SystemTimeToFileTime(&s, &f);
|
||||
t.QuadPart = f.dwHighDateTime;
|
||||
t.QuadPart <<= 32;
|
||||
t.QuadPart |= f.dwLowDateTime;
|
||||
|
||||
t.QuadPart -= offset.QuadPart;
|
||||
return (time_t)(t.QuadPart / 10000000);
|
||||
#else
|
||||
time_t result = mktime(timep);
|
||||
if (result != -1) {
|
||||
return result;
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER >= 1900
|
||||
int64_t tz = _timezone;
|
||||
#endif
|
||||
#endif
|
||||
return user_mktime64(timep->tm_year + 1900, timep->tm_mon + 1, timep->tm_mday, timep->tm_hour, timep->tm_min,
|
||||
timep->tm_sec, tz);
|
||||
#endif
|
||||
#else
|
||||
time_t r = mktime_z(state, timep);
|
||||
if (r == (time_t)-1) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
}
|
||||
return r;
|
||||
#endif
|
||||
}
|
||||
|
||||
struct tm *taosLocalTimeRz(timezone_t state, const time_t *timep, struct tm *result) {
|
||||
struct tm *res = NULL;
|
||||
if (timep == NULL || result == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
#ifdef WINDOWS
|
||||
if (*timep < -2208988800LL) {
|
||||
if (buf != NULL) {
|
||||
snprintf(buf, bufSize, "NaN");
|
||||
}
|
||||
return NULL;
|
||||
} else if (*timep < 0) {
|
||||
SYSTEMTIME ss, s;
|
||||
FILETIME ff, f;
|
||||
|
||||
LARGE_INTEGER offset;
|
||||
struct tm tm1;
|
||||
time_t tt = 0;
|
||||
if (localtime_s(&tm1, &tt) != 0) {
|
||||
if (buf != NULL) {
|
||||
snprintf(buf, bufSize, "NaN");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
ss.wYear = tm1.tm_year + 1900;
|
||||
ss.wMonth = tm1.tm_mon + 1;
|
||||
ss.wDay = tm1.tm_mday;
|
||||
ss.wHour = tm1.tm_hour;
|
||||
ss.wMinute = tm1.tm_min;
|
||||
ss.wSecond = tm1.tm_sec;
|
||||
ss.wMilliseconds = 0;
|
||||
SystemTimeToFileTime(&ss, &ff);
|
||||
offset.QuadPart = ff.dwHighDateTime;
|
||||
offset.QuadPart <<= 32;
|
||||
offset.QuadPart |= ff.dwLowDateTime;
|
||||
offset.QuadPart += *timep * 10000000;
|
||||
f.dwLowDateTime = offset.QuadPart & 0xffffffff;
|
||||
f.dwHighDateTime = (offset.QuadPart >> 32) & 0xffffffff;
|
||||
FileTimeToSystemTime(&f, &s);
|
||||
result->tm_sec = s.wSecond;
|
||||
result->tm_min = s.wMinute;
|
||||
result->tm_hour = s.wHour;
|
||||
result->tm_mday = s.wDay;
|
||||
result->tm_mon = s.wMonth - 1;
|
||||
result->tm_year = s.wYear - 1900;
|
||||
result->tm_wday = s.wDayOfWeek;
|
||||
result->tm_yday = 0;
|
||||
result->tm_isdst = 0;
|
||||
} else {
|
||||
if (localtime_s(result, timep) != 0) {
|
||||
if (buf != NULL) {
|
||||
snprintf(buf, bufSize, "NaN");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#else
|
||||
return localtime_rz(state, timep, result);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int isLeapYear(time_t year) {
|
||||
if (year % 4)
|
||||
return 0;
|
||||
|
|
|
@ -740,8 +740,6 @@ char *tz_win[554][2] = {{"Asia/Shanghai", "China Standard Time"},
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
static int isdst_now = 0;
|
||||
|
||||
void parseTimeStr(char *p, char to[5]) {
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
if (strlen(p) > i) {
|
||||
|
@ -756,27 +754,16 @@ void parseTimeStr(char *p, char to[5]) {
|
|||
}
|
||||
}
|
||||
|
||||
int32_t taosSetSystemTimezone(const char *inTimezoneStr, char *outTimezoneStr, int8_t *outDaylight,
|
||||
enum TdTimezone *tsTimezone) {
|
||||
if (inTimezoneStr == NULL || inTimezoneStr[0] == 0) {
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
return terrno;
|
||||
}
|
||||
int32_t taosIsValidateTimezone(const char *tz) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
size_t len = strlen(inTimezoneStr);
|
||||
if (len >= TD_TIMEZONE_LEN) {
|
||||
int32_t taosSetGlobalTimezone(const char *tz) {
|
||||
if (tz == NULL || tz[0] == 0) {
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
return terrno;
|
||||
}
|
||||
char buf[TD_TIMEZONE_LEN] = {0};
|
||||
for (int32_t i = 0; i < len; i++) {
|
||||
if (inTimezoneStr[i] == ' ' || inTimezoneStr[i] == '(') {
|
||||
buf[i] = 0;
|
||||
break;
|
||||
}
|
||||
buf[i] = inTimezoneStr[i];
|
||||
}
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
#ifdef WINDOWS
|
||||
char winStr[TD_LOCALE_LEN * 2];
|
||||
|
@ -825,44 +812,100 @@ int32_t taosSetSystemTimezone(const char *inTimezoneStr, char *outTimezoneStr, i
|
|||
if (outTimezoneStr != inTimezoneStr) {
|
||||
tstrncpy(outTimezoneStr, inTimezoneStr, TD_TIMEZONE_LEN);
|
||||
}
|
||||
*outDaylight = 0;
|
||||
|
||||
#elif defined(_TD_DARWIN_64)
|
||||
|
||||
code = setenv("TZ", buf, 1);
|
||||
if (-1 == code) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
return terrno;
|
||||
}
|
||||
tzset();
|
||||
int32_t tz = (int32_t)((-timezone * MILLISECOND_PER_SECOND) / MILLISECOND_PER_HOUR);
|
||||
*tsTimezone = tz;
|
||||
tz += isdst_now;
|
||||
|
||||
snprintf(outTimezoneStr, TD_TIMEZONE_LEN, "%s (%s, %s%02d00)", buf, tzname[isdst_now], tz >= 0 ? "+" : "-", abs(tz));
|
||||
*outDaylight = isdst_now;
|
||||
|
||||
// *outDaylight = 0;
|
||||
#else
|
||||
code = setenv("TZ", buf, 1);
|
||||
code = setenv("TZ", tz, 1);
|
||||
if (-1 == code) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
tzset();
|
||||
int32_t tz = (int32_t)((-timezone * MILLISECOND_PER_SECOND) / MILLISECOND_PER_HOUR);
|
||||
*tsTimezone = tz;
|
||||
tz += isdst_now;
|
||||
(void)snprintf(outTimezoneStr, TD_TIMEZONE_LEN, "%s (%s, %s%02d00)", buf, tzname[isdst_now], tz >= 0 ? "+" : "-", abs(tz));
|
||||
*outDaylight = isdst_now;
|
||||
|
||||
time_t tx1 = taosGetTimestampSec();
|
||||
return taosFormatTimezoneStr(tx1, tz, NULL, tsTimezoneStr);
|
||||
#endif
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t taosGetSystemTimezone(char *outTimezoneStr, enum TdTimezone *tsTimezone) {
|
||||
int32_t code = 0;
|
||||
int32_t taosFormatTimezoneStr(time_t t, const char* tz, timezone_t sp, char *outTimezoneStr){
|
||||
struct tm tm1;
|
||||
if (sp == NULL) {
|
||||
if (taosLocalTime(&t, &tm1, NULL, 0) == NULL) {
|
||||
uError("failed to get local time");
|
||||
return TSDB_CODE_TIME_ERROR;
|
||||
}
|
||||
} else {
|
||||
if (taosLocalTimeRz(sp, &t, &tm1) == NULL) {
|
||||
uError("failed to get rz time");
|
||||
return TSDB_CODE_TIME_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* format example:
|
||||
*
|
||||
* Asia/Shanghai (CST, +0800)
|
||||
* Europe/London (BST, +0100)
|
||||
* n/a (UTC, +0000)
|
||||
*/
|
||||
|
||||
char str1[TD_TIMEZONE_LEN] = {0};
|
||||
if (strftime(str1, sizeof(str1), "%Z", &tm1) == 0){
|
||||
uError("failed to get timezone name");
|
||||
return TSDB_CODE_TIME_ERROR;
|
||||
}
|
||||
|
||||
char str2[TD_TIMEZONE_LEN] = {0};
|
||||
if (strftime(str2, sizeof(str2), "%z", &tm1) == 0){
|
||||
uError("failed to get timezone offset");
|
||||
return TSDB_CODE_TIME_ERROR;
|
||||
}
|
||||
(void)snprintf(outTimezoneStr, TD_TIMEZONE_LEN, "%s (%s, %s)", tz, str1, str2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void getTimezoneStr(char *tz) {
|
||||
do {
|
||||
int n = readlink("/r/localtime", tz, TD_TIMEZONE_LEN - 1);
|
||||
if (n < 0) {
|
||||
uWarn("[tz] failed to readlink /etc/localtime, reason:%s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
char *zi = strstr(tz, "zoneinfo");
|
||||
if (zi == NULL) {
|
||||
uWarn("[tz] failed to find zoneinfo in /etc/localtime");
|
||||
break;
|
||||
}
|
||||
zi += sizeof("zoneinfo");
|
||||
memcpy(tz, zi, TD_TIMEZONE_LEN - (zi - tz));
|
||||
goto END;
|
||||
} while (0);
|
||||
|
||||
|
||||
TdFilePtr pFile = taosOpenFile("/etc/timezone", TD_FILE_READ);
|
||||
if (pFile == NULL) {
|
||||
uWarn("[tz] failed to open /etc/timezone, reason:%s", strerror(errno));
|
||||
goto END;
|
||||
}
|
||||
int len = taosReadFile(pFile, tz, TD_TIMEZONE_LEN - 1);
|
||||
TAOS_UNUSED(taosCloseFile(&pFile));
|
||||
if (len <= 0) {
|
||||
uWarn("[tz] failed to read /etc/timezone, len:%d", len);
|
||||
goto END;
|
||||
}
|
||||
if (tz[len - 1] == '\n') {
|
||||
tz[len - 1] = '\0';
|
||||
}
|
||||
|
||||
END:
|
||||
if (tz[0] == '\0') {
|
||||
memcpy(tz, "n/a", sizeof("n/a"));
|
||||
}
|
||||
}
|
||||
|
||||
int32_t taosGetSystemTimezone(char *outTimezoneStr) {
|
||||
#ifdef WINDOWS
|
||||
char value[100];
|
||||
char keyPath[100];
|
||||
|
@ -895,162 +938,11 @@ int32_t taosGetSystemTimezone(char *outTimezoneStr, enum TdTimezone *tsTimezone)
|
|||
}
|
||||
}
|
||||
return 0;
|
||||
#elif defined(_TD_DARWIN_64)
|
||||
char buf[4096] = {0};
|
||||
char *tz = NULL;
|
||||
{
|
||||
int n = readlink("/etc/localtime", buf, sizeof(buf));
|
||||
if (n < 0) {
|
||||
return TSDB_CODE_TIME_ERROR;
|
||||
}
|
||||
buf[n] = '\0';
|
||||
|
||||
char *zi = strstr(buf, "zoneinfo");
|
||||
if (!zi) {
|
||||
return TSDB_CODE_TIME_ERROR;
|
||||
}
|
||||
tz = zi + strlen("zoneinfo") + 1;
|
||||
|
||||
code = setenv("TZ", tz, 1);
|
||||
if (-1 == code) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
return terrno;
|
||||
}
|
||||
tzset();
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: do not remove it.
|
||||
* Enforce set the correct daylight saving time(DST) flag according
|
||||
* to current time
|
||||
*/
|
||||
time_t tx1 = taosGetTimestampSec();
|
||||
struct tm tm1;
|
||||
if (taosLocalTime(&tx1, &tm1, NULL, 0) == NULL) {
|
||||
return TSDB_CODE_TIME_ERROR;
|
||||
}
|
||||
daylight = tm1.tm_isdst;
|
||||
isdst_now = tm1.tm_isdst;
|
||||
|
||||
/*
|
||||
* format example:
|
||||
*
|
||||
* Asia/Shanghai (CST, +0800)
|
||||
* Europe/London (BST, +0100)
|
||||
*/
|
||||
snprintf(outTimezoneStr, TD_TIMEZONE_LEN, "%s (%s, %+03ld00)", tz, tm1.tm_isdst ? tzname[daylight] : tzname[0],
|
||||
-timezone / 3600);
|
||||
return 0;
|
||||
#else
|
||||
|
||||
char buf[4096] = {0};
|
||||
char *tz = NULL;
|
||||
{
|
||||
int n = readlink("/etc/localtime", buf, sizeof(buf)-1);
|
||||
if (n < 0) {
|
||||
if (taosCheckExistFile("/etc/timezone")) {
|
||||
/*
|
||||
* NOTE: do not remove it.
|
||||
* Enforce set the correct daylight saving time(DST) flag according
|
||||
* to current time
|
||||
*/
|
||||
time_t tx1 = taosGetTimestampSec();
|
||||
struct tm tm1;
|
||||
if(taosLocalTime(&tx1, &tm1, NULL, 0) == NULL) {
|
||||
return TSDB_CODE_TIME_ERROR;
|
||||
}
|
||||
/* load time zone string from /etc/timezone */
|
||||
// FILE *f = fopen("/etc/timezone", "r");
|
||||
errno = 0;
|
||||
TdFilePtr pFile = taosOpenFile("/etc/timezone", TD_FILE_READ);
|
||||
char buf[68] = {0};
|
||||
if (pFile != NULL) {
|
||||
int len = taosReadFile(pFile, buf, 64);
|
||||
if (len < 0) {
|
||||
TAOS_UNUSED(taosCloseFile(&pFile));
|
||||
return TSDB_CODE_TIME_ERROR;
|
||||
}
|
||||
|
||||
TAOS_UNUSED(taosCloseFile(&pFile));
|
||||
|
||||
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) {
|
||||
code = setenv("TZ", buf, 1);
|
||||
if (-1 == code) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
return terrno;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
*tsTimezone = tz;
|
||||
tz += daylight;
|
||||
|
||||
/*
|
||||
* format example:
|
||||
*
|
||||
* Asia/Shanghai (CST, +0800)
|
||||
* Europe/London (BST, +0100)
|
||||
*/
|
||||
(void)snprintf(outTimezoneStr, TD_TIMEZONE_LEN, "%s (%s, %s%02d00)", buf, tzname[daylight], tz >= 0 ? "+" : "-",
|
||||
abs(tz));
|
||||
} else {
|
||||
return TSDB_CODE_TIME_ERROR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
buf[n] = '\0';
|
||||
|
||||
char *zi = strstr(buf, "zoneinfo");
|
||||
if (!zi) {
|
||||
return TSDB_CODE_TIME_ERROR;
|
||||
}
|
||||
tz = zi + strlen("zoneinfo") + 1;
|
||||
|
||||
code = setenv("TZ", tz, 1);
|
||||
if (-1 == code) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
return terrno;
|
||||
}
|
||||
tzset();
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: do not remove it.
|
||||
* Enforce set the correct daylight saving time(DST) flag according
|
||||
* to current time
|
||||
*/
|
||||
char tz[TD_TIMEZONE_LEN] = {0};
|
||||
getTimezoneStr(tz);
|
||||
time_t tx1 = taosGetTimestampSec();
|
||||
struct tm tm1;
|
||||
if(taosLocalTime(&tx1, &tm1, NULL, 0) == NULL) {
|
||||
return TSDB_CODE_TIME_ERROR;
|
||||
}
|
||||
isdst_now = tm1.tm_isdst;
|
||||
|
||||
/*
|
||||
* format example:
|
||||
*
|
||||
* Asia/Shanghai (CST, +0800)
|
||||
* Europe/London (BST, +0100)
|
||||
*/
|
||||
(void)snprintf(outTimezoneStr, TD_TIMEZONE_LEN, "%s (%s, %+03ld00)", tz, tm1.tm_isdst ? tzname[daylight] : tzname[0],
|
||||
-timezone / 3600);
|
||||
return 0;
|
||||
return taosFormatTimezoneStr(tx1, tz, NULL, outTimezoneStr);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -245,6 +245,17 @@ static int32_t doSetConf(SConfigItem *pItem, const char *value, ECfgSrcType styp
|
|||
}
|
||||
|
||||
static int32_t cfgSetTimezone(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
|
||||
if (stype == CFG_STYPE_ALTER_SERVER_CMD || (pItem->dynScope & CFG_DYN_CLIENT) == 0){
|
||||
uError("failed to config timezone, not support");
|
||||
TAOS_RETURN(TSDB_CODE_INVALID_CFG);
|
||||
}
|
||||
|
||||
if(!taosIsValidateTimezone(value)){
|
||||
uError("invalid timezone:%s", value);
|
||||
TAOS_RETURN(TSDB_CODE_INVALID_TIMEZONE);
|
||||
}
|
||||
TAOS_CHECK_RETURN(osSetTimezone(value));
|
||||
|
||||
TAOS_CHECK_RETURN(doSetConf(pItem, value, stype));
|
||||
if (strlen(value) == 0) {
|
||||
uError("cfg:%s, type:%s src:%s, value:%s, skip to set timezone", pItem->name, cfgDtypeStr(pItem->dtype),
|
||||
|
@ -252,7 +263,6 @@ static int32_t cfgSetTimezone(SConfigItem *pItem, const char *value, ECfgSrcType
|
|||
TAOS_RETURN(TSDB_CODE_SUCCESS);
|
||||
}
|
||||
|
||||
TAOS_CHECK_RETURN(osSetTimezone(value));
|
||||
TAOS_RETURN(TSDB_CODE_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -634,6 +644,10 @@ const char *cfgStypeStr(ECfgSrcType type) {
|
|||
return "taos_options";
|
||||
case CFG_STYPE_ENV_CMD:
|
||||
return "env_cmd";
|
||||
case CFG_STYPE_ALTER_CLIENT_CMD:
|
||||
return "alter_client_cmd";
|
||||
case CFG_STYPE_ALTER_SERVER_CMD:
|
||||
return "alter_server_cmd";
|
||||
default:
|
||||
return "invalid";
|
||||
}
|
||||
|
|
|
@ -866,6 +866,9 @@ TAOS_DEFINE_ERROR(TSDB_CODE_UTIL_QUEUE_OUT_OF_MEMORY, "Queue out of memory
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_AUDIT_NOT_FORMAT_TO_JSON, "can't format to json")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_AUDIT_FAIL_SEND_AUDIT_RECORD, "Failed to send out audit record")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_AUDIT_FAIL_GENERATE_JSON, "Failed to generate json")
|
||||
|
||||
//TIMEZONE
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_TIMEZONE, "Invalid timezone")
|
||||
#ifdef TAOS_ERROR_C
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -416,25 +416,6 @@ int32_t taosHexStrToByteArray(char hexstr[], char bytes[]) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
char *taosIpStr(uint32_t ipInt) {
|
||||
static char ipStrArray[3][30];
|
||||
static int32_t ipStrIndex = 0;
|
||||
|
||||
char *ipStr = ipStrArray[(ipStrIndex++) % 3];
|
||||
// sprintf(ipStr, "0x%x:%u.%u.%u.%u", ipInt, ipInt & 0xFF, (ipInt >> 8) & 0xFF, (ipInt >> 16) & 0xFF, (uint8_t)(ipInt
|
||||
// >> 24));
|
||||
sprintf(ipStr, "%u.%u.%u.%u", ipInt & 0xFF, (ipInt >> 8) & 0xFF, (ipInt >> 16) & 0xFF, (uint8_t)(ipInt >> 24));
|
||||
return ipStr;
|
||||
}
|
||||
|
||||
void taosIp2String(uint32_t ip, char *str) {
|
||||
sprintf(str, "%u.%u.%u.%u", ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, (uint8_t)(ip >> 24));
|
||||
}
|
||||
|
||||
void taosIpPort2String(uint32_t ip, uint16_t port, char *str) {
|
||||
sprintf(str, "%u.%u.%u.%u:%u", ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, (uint8_t)(ip >> 24), port);
|
||||
}
|
||||
|
||||
size_t tstrncspn(const char *str, size_t size, const char *reject, size_t rsize) {
|
||||
if (rsize == 0 || rsize == 1) {
|
||||
char *p = strnchr(str, reject[0], size, false);
|
||||
|
|
Loading…
Reference in New Issue