39 #if defined (SERVER_MODE) || defined (SA_MODE) 42 #if !defined (SERVER_MODE) 48 #if defined (SERVER_MODE) 52 #if defined (SUPPRESS_STRLEN_WARNING) 53 #define strlen(s1) ((int) strlen(s1)) 86 #define FULL_DATE(jul_date, time_sec) ((full_date_t) jul_date * 86400ll \ 87 + (full_date_t) time_sec) 88 #define TIME_OFFSET(is_utc, offset) \ 89 ((is_utc) ? (-offset) : (offset)) 90 #define ABS(i) ((i) >= 0 ? (i) : -(i)) 92 #define TZ_INVALID_OFFSET ((((23 * 60) + 59) * 60) + 59) 93 #define TZ_MIN_OFFSET -12 * 3600 94 #define TZ_MAX_OFFSET 14 * 3600 95 #define MILLIS_IN_A_DAY (long)(86400000) 96 #define TZ_MASK_TZ_ID_FLAG 0xc0000000 97 #define TZ_BIT_SHIFT_TZ_ID_FLAG 30 98 #define TZ_OFFSET_MASK 0x3fffffff 99 #define SECONDS_IN_A_DAY 24 * 3600 103 #if !defined(SERVER_MODE) 113 tz_Timezone_data = { 0,
NULL, 0,
NULL,
NULL, 0,
NULL, 0,
NULL, 0,
NULL, 0,
NULL, 0,
NULL, 0,
NULL, {
'0'} };
117 tz_New_timezone_data = { 0,
NULL, 0,
NULL,
NULL, 0,
NULL, 0,
NULL, 0,
NULL, 0,
NULL, 0,
NULL, 0,
NULL, {
'0'} };
120 static TZ_DATA tz_Timezone_data = { 0,
NULL, 0,
NULL,
NULL, 0,
NULL, 0,
NULL, 0,
NULL, 0,
NULL, 0,
NULL, {
'0'} };
123 static TZ_DATA tz_New_timezone_data = { 0,
NULL, 0,
NULL,
NULL, 0,
NULL, 0,
NULL, 0,
NULL, 0,
NULL, 0,
NULL, {
'0'} };
126 static const int tz_Days_of_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
127 static const int tz_Days_up_to_month[] = { 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
129 #if defined (SA_MODE) 130 bool tz_Is_backward_compatible_timezone[
ZONE_MAX];
131 bool tz_Compare_datetimetz_tz_id =
false;
132 bool tz_Compare_timestamptz_tz_id =
false;
141 const char **tz_end);
148 const int src_year,
const int src_month,
int *ds_rule_id);
150 const char *ds_string,
const char *default_abrev);
157 static int starts_with (
const char *prefix,
const char *str);
160 int *minutesp,
int *secondsp);
161 static int tz_offset (
const bool src_is_utc,
const TZ_TIME_TYPE until_time_type,
const int gmt_offset_sec,
162 const int ds_save_time);
169 const full_date_t gmt_diff,
const int save_time_diff);
173 static int find_timezone_from_clock (
char *timezone_name,
int buf_len);
174 static int find_timezone_from_localtime (
char *timezone_name,
int buf_len);
177 static int tz_get_iana_zone_id_by_windows_zone (
const char *windows_zone_name);
181 #define TZ_GET_SYM_ADDR(lib, sym) GetProcAddress((HMODULE)lib, sym) 183 #define TZ_GET_SYM_ADDR(lib, sym) dlsym(lib, sym) 186 #define TZLIB_GET_ADDR(v, SYM_NAME, SYM_TYPE, lh) \ 188 v = (SYM_TYPE) TZ_GET_SYM_ADDR (lh, SYM_NAME); \ 191 strncpy (sym_name, (SYM_NAME), sizeof (sym_name) - 1); \ 192 sym_name[sizeof (sym_name) - 1] = '\0'; \ 193 goto error_loading_symbol; \ 197 #define TZLIB_GET_VAL(v, SYM_NAME, SYM_TYPE, lh) \ 200 TZLIB_GET_ADDR(aux, SYM_NAME, SYM_TYPE*, lh); \ 204 #define APPLY_NEXT_OFF_RULE() \ 206 prev_off_rule = curr_off_rule; \ 207 curr_off_rule = next_off_rule; \ 208 next_off_rule = offset_rules[offset_rule_counter++]; \ 235 error_mode = SetErrorMode (SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
236 *handle = LoadLibrary (lib_file);
237 SetErrorMode (error_mode);
238 loading_err = GetLastError ();
241 *handle = dlopen (lib_file, RTLD_NOW | RTLD_MEMBER);
244 *handle = dlopen (lib_file, RTLD_NOW);
255 FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
256 loading_err, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), (
char *) &lpMsgBuf, 1,
257 (va_list *) & lib_file);
258 snprintf (err_msg,
sizeof (err_msg) - 1,
259 "Library file is invalid or not accessible.\n" " Unable to load %s !\n %s", lib_file, lpMsgBuf);
260 LocalFree (lpMsgBuf);
264 "Library file is invalid or not accessible.\n" " Unable to load %s !\n %s", lib_file,
267 printf (
"%s\n", err_msg);
284 char err_msg[512 + PATH_MAX];
314 TZLIB_GET_VAL (tzd->windows_iana_map_count,
"windows_iana_map_count",
int, lib_handle);
318 TZLIB_GET_ADDR (checksum,
"tz_timezone_checksum",
char *, lib_handle);
319 strncpy (tzd->
checksum, checksum, 32);
324 error_loading_symbol:
325 snprintf (err_msg,
sizeof (err_msg) - 1,
"Cannot load symbol '%s' from the timezone library file!", sym_name);
326 printf (
"%s\n", err_msg);
340 char lib_file[PATH_MAX] = { 0 };
383 memset (&tz_Timezone_data, 0,
sizeof (tz_Timezone_data));
390 dlclose (tz_Lib_handle);
392 tz_Lib_handle =
NULL;
404 bool leapsec_support;
408 return leapsec_support;
435 if (leap_second.
year > year_century + year)
439 if (leap_second.
year == year_century + year)
441 if ((mon < leap_second.
month) || (mon == leap_second.
month && day <= leap_second.
day))
477 const int year_base = 1970;
478 const int secs_per_day = 24 * 3600;
481 int year, months, day;
482 int hours, minutes, seconds;
515 while (index < leap_cnt && tzd->ds_leap_sec[index].year == year_base + year)
521 if (timestamp - days_in_year * secs_per_day - leap < 0)
527 timestamp -= days_in_year * secs_per_day + leap;
540 subtract += secs_per_day;
543 while (index < leap_cnt && tzd->ds_leap_sec[index].year == year_base + year
550 if (timestamp - subtract - leap < 0)
555 timestamp -= subtract + leap;
560 day = timestamp / secs_per_day;
561 timestamp = timestamp % secs_per_day;
564 while (index < leap_cnt && tzd->ds_leap_sec[index].year == year_base + year && tzd->
ds_leap_sec[index].
month == months
571 diff = timestamp - leap;
575 timestamp = secs_per_day +
diff;
584 hours = timestamp / 3600;
585 minutes = (timestamp % 3600) / 60;
586 seconds = (timestamp % 3600) % 60;
588 *yearp = year + year_base;
604 const int year_base = 1970;
605 const int secs_per_day = 24 * 3600;
606 const int days_in_year = 365;
607 const int secs_in_a_year = secs_per_day * days_in_year;
608 int year, month, day;
609 int hours, minutes, seconds;
610 int secs_until_last_year;
611 int secs_until_last_month = 0;
615 year = timestamp / (days_in_year * secs_per_day);
616 secs_until_last_year =
617 year * secs_in_a_year + ((year + 1) / 4) * secs_per_day - ((year + 69) / 100) * secs_per_day +
618 ((year + 369) / 400) * secs_per_day;
621 if (timestamp - secs_until_last_year < 0)
624 secs_until_last_year -= secs_in_a_year;
627 secs_until_last_year -= secs_per_day;
630 timestamp -= secs_until_last_year;
633 month = timestamp / (31 * secs_per_day);
641 secs_until_last_month += secs_per_day;
648 days_last_month += secs_per_day;
651 if (timestamp - secs_until_last_month - days_last_month >= 0)
653 secs_until_last_month += days_last_month;
657 timestamp -= secs_until_last_month;
660 day = timestamp / secs_per_day;
662 timestamp = timestamp % secs_per_day;
665 hours = timestamp / 3600;
666 minutes = (timestamp % 3600) / 60;
667 seconds = (timestamp % 3600) % 60;
669 *yearp = year + year_base;
704 tz_Timezone_data = *data;
731 tz_New_timezone_data = *data;
773 *tz_region = *session_tz_region;
777 #if defined(SERVER_MODE) 778 session_tz_region = tz_get_server_tz_region_session ();
782 if (session_tz_region !=
NULL)
784 *tz_region = *session_tz_region;
818 static const TZ_ID utc_tz_id = 0x1 << 30;
844 return &invalid_region;
856 struct tm c_time_struct, *c_time_struct_p;
858 time_val = time (
NULL);
859 c_time_struct_p = localtime_r (&time_val, &c_time_struct);
860 if (c_time_struct_p ==
NULL)
867 c_time_struct_p->tm_year + 1900, c_time_struct_p->tm_hour, c_time_struct_p->tm_min,
868 c_time_struct_p->tm_sec, 0);
871 return datetime.
date;
886 const int sign_hour_minutes = 6;
887 const int seconds = 3;
888 int off_hour, off_min, off_sec, out_len = 0;
897 off_hour = tz_offset / 3600;
898 off_min = (tz_offset % 3600) / 60;
899 off_sec = (tz_offset % 3600) % 60;
901 out_len += sign_hour_minutes;
909 if (snprintf (result, out_len + 1,
"%c%02d:%02d", sign, off_hour, off_min) < 0)
917 if (snprintf (result, out_len + 1,
"%c%02d:%02d:%02d", sign, off_hour, off_min, off_sec) < 0)
923 (result)[out_len] =
'\0';
937 const char *
p = tz_str;
945 if (p >= tz_str + tz_size)
951 if (*p ==
'+' || *p ==
'-')
954 const char *zone_end;
961 while (zone_end < tz_str + tz_size &&
char_isspace (*zone_end))
966 if (zone_end != tz_str + tz_size)
981 const char *save_poz;
995 if (end != tz_str + tz_size)
1010 tzinfo.
zone.dst_str[0] =
'\0';
1019 (int) (dest_datetime.
date - utc_datetime->
date) * 3600 * 24 + (int) (dest_datetime.
time -
1020 utc_datetime->
time) / 1000;
1076 dt.
time = time * 1000;
1096 src_dt.
time = *src_time;
1112 int name_index = -1;
1113 int index_bot, index_top;
1127 while (index_bot <= index_top)
1129 name_index = (index_bot + index_top) >> 1;
1130 cmp_res = strncmp (name, tzd->
names[name_index].
name, name_size);
1134 index_top = name_index - 1;
1136 else if (cmp_res > 0)
1138 index_bot = name_index + 1;
1144 index_top = name_index - 1;
1172 const char *zone_str, *tz_str_end;
1173 const char *zone_str_end;
1176 tz_str_end = tz_str + tz_str_size;
1179 while (zone_str < tz_str_end &&
char_isspace (*zone_str))
1184 if (zone_str >= tz_str_end)
1190 if (*zone_str ==
'+' || *zone_str ==
'-')
1203 reg_str_end = zone_str;
1204 while (reg_str_end < tz_str_end && !
char_isspace (*reg_str_end))
1209 dst_str = reg_str_end;
1210 while (dst_str < tz_str_end &&
char_isspace (*dst_str))
1215 if (dst_str < tz_str_end)
1218 while (dst_str_end < tz_str_end && !
char_isspace (*dst_str_end))
1222 zone_str_end = dst_str_end;
1242 if (dst_str !=
NULL)
1244 if (dst_str_end - dst_str > (
int)
sizeof (tz_info->
zone.dst_str))
1250 strncpy (tz_info->
zone.dst_str, dst_str, dst_str_end - dst_str);
1251 tz_info->
zone.dst_str[dst_str_end -
dst_str] =
'\0';
1252 zone_str = dst_str_end;
1256 tz_info->
zone.dst_str[0] =
'\0';
1262 while (zone_str_end < tz_str_end &&
char_isspace (*zone_str_end))
1266 *tz_end = zone_str_end;
1288 const char *zone_str, *tz_str_end;
1289 const char *zone_str_end;
1290 int reg_zone_id, reg_offset;
1293 tz_str_end = tz_str + tz_str_size;
1296 while (zone_str < tz_str_end &&
char_isspace (*zone_str))
1301 if (zone_str >= tz_str_end)
1307 if (*zone_str ==
'+' || *zone_str ==
'-')
1315 while (zone_str_end < tz_str_end &&
char_isspace (*zone_str_end))
1320 if (zone_str_end != tz_str_end)
1330 const char *reg_str_end;
1332 reg_str_end = zone_str;
1333 while (reg_str_end < tz_str_end && !
char_isspace (*reg_str_end))
1339 if (reg_zone_id == -1)
1348 if (tz_region !=
NULL)
1350 tz_region->
type = reg_type;
1353 tz_region->
offset = reg_offset;
1357 tz_region->
zone_id = reg_zone_id;
1390 if (end_tz_str !=
NULL)
1444 if (end_tz_str !=
NULL)
1463 dt.
time = (*time) * 1000;
1470 date_utc = utc_dt.
date;
1471 time_utc = utc_dt.
time / 1000;
1529 const char *dest_zone,
int len_dest,
DB_TIME * time_dest)
1548 src_dt.
time = (*time_source) * 1000;
1556 *time_dest = dest_dt.
time / 1000;
1581 total_offset = tz_info.
offset;
1584 #if !defined (CS_MODE) 1594 total_offset = tz_info.
zone.p_zone_off_rule->gmt_off;
1598 total_offset += tz_info.
zone.p_ds_rule->save_time;
1602 total_offset += tz_info.
zone.p_zone_off_rule->ds_ruleset;
1606 if (dt_utc->
date == 0)
1609 *dt_local = *dt_utc;
1658 int dst_format_size;
1663 const char *p_dst_format =
NULL;
1668 int hour,
min, sec, n;
1676 sign = (offset < 0) ?
'-' :
'+';
1679 offset = (offset < 0) ? (-offset) :
offset;
1684 n = sprintf (tz_str,
"%c%02d:%02d:%02d", sign, hour, min, sec);
1688 n = sprintf (tz_str,
"%c%02d:%02d", sign, hour, min);
1699 zone_id = tz_info->
zone.zone_id;
1700 zone_offset_id = tz_info->
zone.offset_id;
1712 const char *ds_abbr =
NULL;
1715 if (dst_id < ds_ruleset->
count)
1723 if (ds_abbr ==
NULL)
1725 p_dst_format =
NULL;
1729 snprintf (dst_format,
sizeof (dst_format) - 1, zone_off_rule->
var_format,
1730 (ds_abbr !=
NULL && *ds_abbr !=
'-') ? ds_abbr :
"");
1731 p_dst_format = dst_format;
1743 if (p_dst_format !=
NULL)
1745 dst_format_size =
strlen (p_dst_format);
1749 dst_format_size = 0;
1752 if (dst_format_size > 0)
1754 total_len = dst_format_size + zone_name_size + 2;
1758 total_len = zone_name_size + 1;
1761 if (total_len > tz_str_size)
1767 if (p_dst_format !=
NULL)
1769 snprintf (tz_str, tz_str_size,
"%s %s", tzd->
names[zone_id].
name, p_dst_format);
1773 snprintf (tz_str, tz_str_size,
"%s", tzd->
names[zone_id].
name);
1776 return total_len - 1;
1903 *tz_id = offset | (0x2 << 30);
1907 *tz_id = offset | (0x1 << 30);
1920 *tz_id = dst_id | (offset_id << 8) | (zone_id) << 16;
1959 unsigned int val = (
unsigned int) *tz_id;
1962 memset (tz_info, 0,
sizeof (tz_info[0]));
1966 tz_info->
zone.zone_id = (val & (TZ_ZONE_ID_MAX << 16)) >> 16;
1967 tz_info->
zone.offset_id = (val & (TZ_OFFSET_ID_MAX << 8)) >> 8;
1989 zone_offset_id = tz_info->
zone.offset_id;
1994 tz_info->
zone.p_timezone = timezone;
1997 tz_info->
zone.p_zone_off_rule = zone_off_rule;
2004 const char *ds_abbr =
NULL;
2007 dst_id = tz_info->
zone.dst_id;
2010 if (dst_id != TZ_DS_ID_MAX)
2012 assert (dst_id >= 0 && dst_id < ds_ruleset->
count);
2016 tz_info->
zone.p_ds_rule = ds_rule;
2020 snprintf (tz_info->
zone.dst_str, sizeof (tz_info->
zone.dst_str) - 1, zone_off_rule->
var_format,
2021 (ds_abbr !=
NULL && *ds_abbr !=
'-') ? ds_abbr :
"");
2069 tz_info->
zone.p_zone_off_rule =
NULL;
2071 tz_info->
zone.dst_str[0] =
'\0';
2088 int first_weekday = -1;
2094 first_weekday = ref_day;
2096 while (wday != weekday)
2102 assert (first_weekday >= 0);
2114 return first_weekday;
2130 tz_str_read_number (
const char *str,
const char *str_end,
const bool strict,
const bool read_sign,
int *val,
2131 const char **str_next)
2134 const char *str_cursor;
2135 bool is_negative =
false;
2141 if (read_sign ==
true && str < str_end)
2143 if (*str_cursor ==
'-')
2148 else if (*str_cursor ==
'+')
2154 while (str_cursor < str_end &&
char_isdigit (*str_cursor))
2156 cur_val = cur_val * 10 + (*str_cursor -
'0');
2160 *val = is_negative ? -cur_val : cur_val;
2162 *str_next = (
char *) str_cursor;
2164 if (strict && str_cursor == str)
2186 tz_str_read_time (
const char *str,
const char *str_end,
bool need_minutes,
bool allow_sec60,
int *hour,
int *
min,
2187 int *sec,
const char **str_next)
2189 const char *str_cursor;
2194 *hour = *min = *sec = 0;
2202 if (val_read < 0 || val_read > 24)
2208 str_cursor = *str_next;
2209 if (*str_cursor !=
':')
2211 if (!need_minutes && *str_cursor ==
'\0')
2222 if (str_cursor >= str_end ||
IS_EMPTY_STR (str_cursor))
2231 if (val_read < 0 || val_read > 60 || (val_read > 0 && *hour == 24))
2238 str_cursor = *str_next;
2240 assert (str_cursor <= str_end);
2241 if (str_cursor == str_end)
2248 assert (str_cursor < str_end);
2249 if (*str_cursor ==
':')
2257 if (val_read < 0 || val_read > (allow_sec60 ? 61 : 60))
2278 tz_str_to_seconds (
const char *str,
const char *str_end,
int *seconds,
const char **str_next,
const bool is_offset)
2282 const char *str_cursor =
NULL;
2283 int hour = 0,
min = 0, sec = 0;
2284 bool is_negative =
false;
2289 if (str_cursor < str_end && *str_cursor ==
'-')
2294 if (str_cursor < str_end && *str_cursor ==
'+')
2299 err_status =
tz_str_read_time (str_cursor, str_end,
false,
false, &hour, &
min, &sec, str_next);
2304 if (is_offset ==
true)
2306 if (is_negative ==
true && -(hour * 3600 +
min * 60 + sec) <
TZ_MIN_OFFSET)
2310 if (is_negative ==
false && (hour * 3600 +
min * 60 + sec) >
TZ_MAX_OFFSET)
2316 result = sec +
min * 60 + hour * 3600;
2318 *seconds = is_negative ? -result : result;
2334 int *ds_rule_julian_date,
full_date_t * date_diff)
2337 int ds_rule_month = ds_rule->
in_month;
2346 int ds_rule_weekday, day_month_bound;
2352 && day_month_bound == 27)
2359 if (ds_rule_day == -1)
2366 *ds_rule_julian_date =
julian_encode (1 + ds_rule_month, 1 + ds_rule_day, year);
2368 if (date_diff !=
NULL)
2389 const int src_year,
const int src_month,
int *ds_rule_id)
2395 int year_to_apply_rule = 0;
2397 int second_best_ds_id = -1;
2406 for (curr_ds_id = 0; curr_ds_id < ds_ruleset->
count; curr_ds_id++)
2408 int ds_rule_julian_date;
2414 if (src_year + 1 < curr_ds_rule->
from_year)
2420 if (src_year - 1 > curr_ds_rule->
to_year 2435 diff =
FULL_DATE (src_julian_date, 0) - ds_rule_date;
2437 if (second_best_date_diff == -1 || diff < second_best_date_diff)
2439 second_best_date_diff =
diff;
2440 second_best_ds_id = curr_ds_id;
2460 if (date_diff < 0 && curr_ds_rule->from_year < year_to_apply_rule)
2465 &ds_rule_julian_date, &date_diff);
2473 && (smallest_date_diff == -1 || date_diff < smallest_date_diff))
2476 *ds_rule_id = curr_ds_id;
2477 smallest_date_diff = date_diff;
2480 if (*ds_rule_id == -1)
2482 *ds_rule_id = second_best_ds_id;
2500 const char *default_abrev)
2502 bool rule_matched =
true;
2503 const char *letter_abrev =
NULL;
2509 else if (ds_rule ==
NULL && *default_abrev !=
'-')
2511 letter_abrev = default_abrev;
2518 if (letter_abrev !=
NULL)
2520 snprintf (rule_dst_format,
sizeof (rule_dst_format) - 1, off_rule->
var_format, letter_abrev);
2524 snprintf (rule_dst_format,
sizeof (rule_dst_format) - 1, off_rule->
var_format,
"");
2527 if (strcasecmp (rule_dst_format, ds_string) != 0)
2530 rule_matched =
false;
2534 && strcasecmp (off_rule->
save_format, ds_string) != 0)
2537 rule_matched =
false;
2542 rule_matched =
false;
2545 return rule_matched;
2563 if (src_is_utc ==
true)
2567 offset += gmt_offset_sec;
2571 offset += gmt_offset_sec + ds_save_time;
2574 else if (src_is_utc ==
false)
2578 offset -= gmt_offset_sec + ds_save_time;
2582 offset -= ds_save_time;
2604 int ds_rule_julian_date;
2625 *date_diff =
FULL_DATE (src_julian_date, src_time_sec) - ds_rule_date;
2629 *date_diff = -(*date_diff);
2652 int closest_ds_rule_id = 0;
2658 for (; curr_ds_id < ds_ruleset->
count; curr_ds_id++)
2671 if (best_diff == -1 || date_diff < best_diff)
2673 best_diff = date_diff;
2674 closest_ds_rule_id = curr_ds_id;
2678 return closest_ds_rule_id;
2699 int ds_rule_id = -1;
2701 int offset_rule_src_year;
2702 int offset_rule_src_month;
2709 offset_rule_src_month, &ds_rule_id);
2715 if (ds_rule_id != -1)
2745 const int save_time_diff)
2748 bool overlap =
true;
2752 add_time = save_time_diff;
2756 add_time = gmt_diff + save_time_diff;
2759 if (gmt_diff + save_time_diff > 0 || (
ABS (offset_rule_diff + add_time) >
ABS (gmt_diff + save_time_diff)))
2779 int year_to_apply_rule;
2781 if (src_year <= ds_rule->to_year)
2785 year_to_apply_rule = src_year;
2789 year_to_apply_rule = ds_rule->
from_year;
2794 year_to_apply_rule = src_year - 1;
2797 return year_to_apply_rule;
2818 int src_julian_date, rule_julian_date;
2819 int src_time_sec, rule_time_sec;
2822 int gmt_std_offset_sec;
2823 int total_offset_sec;
2825 int curr_offset_id = -1;
2826 int curr_ds_id = -1, applying_ds_id = -1;
2834 bool check_user_dst =
false;
2835 bool applying_with_prev_year =
false;
2836 bool applying_is_in_leap_interval =
false;
2837 int save_time = 0, src_offset_curr_off_rule = 0;
2838 int src_offset_prev_off_rule = 0;
2839 int leap_offset_rule_interval = 0;
2840 int prev_rule_julian_date = 0, prev_rule_time_sec = 0;
2841 bool try_offset_rule_overlap =
false;
2842 int second_best_applying_ds_id = -1;
2845 int offset_rule_counter = 0;
2851 total_offset_sec = tz_info->
offset;
2854 #if !defined (CS_MODE) 2886 src_julian_date = src_dt->
date;
2887 src_time_sec = src_dt->
time / 1000;
2889 for (curr_offset_id = 0; curr_offset_id < timezone->
gmt_off_rule_count; curr_offset_id++)
2892 prev_off_rule = curr_off_rule;
2907 if (src_julian_date <= rule_julian_date + 1)
2913 assert (curr_offset_id < timezone->gmt_off_rule_count - 1);
2943 applying_ds_id = -1;
2944 applying_date_diff = -1;
2945 gmt_std_offset_sec = curr_off_rule->
gmt_off;
2946 total_offset_sec = gmt_std_offset_sec;
2947 second_best_applying_ds_id = -1;
2948 second_best_applying_date_diff = -1;
2950 if (prev_off_rule !=
NULL)
2952 prev_rule_julian_date = prev_off_rule->
julian_date;
2954 leap_offset_rule_interval = curr_off_rule->
gmt_off - prev_off_rule->
gmt_off;
2959 int curr_time_offset;
2964 if (prev_off_rule !=
NULL)
2966 src_offset_prev_off_rule =
2971 FULL_DATE (src_julian_date, src_time_sec + src_offset_prev_off_rule) -
FULL_DATE (prev_rule_julian_date,
2972 prev_rule_time_sec);
2974 if (
FULL_DATE (src_julian_date, src_time_sec + curr_time_offset) <
FULL_DATE (rule_julian_date, rule_time_sec))
2976 int add_ds_save_time_diff = 0;
2977 int prev_rule_save_time = 0;
2980 if (prev_off_rule !=
NULL)
2984 add_ds_save_time_diff = curr_off_rule->
ds_ruleset;
2993 add_ds_save_time_diff -= prev_rule_save_time;
2994 leap = leap_offset_rule_interval + add_ds_save_time_diff;
2998 leap = leap_offset_rule_interval;
3002 if (try_offset_rule_overlap ==
false && leap >= 0 && (offset_rule_diff < leap))
3010 if (src_is_utc ==
false && tz_info->
zone.dst_str[0] !=
'\0' && curr_off_rule->
var_format ==
NULL 3012 || strcasecmp (curr_off_rule->
std_format, tz_info->
zone.dst_str) != 0)
3014 || strcasecmp (curr_off_rule->
save_format, tz_info->
zone.dst_str) != 0))
3016 if (next_off_rule ==
NULL || try_offset_rule_overlap ==
true)
3024 try_offset_rule_overlap =
true;
3029 else if (src_is_utc ==
false && tz_info->
zone.dst_str[0] !=
'\0' && try_offset_rule_overlap ==
true)
3031 bool overlap =
false;
3035 int prev_rule_save_time = 0;
3036 int save_time_diff = 0;
3044 save_time_diff = curr_off_rule->
ds_ruleset - prev_rule_save_time;
3050 if (overlap ==
false)
3065 if (next_off_rule ==
NULL)
3080 applying_ds_rule =
NULL;
3081 second_best_applying_ds_rule =
NULL;
3082 if (src_is_utc ==
false && tz_info->
zone.dst_str[0] !=
'\0')
3084 check_user_dst =
true;
3089 curr_ds_id = ds_ruleset->
count;
3096 for (; curr_ds_id < ds_ruleset->
count; curr_ds_id++)
3098 int ds_rule_julian_date;
3100 bool rule_matched =
false;
3101 bool is_in_leap_interval =
false;
3102 bool check_prev_year =
true;
3103 int year_to_apply_rule = 0;
3109 if (src_year + 1 < curr_ds_rule->
from_year)
3115 if (src_year - 1 > curr_ds_rule->
to_year 3130 diff =
FULL_DATE (src_julian_date, src_time_sec) - ds_rule_date;
3132 if (second_best_applying_date_diff == -1 || diff < second_best_applying_date_diff)
3134 second_best_applying_date_diff =
diff;
3135 second_best_applying_ds_id = curr_ds_id;
3136 second_best_applying_ds_rule = curr_ds_rule;
3159 rule_matched =
true;
3163 int wall_ds_rule_id;
3164 int wall_safe_julian_date;
3166 int ds_time_offset = 0;
3170 bool at_time_type_is_utc =
false;
3171 int ds_rule_time_offset_curr_off_rule = 0, add_save_time = 0;
3172 int ds_rule_time_offset_prev_off_rule = 0;
3173 int add_leap_offset_rule_interval = 0;
3180 tz_fast_find_ds_rule (tzd, ds_ruleset, wall_safe_julian_date, src_year, src_month, &wall_ds_rule_id);
3186 if (wall_ds_rule_id != -1)
3192 else if (prev_off_rule !=
NULL)
3199 add_leap_offset_rule_interval = leap_offset_rule_interval;
3204 at_time_type_is_utc =
true;
3207 if (wall_ds_rule !=
NULL && prev_off_rule !=
NULL)
3209 bool utc_time =
false;
3210 int ds_rule_time_offset;
3212 int wall_rule_julian_date;
3213 int add_save_time = 0;
3214 int year_to_apply_rule;
3219 &wall_rule_julian_date, &date_diff);
3226 year_to_apply_rule = year_to_apply_rule - 1;
3244 wall_ds_rule->
at_time + ds_rule_time_offset) -
FULL_DATE (prev_rule_julian_date,
3245 prev_rule_time_sec);
3249 int prev_rule_save_time;
3257 ds_rule_time_offset =
3261 add_save_time = save_time;
3264 if (
FULL_DATE (ds_rule_julian_date, curr_ds_rule->
at_time + add_save_time + ds_rule_time_offset) <=
3265 FULL_DATE (prev_rule_julian_date, prev_rule_time_sec))
3267 save_time = prev_rule_save_time;
3268 add_leap_offset_rule_interval = leap_offset_rule_interval;
3275 add_save_time = save_time;
3278 if (prev_off_rule !=
NULL)
3280 ds_rule_time_offset_prev_off_rule =
3283 (ds_rule_julian_date,
3284 curr_ds_rule->
at_time + add_save_time + ds_rule_time_offset_prev_off_rule) >
3285 FULL_DATE (prev_rule_julian_date, prev_rule_time_sec))
3287 add_leap_offset_rule_interval = 0;
3291 ds_rule_time_offset_curr_off_rule =
3294 if (
FULL_DATE (ds_rule_julian_date, curr_ds_rule->
at_time + add_save_time + ds_rule_time_offset_curr_off_rule)
3295 >=
FULL_DATE (rule_julian_date, rule_time_sec))
3306 ds_time_offset = gmt_std_offset_sec + curr_ds_rule->
save_time;
3310 ds_time_offset = curr_ds_rule->
save_time;
3315 ds_time_offset = curr_ds_rule->
save_time - save_time;
3319 ds_time_offset += add_leap_offset_rule_interval;
3322 if (src_is_utc ==
true)
3326 utc_src_offset = gmt_std_offset_sec + curr_ds_rule->
save_time;
3330 leap_interval = save_time - curr_ds_rule->
save_time;
3331 leap_interval -= add_leap_offset_rule_interval;
3334 ds_rule_date =
FULL_DATE (ds_rule_julian_date, ds_time_offset + curr_ds_rule->
at_time);
3335 date_diff =
FULL_DATE (src_julian_date, src_time_sec + utc_src_offset) - ds_rule_date;
3339 rule_matched =
true;
3341 if (leap_interval > 0 && date_diff < leap_interval)
3343 is_in_leap_interval =
true;
3348 if (leap_interval < 0 &&
ABS (date_diff) <=
ABS (leap_interval))
3354 if (
FULL_DATE (src_julian_date, src_time_sec + offset) <
FULL_DATE (rule_julian_date, rule_time_sec))
3363 applying_ds_id = -1;
3364 second_best_applying_ds_id = -1;
3376 if (applying_date_diff > 0 && date_diff > applying_date_diff && !applying_is_in_leap_interval)
3382 if (is_in_leap_interval || applying_is_in_leap_interval)
3390 else if (applying_ds_id != -1)
3395 if (applying_date_diff > date_diff || applying_with_prev_year)
3397 rule_matched =
false;
3403 && (applying_date_diff < 0 || date_diff < applying_date_diff || applying_is_in_leap_interval))
3405 if (is_in_leap_interval ==
true && wall_ds_rule !=
NULL && check_user_dst ==
true 3412 applying_date_diff = date_diff;
3413 applying_ds_rule = curr_ds_rule;
3414 applying_ds_id = curr_ds_id;
3415 applying_is_in_leap_interval = is_in_leap_interval;
3416 if (check_prev_year ==
false)
3418 applying_with_prev_year =
true;
3422 else if (curr_ds_rule->
from_year < src_year && check_prev_year ==
true && date_diff < 0)
3433 rule_matched =
true;
3434 check_prev_year =
false;
3440 if (applying_ds_id == -1)
3442 applying_ds_id = second_best_applying_ds_id;
3443 applying_ds_rule = second_best_applying_ds_rule;
3446 if (applying_ds_id != -1)
3448 save_time = applying_ds_rule->
save_time;
3451 if (prev_off_rule !=
NULL)
3456 if (applying_ds_id != -1)
3459 int add_ds_save_time = 0;
3462 if (
FULL_DATE (src_julian_date, src_time_sec + src_offset_curr_off_rule) >=
3463 FULL_DATE (rule_julian_date, rule_time_sec))
3470 FULL_DATE (src_julian_date, src_time_sec + src_offset_prev_off_rule) -
FULL_DATE (prev_rule_julian_date,
3471 prev_rule_time_sec);
3473 if (prev_off_rule !=
NULL)
3477 int prev_rule_save_time = 0;
3479 add_ds_save_time = save_time;
3488 add_ds_save_time -= prev_rule_save_time;
3489 leap = leap_offset_rule_interval + add_ds_save_time;
3493 leap = leap_offset_rule_interval;
3497 if (try_offset_rule_overlap ==
false && leap >= 0 && (offset_rule_diff < leap))
3508 (curr_off_rule, applying_ds_rule, tz_info->
zone.dst_str, ds_ruleset->
default_abrev) ==
false)
3510 if (next_off_rule ==
NULL || try_offset_rule_overlap ==
true)
3519 try_offset_rule_overlap =
true;
3525 else if (try_offset_rule_overlap ==
true)
3527 bool overlap =
false;
3531 int prev_rule_save_time = 0;
3532 int save_time_diff = 0;
3540 save_time_diff = save_time - prev_rule_save_time;
3546 if (overlap ==
false)
3559 if (next_off_rule ==
NULL 3560 || (
FULL_DATE (src_julian_date, src_time_sec + src_offset_curr_off_rule) <
3561 FULL_DATE (rule_julian_date, rule_time_sec)))
3564 int add_ds_save_time = 0;
3568 FULL_DATE (src_julian_date, src_time_sec + src_offset_prev_off_rule) -
FULL_DATE (prev_rule_julian_date,
3569 prev_rule_time_sec);
3571 if (prev_off_rule !=
NULL)
3575 int prev_rule_save_time = 0;
3577 add_ds_save_time = save_time;
3586 add_ds_save_time -= prev_rule_save_time;
3587 leap = leap_offset_rule_interval + add_ds_save_time;
3591 leap = leap_offset_rule_interval;
3595 if (try_offset_rule_overlap ==
false && leap >= 0 && (offset_rule_diff < leap))
3603 if (curr_ds_id == ds_ruleset->
count)
3616 if (tz_info->
zone.dst_str[0] !=
'\0' 3620 if (next_off_rule ==
NULL || try_offset_rule_overlap ==
true)
3628 try_offset_rule_overlap =
true;
3633 else if (tz_info->
zone.dst_str[0] !=
'\0' 3635 ds_ruleset->
default_abrev) ==
true && try_offset_rule_overlap ==
true)
3637 bool overlap =
false;
3641 int prev_rule_save_time = 0;
3642 int save_time_diff = 0;
3650 save_time_diff = save_time - prev_rule_save_time;
3655 if (overlap ==
false)
3672 total_offset_sec += applying_ds_rule->
save_time;
3674 assert (curr_offset_id != -1);
3675 assert (applying_ds_id != -1);
3680 if (curr_offset_id >= 0)
3684 total_offset_sec += curr_off_rule->
ds_ruleset;
3687 tz_info->
zone.offset_id = curr_offset_id;
3689 if (applying_ds_id >= 0)
3691 tz_info->
zone.dst_id = applying_ds_id;
3695 if (only_tz_adjust ==
true)
3701 if (src_dt->
date == 0)
3743 tmp_zone_info = *src_zone_info_in;
3759 if (src_zone_info_out !=
NULL)
3761 *src_zone_info_out = tmp_zone_info;
3766 if (src_zone_info_in->
type == dest_zone_info_in->
type 3768 && src_zone_info_in->
zone.zone_id == dest_zone_info_in->
zone.zone_id)
3773 if (dest_zone_info_out !=
NULL)
3775 *dest_zone_info_out = tmp_zone_info;
3780 tmp_zone_info = *dest_zone_info_in;
3791 if (dest_zone_info_out !=
NULL)
3793 *dest_zone_info_out = tmp_zone_info;
3814 TZ_ID * dest_tz_id_out)
3832 &dest_zone_info_out);
3833 if (src_tz_id_out !=
NULL)
3838 if (dest_tz_id_out !=
NULL)
3859 const char *dest_zone,
int len_dest,
DB_DATETIME * dest_dt)
3896 #define LEN_MIN_HOUR 6 3897 #define LEN_MIN_HOUR_SEC 9 3902 int dst_format_size;
3907 const char *p_dst_format =
NULL;
3908 int total_offset = 0;
3920 #if !defined (CS_MODE) 3928 sign = (tz_info.
offset < 0) ?
'-' :
'+';
3937 offset = (offset < 0) ? (-offset) :
offset;
3950 sprintf (tzr,
"%c%02d:%02d:%02d", sign, hour, min, sec);
3955 sprintf (tzr,
"%c%02d:%02d", sign, hour, min);
3969 total_offset = tz_info.
zone.p_zone_off_rule->gmt_off;
3972 total_offset += tz_info.
zone.p_ds_rule->save_time;
3974 *tzh = total_offset / 3600;
3975 *tzm = (total_offset % 3600) / 60;
3976 zone_id = tz_info.
zone.zone_id;
3977 zone_offset_id = tz_info.
zone.offset_id;
3989 const char *ds_abbr =
NULL;
3992 if (dst_id < ds_ruleset->
count)
4000 if (ds_abbr ==
NULL)
4002 p_dst_format =
NULL;
4006 snprintf (dst_format,
sizeof (dst_format) - 1, zone_off_rule->
var_format,
4007 (ds_abbr !=
NULL && *ds_abbr !=
'-') ? ds_abbr :
"");
4008 p_dst_format = dst_format;
4020 if (p_dst_format !=
NULL)
4022 dst_format_size =
strlen (p_dst_format);
4026 dst_format_size = 0;
4029 if (zone_name_size + 1 > tzr_size || dst_format_size + 1 > tzdst_size)
4036 if (p_dst_format !=
NULL)
4038 snprintf (tzr, tzr_size,
"%s", tzd->
names[zone_id].
name);
4039 snprintf (tzdst, tzdst_size,
"%s", p_dst_format);
4040 tzdst[dst_format_size] =
'\0';
4044 snprintf (tzr, tzr_size,
"%s", tzd->
names[zone_id].
name);
4047 tzr[zone_name_size] =
'\0';
4051 #undef LEN_MIN_HOUR_SEC 4075 tz_info.
offset = tzh * 3600 + tzm * 60;
4117 tz_info.
offset = tzh * 3600 + tzm * 60;
4127 dt.
time = (*time) * 1000;
4134 date_utc = utc_dt.
date;
4135 time_utc = utc_dt.
time / 1000;
4160 int index_bot, index_top;
4174 while (index_bot <= index_top)
4176 int mid = index_bot + ((index_top - index_bot) >> 1);
4181 index_bot = mid + 1;
4185 index_top = mid - 1;
4195 return index_bot - 1;
4213 const char *tzd,
const int tzd_len,
bool is_time_tz,
DB_DATETIMETZ * dt_tz)
4234 if (tzd_len + 1 > (
int)
sizeof (tz_info.
zone.dst_str))
4239 strncpy (tz_info.
zone.dst_str, tzd, tzd_len);
4240 tz_info.
zone.dst_str[tzd_len] =
'\0';
4244 tz_info.
zone.dst_str[0] =
'\0';
4253 if (is_time_tz ==
true)
4255 offset = (int) (dt->
date - utc_dt.
date) * 3600 * 24 + (int) (dt->
time - utc_dt.
time) / 1000;
4281 const int zone_id,
const char *tzd,
const int tzd_len,
4304 if (tzd_len + 1 > (
int)
sizeof (tz_info.
zone.dst_str))
4309 strncpy (tz_info.
zone.dst_str, tzd, tzd_len);
4310 tz_info.
zone.dst_str[tzd_len] =
'\0';
4314 tz_info.
zone.dst_str[0] =
'\0';
4318 dt.
time = *(time) * 1000;
4326 date_utc = utc_dt.
date;
4327 time_utc = utc_dt.
time / 1000;
4351 while (*prefix !=
'\0' && (*prefix) == (*str))
4355 if (*prefix ==
'\0')
4360 return *(
const unsigned char *) prefix - *(
const unsigned char *) str;
4373 find_timezone_from_clock (
char *timezone_name,
int buf_len)
4375 #define MAX_LINE_SIZE 256 4378 char str[MAX_LINE_SIZE + 1];
4381 fp = fopen (
"/etc/sysconfig/clock",
"r");
4387 while (fgets (str, MAX_LINE_SIZE + 1, fp) !=
NULL)
4395 zone = strstr (str,
"ZONE");
4399 while (*zone ==
' ')
4410 while (*zone ==
' ')
4421 while (*zone !=
'"' && *zone !=
'\0')
4423 timezone_name[cnt++] = *
zone;
4439 while (*zone !=
'"' && *zone !=
'\0')
4441 timezone_name[cnt++] = *
zone;
4452 timezone_name[cnt] =
'\0';
4459 #undef MAX_LINE_SIZE 4471 find_timezone_from_localtime (
char *timezone_name,
int buf_len)
4473 char linkname[PATH_MAX + 1];
4475 const char *zone_info =
"zoneinfo";
4480 memset (linkname, 0,
sizeof (linkname));
4481 r = readlink (
"/etc/localtime", linkname, PATH_MAX + 1);
4492 p = strtok (linkname,
"/");
4497 if (strcmp (p, zone_info) == 0)
4510 timezone_name[cnt++] = *
p;
4517 timezone_name[cnt++] =
'/';
4519 p = strtok (
NULL,
"/");
4522 timezone_name[cnt - 1] =
'\0';
4530 #if defined(WINDOWS) 4539 tz_get_iana_zone_id_by_windows_zone (
const char *windows_zone_name)
4543 int index_bot, index_top;
4555 index_top = tzd->windows_iana_map_count - 1;
4557 while (index_bot <= index_top)
4559 mid = index_bot + ((index_top - index_bot) >> 1);
4560 cmp_res = strcmp (windows_zone_name, tzd->windows_iana_map[mid].windows_zone);
4564 index_top = mid - 1;
4568 index_bot = mid + 1;
4572 if (strcmp (tzd->windows_iana_map[index_bot].windows_zone, windows_zone_name) != 0)
4576 return tzd->windows_iana_map[index_bot].iana_zone_id;
4590 #if defined (WINDOWS) 4592 int len_iana_zone, iana_zone_id;
4598 _get_tzname (&tzret, tzname,
sizeof (tzname), 0);
4599 iana_zone_id = tz_get_iana_zone_id_by_windows_zone (tzname);
4600 if (iana_zone_id < 0)
4602 return iana_zone_id;
4605 if (buf_len < len_iana_zone)
4609 memmove (timezone, tz_data->
timezone_names[iana_zone_id], len_iana_zone);
4610 timezone[len_iana_zone] =
'\0';
4616 env = getenv (
"TZ");
4623 strncpy (timezone, env, buf_len);
4624 timezone[buf_len] =
'\0';
4631 ret = find_timezone_from_clock (timezone, buf_len);
4634 ret = find_timezone_from_localtime (timezone, buf_len);
4652 tz_Region_system = *tz_region;
4660 #if !defined(SERVER_MODE) 4673 #if defined(SERVER_MODE) 4675 tz_get_server_tz_region_session (
void)
4684 if (session_tz_region ==
NULL)
4689 if (worker_thread_p !=
NULL)
4701 return session_tz_region;
4705 #if !defined (CS_MODE) 4721 const int col_num = 1;
4780 const int col_num = 4;
4785 int year, month, day, hour, minute, second;
4790 const char *dst_name =
NULL;
4793 char empty_string[1];
4795 empty_string[0] =
'\0';
4816 error =
db_datetime_encode (&utc_datetime, month + 1, day, year, hour, minute, second, 0);
4825 int dst_save_time = 0;
4842 tzinfo.
zone.dst_str[0] =
'\0';
4867 const char *ds_abbr =
NULL;
4870 dst_id = tzinfo.
zone.dst_id;
4880 snprintf (dst_format,
sizeof (dst_format) - 1, zone_off_rule.
var_format,
4881 (ds_abbr !=
NULL && *ds_abbr !=
'-') ? ds_abbr :
"");
4882 dst_name = dst_format;
4886 if (dst_save_time != 0)
4891 if (dst_name ==
NULL)
4893 dst_name = empty_string;
4899 if (dst_name !=
NULL)
5008 #if !defined(SERVER_MODE) 5044 const char *server_text)
5051 if (strcmp (client_checksum, server_checksum) != 0)
5081 total_offset = tz_info.
zone.p_zone_off_rule->gmt_off;
5085 total_offset += tz_info.
zone.p_ds_rule->save_time;
5089 tz_info.
offset = total_offset;
5148 return error_status;
5155 dt_tz_utc.
tz_id = *tz_id;
5166 return error_status;
5179 const char *timezone_name =
NULL;
5180 unsigned int new_zone_id;
5183 timezone_name = tz_Timezone_data.
names[tz_info->
zone.zone_id].
name;
5186 if (new_zone_id == (
unsigned int) -1)
5192 tz_info->
zone.zone_id = new_zone_id;
5237 #if defined (SA_MODE) 5238 if (tz_Is_backward_compatible_timezone[tz_info.
zone.zone_id] ==
true)
5260 src_dt.
date = date_local;
5261 src_dt.
time = time_local * 1000;
5276 tz_info.
zone.dst_str[0] =
'\0';
5284 dest_dt.
time /= 1000;
5309 #if defined (SA_MODE) 5310 if (tz_Is_backward_compatible_timezone[tz_info.
zone.zone_id] ==
true)
5345 tz_info.
zone.dst_str[0] =
'\0';
5378 #if defined (SA_MODE) 5394 src_dt.
date = date_local;
5395 src_dt.
time = time_local * 1000;
5410 dest_dt.
time /= 1000;
5433 #if defined (SA_MODE) 5483 struct tm *timeinfo;
5486 timeinfo = gmtime (&currtime);
5487 time_t utc = mktime (timeinfo);
5488 timeinfo = localtime (&currtime);
5489 time_t local = mktime (timeinfo);
5492 int offsetFromUTC = difftime (utc, local) / 60;
5494 return offsetFromUTC;
int julian_encode(int m, int d, int y)
int tz_create_session_tzid_for_time(const DB_TIME *src_time, bool src_is_utc, TZ_ID *tz_id)
#define DATE_DIFF_MATCH_SAFE_THRESHOLD_DAYS
TZ_DS_RULESET * ds_rulesets
cubthread::entry * thread_get_thread_entry_info(void)
int check_timezone_compat(const char *client_checksum, const char *server_checksum, const char *client_text, const char *server_text)
static int tz_print_tz_offset(char *result, int tz_offset)
#define BO_IS_SERVER_RESTARTED()
int tz_timestamptz_fix_zone(const DB_TIMESTAMPTZ *src_ts_tz, DB_TIMESTAMPTZ *dest_ts_tz)
DB_BIGINT tz_timestamp_encode_leap_sec_adj(const int year_century, const int year, const int mon, const int day)
void showstmt_free_array_context(THREAD_ENTRY *thread_p, SHOWSTMT_ARRAY_CONTEXT *ctx)
#define ER_TZ_INTERNAL_ERROR
static int tz_Initialized
#define TZLIB_GET_ADDR(v, SYM_NAME, SYM_TYPE, lh)
int db_add_int_to_datetime(DB_DATETIME *datetime, DB_BIGINT bi2, DB_DATETIME *result_datetime)
enum tz_region_type TZ_REGION_TYPE
#define ER_TZ_DURING_DS_LEAP
int tz_create_datetimetz_from_ses(const DB_DATETIME *dt, DB_DATETIMETZ *dt_tz)
void tz_timestamp_decode_no_leap_sec(int timestamp, int *yearp, int *monthsp, int *dayp, int *hoursp, int *minutesp, int *secondsp)
const TZ_DATA * tz_get_data(void)
TZ_DS_CHANGE_ON change_on
#define FULL_DATE(jul_date, time_sec)
#define ER_TZ_DURING_OFFSET_RULE_LEAP
static void tz_encode_tz_id(const TZ_DECODE_INFO *tz_info, TZ_ID *tz_id)
static bool is_in_overlap_interval(const TZ_TIME_TYPE time_type, const full_date_t offset_rule_diff, const full_date_t gmt_diff, const int save_time_diff)
int tz_create_datetimetz_from_offset(const DB_DATETIME *dt, const int tzh, const int tzm, DB_DATETIMETZ *dt_tz)
int tz_create_datetimetz_from_zoneid_and_tzd(const DB_DATETIME *dt, TZ_REGION *default_tz_region, const int zone_id, const char *tzd, const int tzd_len, bool is_time_tz, DB_DATETIMETZ *dt_tz)
const char * letter_abbrev
const TZ_ID * tz_get_utc_tz_id(void)
int tz_create_timestamptz_from_offset(const DB_DATE *date, const DB_TIME *time, const int tzh, const int tzm, DB_TIMESTAMPTZ *timestamp_tz)
#define ER_TZ_INCOMPATIBLE_TIMEZONE_LIBRARIES
void tz_get_session_tz_region(TZ_REGION *tz_region)
unsigned long int thread_id_t
int tz_resolve_os_timezone(char *timezone, int buf_len)
void tz_set_tz_region_system(const TZ_REGION *tz_region)
static int tz_zone_info_to_str(const TZ_DECODE_INFO *tz_info, char *tz_str, const int tz_str_size)
int tz_load_with_library_path(TZ_DATA *tzd, const char *timezone_library_path)
char * envvar_libdir_file(char *path, size_t size, const char *filename)
cubthread::manager * thread_get_manager(void)
int tz_create_datetimetz_from_parts(const int m, const int d, const int y, const int h, const int mi, const int s, const int ms, const TZ_ID *tz_id, DB_DATETIMETZ *dt_tz)
int tz_create_timestamptz_from_zoneid_and_tzd(const DB_DATE *date, const DB_TIME *time, TZ_REGION *default_tz_region, const int zone_id, const char *tzd, const int tzd_len, DB_TIMESTAMPTZ *timestamp_tz)
int tz_check_geographic_tz(const TZ_ID *tz_id)
static int starts_with(const char *prefix, const char *str)
int tz_conv_tz_time_w_zone_name(const DB_TIME *time_source, const char *source_zone, int len_source, const char *dest_zone, int len_dest, DB_TIME *time_dest)
static TZ_DATA tz_New_timezone_data
TZ_TIME_TYPE at_time_type
SHOWSTMT_ARRAY_CONTEXT * showstmt_alloc_array_context(THREAD_ENTRY *thread_p, int num_total, int num_cols)
int tz_conv_tz_datetime_w_region(const DB_DATETIME *src_dt, const TZ_REGION *src_tz_region, const TZ_REGION *dest_tz_region, DB_DATETIME *dest_dt, TZ_ID *src_tz_id_out, TZ_ID *dest_tz_id_out)
struct tz_decode_info::@31::@33 zone
#define TZ_BIT_SHIFT_TZ_ID_FLAG
static DB_DATE tz_get_current_date(void)
static int tz_conv_tz_datetime_w_zone_info(const DB_DATETIME *src_dt, const TZ_DECODE_INFO *src_zone_info_in, const TZ_DECODE_INFO *dest_zone_info_in, DB_DATETIME *dest_dt, TZ_DECODE_INFO *src_zone_info_out, TZ_DECODE_INFO *dest_zone_info_out)
static int tz_load_data_from_lib(TZ_DATA *tzd, void *lib_handle)
TZ_TIME_TYPE until_time_type
#define TZLIB_GET_VAL(v, SYM_NAME, SYM_TYPE, lh)
#define TZ_IS_ZONE_VALID_DECODE_INFO(tz_info)
TZ_REGION * session_get_session_tz_region(THREAD_ENTRY *thread_p)
int db_make_string(DB_VALUE *value, DB_CONST_C_CHAR str)
static const int tz_Days_of_month[]
int tz_str_read_number(const char *str, const char *str_end, const bool strict, const bool read_sign, int *val, const char **str_next)
int tz_get_best_match_zone(const char *name, int *size)
#define ER_TZ_INVALID_DST
int tz_create_datetimetz(const DB_DATETIME *dt, const char *tz_str, const int tz_size, const TZ_REGION *default_tz_region, DB_DATETIMETZ *dt_tz, const char **end_tz_str)
unsigned int DB_TIMESTAMP
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
char checksum[TZ_CHECKSUM_SIZE+1]
static int get_closest_ds_rule(const int src_julian_date, const int src_time_sec, const TZ_DS_RULESET *ds_ruleset, const TZ_DATA *tzd, const DS_SEARCH_DIRECTION direction)
int tz_create_session_tzid_for_datetime(const DB_DATETIME *src_dt, bool src_is_utc, TZ_ID *tz_id)
int tz_str_read_time(const char *str, const char *str_end, bool need_minutes, bool allow_sec60, int *hour, int *min, int *sec, const char **str_next)
#define ER_TIME_CONVERSION
int db_timestamp_encode_utc(const DB_DATE *date, const DB_TIME *timeval, DB_TIMESTAMP *utime)
int tz_full_timezones_start_scan(THREAD_ENTRY *thread_p, int show_type, DB_VALUE **arg_values, int arg_cnt, void **ptr)
static TZ_DATA tz_Timezone_data
char dst_str[TZ_DS_STRING_SIZE]
int tz_str_to_seconds(const char *str, const char *str_end, int *seconds, const char **str_next, const bool is_offset)
static int get_date_diff_from_ds_rule(const int src_julian_date, const int src_time_sec, const TZ_DS_RULE *ds_rule, const DS_SEARCH_DIRECTION direction, full_date_t *date_diff)
int tz_get_ds_change_julian_date_diff(const int src_julian_date, const TZ_DS_RULE *ds_rule, const int year, int *ds_rule_julian_date, full_date_t *date_diff)
int tz_id_to_str(const TZ_ID *tz_id, char *tz_str, const int tz_str_size)
static void tz_timestamp_decode_leap_sec_adj(int timestamp, int *yearp, int *monthsp, int *dayp, int *hoursp, int *minutesp, int *secondsp)
int tz_str_to_region(const char *tz_str, const int tz_str_size, TZ_REGION *tz_region)
void tz_tzid_convert_region_to_offset(TZ_ID *tz_id)
int tz_create_datetimetz_from_utc(const DB_DATETIME *src_dt, const TZ_REGION *dest_region, DB_DATETIMETZ *dest_dt_tz)
static TZ_REGION tz_Region_system
#define TZ_DS_STRING_SIZE
static int tz_get_zone_id_by_name(const char *name, const int name_size)
#define ER_TZ_INVALID_TIMEZONE
int db_get_day_of_week(int year, int month, int day)
int tz_datetimeltz_to_local(const DB_DATETIME *dt_ltz, DB_DATETIME *dt_local)
void tz_get_system_tz_region(TZ_REGION *tz_region)
void tz_timestamp_decode_sec(int timestamp, int *yearp, int *monthsp, int *dayp, int *hoursp, int *minutesp, int *secondsp)
int db_timestamp_decode_w_tz_id(const DB_TIMESTAMP *utime, const TZ_ID *tz_id, DB_DATE *date, DB_TIME *timeval)
#define TZ_INVALID_OFFSET
static int get_saving_time_from_offset_rule(const TZ_OFFSET_RULE *offset_rule, const TZ_DATA *tzd, int *save_time)
DB_VALUE * showstmt_alloc_tuple_in_context(THREAD_ENTRY *thread_p, SHOWSTMT_ARRAY_CONTEXT *ctx)
int conv_tz(void *p_out, const void *p_in, DB_TYPE type)
int db_put_internal(DB_OBJECT *obj, const char *name, DB_VALUE *value)
unsigned char day_of_month
void tz_set_new_timezone_data(const TZ_DATA *data)
int count(int &result, const cub_regex_object ®, const std::string &src, const int position, const INTL_CODESET codeset)
static int tz_fast_find_ds_rule(const TZ_DATA *tzd, const TZ_DS_RULESET *ds_ruleset, const int src_julian_date, const int src_year, const int src_month, int *ds_rule_id)
#define ER_DATE_CONVERSION
#define TZ_MASK_TZ_ID_FLAG
static void error(const char *msg)
int tz_timezones_start_scan(THREAD_ENTRY *thread_p, int show_type, DB_VALUE **arg_values, int arg_cnt, void **ptr)
unsigned char day_of_week
#define ER_TZ_GEOGRAPHIC_ZONE
void tz_id_to_region(const TZ_ID *tz_id, TZ_REGION *tz_region)
int tz_utc_datetimetz_to_local(const DB_DATETIME *dt_utc, const TZ_ID *tz_id, DB_DATETIME *dt_local)
static void * tz_Lib_handle
#define snprintf_dots_truncate(dest, max_len,...)
int tz_get_first_weekday_around_date(const int year, const int month, const int weekday, const int ref_day, const bool before)
int tz_conv_tz_datetime_w_zone_name(const DB_DATETIME *src_dt, const char *source_zone, int len_source, const char *dest_zone, int len_dest, DB_DATETIME *dest_dt)
#define APPLY_NEXT_OFF_RULE()
static void tz_decode_tz_id(const TZ_ID *tz_id, const bool is_full_decode, TZ_DECODE_INFO *tz_info)
static bool tz_check_ds_match_string(const TZ_OFFSET_RULE *off_rule, const TZ_DS_RULE *ds_rule, const char *ds_string, const char *default_abrev)
void julian_decode(int jul, int *monthp, int *dayp, int *yearp, int *weekp)
enum ds_search_direction DS_SEARCH_DIRECTION
const TZ_DATA * tz_get_new_timezone_data(void)
int db_datetime_encode(DB_DATETIME *datetime, int month, int day, int year, int hour, int minute, int second, int millisecond)
static int tz_datetime_utc_conv(const DB_DATETIME *src_dt, TZ_DECODE_INFO *tz_info, bool src_is_utc, bool only_tz_adjust, DB_DATETIME *dest_dt)
char * prm_get_string_value(PARAM_ID prm_id)
const char * tz_get_system_timezone(void)
int tz_check_session_has_geographic_tz(void)
const char * default_abrev
int db_make_string_copy(DB_VALUE *value, DB_CONST_C_CHAR str)
int tz_get_offset_in_mins()
bool prm_get_bool_value(PARAM_ID prm_id)
int tz_create_timestamptz(const DB_DATE *date, const DB_TIME *time, const char *tz_str, const int tz_size, const TZ_REGION *default_tz_region, DB_TIMESTAMPTZ *ts_tz, const char **end_tz_str)
TZ_REGION * tz_get_client_tz_region_session(void)
entry * find_by_tid(thread_id_t tid)
const char * tz_get_session_local_timezone(void)
void db_timestamp_decode_utc(const DB_TIMESTAMP *utime, DB_DATE *date, DB_TIME *timeval)
static int get_year_to_apply_rule(const int src_year, const TZ_DS_RULE *ds_rule)
static bool tz_get_leapsec_support(void)
int db_make_null(DB_VALUE *value)
#define TZ_MAX_FORMAT_SIZE
#define ER_TZ_INVALID_COMBINATION
static const int tz_Days_up_to_month[]
static int tz_load_library(const char *lib_file, void **handle)
TZ_OFFSET_RULE * p_zone_off_rule
const TZ_REGION * tz_get_utc_tz_region(void)
int put_timezone_checksum(char *checksum)
int tz_get_timezone_offset(const char *tz_str, int tz_size, char *result, DB_DATETIME *utc_datetime)
static int tz_offset(const bool src_is_utc, const TZ_TIME_TYPE until_time_type, const int gmt_offset_sec, const int ds_save_time)
#define TZ_MAX_JULIAN_DATE
int tz_explain_tz_id(const TZ_ID *tz_id, char *tzr, const int tzr_size, char *tzdst, const int tzdst_size, int *tzh, int *tzm)
static int set_new_zone_id(TZ_DECODE_INFO *tz_info)
#define TZLIB_SYMBOL_NAME_SIZE
TZ_LEAP_SEC * ds_leap_sec
void db_time_decode(DB_TIME *timeval, int *hourp, int *minutep, int *secondp)
int tz_create_session_tzid_for_timestamp(const DB_UTIME *src_ts, TZ_ID *tz_id)
static void tz_encode_tz_region(const TZ_DECODE_INFO *tz_info, TZ_REGION *tz_region)
static int tz_str_timezone_decode(const char *tz_str, const int tz_str_size, TZ_DECODE_INFO *tz_info, const char **tz_end)
#define TIME_OFFSET(is_utc, offset)
static TZ_REGION tz_Region_session
TZ_OFFSET_RULE * offset_rules
static void tz_decode_tz_region(const TZ_REGION *tz_region, TZ_DECODE_INFO *tz_info)
void tz_set_data(const TZ_DATA *data)
static const TZ_REGION * tz_get_invalid_tz_region(void)
int tz_datetimetz_fix_zone(const DB_DATETIMETZ *src_dt_tz, DB_DATETIMETZ *dest_dt_tz)
#define DATE_DIFF_MATCH_SAFE_THRESHOLD_SEC