@@ -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}
0 commit comments