forked from alibaba/AliSQL
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathduckdb_timezone.cc
More file actions
116 lines (92 loc) · 3.92 KB
/
duckdb_timezone.cc
File metadata and controls
116 lines (92 loc) · 3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*****************************************************************************
Copyright (c) 2025, Alibaba and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License, version 2.0, as published by the
Free Software Foundation.
This program is also distributed with certain software (including but not
limited to OpenSSL) that is licensed under separate terms, as designated in a
particular file or component or in included license documentation. The authors
of MySQL hereby grant you an additional permission to link the program and
your derivative works with the separately licensed software that they have
included with MySQL.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
#include "sql/duckdb/duckdb_timezone.h"
#include "sql/derror.h"
#include "my_time.h"
namespace myduck {
std::map<int64_t, std::string> TimeZoneOffsetHelper::timezone_offset_map;
/**
Retrieves the timezone offset of the system in seconds.
This function calculates the difference in seconds between the local system
time and Coordinated Universal Time (UTC). It uses the `localtime_r` function
to obtain the local time and then computes the offset by comparing the seconds
since the Unix epoch (1970-01-01 00:00:00 UTC) with offsets get by
my_system_gmt_sec.
@return The timezone offset in seconds.
*/
static my_time_t get_system_timezone_offset() {
time_t seconds_os;
struct tm l_time;
seconds_os = time(nullptr);
localtime_r(&seconds_os, &l_time);
MYSQL_TIME t;
t.year = static_cast<uint>(l_time.tm_year) + 1900;
t.month = static_cast<uint>(l_time.tm_mon) + 1;
t.day = static_cast<uint>(l_time.tm_mday);
t.hour = static_cast<uint>(l_time.tm_hour);
t.minute = static_cast<uint>(l_time.tm_min);
t.second = static_cast<uint>(l_time.tm_sec);
t.time_type = MYSQL_TIMESTAMP_DATETIME;
t.neg = false;
t.second_part = 0;
/* Compute seconds since 1970-01-01 00:00:00 */
my_time_t days =
calc_daynr(static_cast<uint>(t.year), static_cast<uint>(t.month),
static_cast<uint>(t.day)) -
static_cast<my_time_t>(days_at_timestart);
my_time_t seconds =
days * SECONDS_IN_24H + (static_cast<int64_t>(t.hour) * 3600 +
static_cast<int64_t>(t.minute * 60 + t.second));
/* Get my_time_t form by system time zone. */
my_time_t not_used_tz;
bool not_used_gap;
my_time_t seconds_syszone = my_system_gmt_sec(t, ¬_used_tz, ¬_used_gap);
assert(seconds_syszone == seconds_os);
return (seconds - seconds_syszone);
}
std::string get_timezone_according_thd(THD *thd, std::string &warn_msg) {
Time_zone *tz = thd->variables.time_zone;
std::string target_tzname;
switch (tz->get_timezone_type()) {
case Time_zone::TZ_SYSTEM: {
/* Convert system timezone. */
my_time_t offset = get_system_timezone_offset();
target_tzname =
TimeZoneOffsetHelper::get_name_by_offset(offset, warn_msg);
break;
}
case Time_zone::TZ_DB: {
/* We believe mysql's time_zone name is valid for duckdb. */
target_tzname =
std::string(tz->get_name()->ptr(), tz->get_name()->length());
break;
}
case Time_zone::TZ_OFFSET: {
target_tzname = TimeZoneOffsetHelper::get_name_by_offset(
tz->get_timezone_offset(), warn_msg);
break;
}
case Time_zone::TZ_UTC: {
assert(0); // no reason
}
}
return target_tzname;
}
} // namespace myduck