Skip to content

Commit 7cf19b5

Browse files
committed
数据库驱动增加时区设置,统一使用timezone参数配置
1 parent 6e5d010 commit 7cf19b5

File tree

7 files changed

+117
-0
lines changed

7 files changed

+117
-0
lines changed

src/db/PDOConnection.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ abstract class PDOConnection extends Connection
8585
'break_match_str' => [],
8686
// 自动参数绑定
8787
'auto_param_bind' => true,
88+
// 数据库时区设置
89+
'timezone' => '',
8890
];
8991

9092
/**
@@ -586,6 +588,9 @@ public function connect(array $config = [], $linkNum = 0, $autoConnection = fals
586588
$this->trigger('CONNECT:[ UseTime:' . number_format(microtime(true) - $startTime, 6) . 's ] ' . $config['dsn']);
587589
}
588590

591+
// 设置数据库时区
592+
$this->setTimezone($this->links[$linkNum], $config['timezone']);
593+
589594
$this->db->trigger('after_connect', $this->links[$linkNum]);
590595
return $this->links[$linkNum];
591596
} catch (\PDOException $e) {
@@ -2007,4 +2012,43 @@ public function commitXa(string $xid): void
20072012
public function rollbackXa(string $xid): void
20082013
{
20092014
}
2015+
2016+
/**
2017+
* 设置数据库时区.
2018+
*
2019+
* @param PDO $pdo PDO实例
2020+
* @param string $timezone 时区名称,如 'Asia/Shanghai' 或 '+08:00'
2021+
*
2022+
* @return void
2023+
*/
2024+
protected function setTimezone(PDO $pdo, string $timezone): void
2025+
{
2026+
if (empty($timezone)) {
2027+
return;
2028+
}
2029+
2030+
try {
2031+
$sql = $this->getSetTimezoneSql($timezone);
2032+
if (!empty($sql)) {
2033+
$pdo->exec($sql);
2034+
}
2035+
} catch (\Exception $e) {
2036+
// 时区设置失败,记录日志但不中断连接
2037+
$this->db->log('Set timezone failed: ' . $e->getMessage(), 'warning');
2038+
}
2039+
}
2040+
2041+
/**
2042+
* 获取设置时区的SQL语句.
2043+
* 子类应重写此方法以提供数据库特定的时区设置SQL.
2044+
*
2045+
* @param string $timezone 时区名称
2046+
*
2047+
* @return string
2048+
*/
2049+
protected function getSetTimezoneSql(string $timezone): string
2050+
{
2051+
// 默认实现,子类应重写此方法
2052+
return '';
2053+
}
20102054
}

src/db/connector/Mongo.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ class Mongo extends Connection
106106
'pk_convert_id' => false,
107107
// typeMap
108108
'type_map' => ['root' => 'array', 'document' => 'array'],
109+
// 时区设置(MongoDB使用UTC,建议在应用层处理时区转换)
110+
'timezone' => '',
109111
];
110112

111113
/**
@@ -177,6 +179,13 @@ public function connect(array $config = [], $linkNum = 0)
177179
// 记录数据库连接信息
178180
$this->trigger('CONNECT:[ UseTime:' . number_format(microtime(true) - $startTime, 6) . 's ] ' . $config['dsn']);
179181
}
182+
183+
// Note: MongoDB 使用 UTC 时间存储,建议在应用层处理时区转换
184+
// 时区配置 $config['timezone'] 可用于记录连接的期望时区
185+
if (!empty($config['timezone'])) {
186+
// 记录时区配置,但不实际设置(MongoDB 内部使用 UTC)
187+
$this->db->log('Timezone setting: ' . $config['timezone'] . ' (Note: MongoDB uses UTC internally)', 'info');
188+
}
180189
}
181190

182191
return $this->links[$linkNum];

src/db/connector/Mysql.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,16 @@ protected function restoreBufferedMode(): void
212212
$this->linkID->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
213213
}
214214
}
215+
216+
/**
217+
* 获取设置时区的SQL语句.
218+
*
219+
* @param string $timezone 时区名称,如 'Asia/Shanghai' 或 '+08:00'
220+
*
221+
* @return string
222+
*/
223+
protected function getSetTimezoneSql(string $timezone): string
224+
{
225+
return "SET time_zone = '$timezone'";
226+
}
215227
}

src/db/connector/Oracle.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,16 @@ protected function supportSavepoint(): bool
122122
{
123123
return true;
124124
}
125+
126+
/**
127+
* 获取设置时区的SQL语句.
128+
*
129+
* @param string $timezone 时区名称,如 'Asia/Shanghai' 或 '+08:00'
130+
*
131+
* @return string
132+
*/
133+
protected function getSetTimezoneSql(string $timezone): string
134+
{
135+
return "ALTER SESSION SET TIME_ZONE = '$timezone'";
136+
}
125137
}

src/db/connector/Pgsql.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,16 @@ protected function supportSavepoint(): bool
110110
{
111111
return true;
112112
}
113+
114+
/**
115+
* 获取设置时区的SQL语句.
116+
*
117+
* @param string $timezone 时区名称,如 'Asia/Shanghai' 或 '+08:00'
118+
*
119+
* @return string
120+
*/
121+
protected function getSetTimezoneSql(string $timezone): string
122+
{
123+
return "SET timezone = '$timezone'";
124+
}
113125
}

src/db/connector/Sqlite.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,18 @@ protected function supportSavepoint(): bool
9494
{
9595
return true;
9696
}
97+
98+
/**
99+
* 获取设置时区的SQL语句.
100+
*
101+
* @param string $timezone 时区名称,如 'Asia/Shanghai' 或 '+08:00'
102+
*
103+
* @return string SQLite 不支持时区设置,返回空字符串
104+
*/
105+
protected function getSetTimezoneSql(string $timezone): string
106+
{
107+
// SQLite 是嵌入式数据库,不支持时区设置
108+
// 建议在应用层处理时区转换
109+
return '';
110+
}
97111
}

src/db/connector/Sqlsrv.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,18 @@ public function getTables(string $dbName = ''): array
128128

129129
return $info;
130130
}
131+
132+
/**
133+
* 获取设置时区的SQL语句.
134+
*
135+
* @param string $timezone 时区名称,如 'Asia/Shanghai' 或 '+08:00'
136+
*
137+
* @return string
138+
*/
139+
protected function getSetTimezoneSql(string $timezone): string
140+
{
141+
// SQL Server 使用 SET TIME ZONE 命令
142+
// 注意:SQL Server 2016 及以上版本才支持此命令
143+
return "SET TIME ZONE '$timezone'";
144+
}
131145
}

0 commit comments

Comments
 (0)