如何获取 MySQL 的当前时区?

Posted

技术标签:

【中文标题】如何获取 MySQL 的当前时区?【英文标题】:How do I get the current time zone of MySQL? 【发布时间】:2011-02-25 10:18:44 【问题描述】:

谁知道mysql中是否有这样的功能?

更新

这不会输出任何有效信息:

mysql> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| SYSTEM             | SYSTEM              |
+--------------------+---------------------+

或者也许 MySQL 本身无法确切知道使用的time_zone,那很好,我们可以在这里涉及php,只要我能得到不像SYSTEM 这样的有效信息...

【问题讨论】:

“我们可以在这里涉及 PHP” - 那个 php 实例是否总是与 MySQL 服务器在同一台机器上? 是的,他们将在同一台机器上。 尝试@@system_time_zone,如下面我的回答所述。 既然问了这个问题,又添加了更多答案,也许重新考虑接受的答案? 即使 MySQL 服务器和 PHP 在同一台服务器上,它们可能会根据它们的设置选择不同的时区。这些时间可能与您的操作系统和 PHP/MySQL 显示的不同。 【参考方案1】:

查看MySQL Server Time Zone Support 和system_time_zone 系统变量。这有帮助吗?

【讨论】:

@user 您能否在问题中详细说明您正在寻找什么信息(服务器的时区?客户端的时区?)以及您可以使用哪些工具?你提到PHP。可以访问命令行吗? @user 同样,我发现您对那些试图提供帮助的人的回答有点不屑一顾,而不是完全错误。我不介意投票或失分,但你的态度并不完全鼓励进一步寻找解决方案。 @user 正如我所说,您的态度并没有促使我为您研究进一步的答案,尤其是鉴于您提供的信息很少。对不起。 @user198729:哇,失去态度。佩卡是那种真正能帮助别人的人。如果仅凭礼貌不足以激励您,请尝试自我利益。 只是我的想法:如果用户对我的帖子做了同样的事情,我不会生气。我的意思是,截止日期的压力或挫败感确实会在人们周围增加一些粗糙的边缘,但我认为我们应该在某种程度上允许它。也许我太宽容了:|【参考方案2】:

来自手册(section 9.6):

全球和客户特定时区的当前值可以这样检索: mysql> SELECT @@global.time_zone, @@session.time_zone;

编辑 如果 MySQL 设置为使用系统的时区,上述返回 SYSTEM,这没什么帮助。由于您使用的是 PHP,如果来自 MySQL 的答案是SYSTEM,那么您可以通过date_default_timezone_get 询问系统它是 使用的时区。 (当然,正如 VolkerK 指出的那样,PHP 可能在不同的服务器上运行,但假设是,假设 Web 服务器和它正在与之交谈的数据库服务器 设置为 [如果实际上不是 in] 相同的时区不是一个巨大 飞跃。)但请注意(与 MySQL 一样),您可以设置 PHP 使用的时区 (date_default_timezone_set),这意味着它可能会报告与操作系统使用的值不同的值。如果您可以控制 PHP 代码,那么您应该知道自己是否这样做并且没问题。

但是 MySQL 服务器正在使用哪个时区的整个问题可能是切线的,因为询问服务器它所在的时区不会告诉您关于数据库中数据的绝对没有。请继续阅读以了解详细信息:

进一步讨论

如果您可以控制服务器,当然可以确保时区是一个已知数量。如果您无法控制服务器,则可以像这样设置 连接 使用的时区:

set time_zone = '+00:00';

这会将时区设置为 GMT,因此任何进一步的操作(如 now())都将使用 GMT。

但请注意,时间和日期值与 MySQL 中的时区信息一起存储:

mysql> create table foo (tstamp datetime) Engine=MyISAM;
Query OK, 0 rows affected (0.06 sec)

mysql> insert into foo (tstamp) values (now());
Query OK, 1 row affected (0.00 sec)

mysql> set time_zone = '+01:00';
Query OK, 0 rows affected (0.00 sec)

mysql> select tstamp from foo;
+---------------------+
| tstamp              |
+---------------------+
| 2010-05-29 08:31:59 |
+---------------------+
1 row in set (0.00 sec)

mysql> set time_zone = '+02:00';
Query OK, 0 rows affected (0.00 sec)

mysql> select tstamp from foo;
+---------------------+
| tstamp              |
+---------------------+
| 2010-05-29 08:31:59 |      <== Note, no change!
+---------------------+
1 row in set (0.00 sec)

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2010-05-29 10:32:32 |
+---------------------+
1 row in set (0.00 sec)

mysql> set time_zone = '+00:00';
Query OK, 0 rows affected (0.00 sec)

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2010-05-29 08:32:38 |      <== Note, it changed!
+---------------------+
1 row in set (0.00 sec)

所以知道服务器的时区只对获取当前时间的函数很重要,例如now()unix_timestamp()等;它不会告诉您有关数据库数据中的日期使用的时区的任何信息。您可能会选择假设它们是使用服务器的时区编写的,但这种假设很可能是有缺陷的。要了解存储在数据中的任何日期或时间的时区,您必须确保它们与时区信息一起存储,或者(像我一样)确保它们始终采用 GMT。

为什么假设数据是使用服务器的时区写入有缺陷的?好吧,一方面,数据可能是使用设置不同时区的连接写入的。数据库可能已从一台服务器移动到另一台服务器,其中服务器位于不同的时区(当我继承一个从德克萨斯州搬到加利福尼亚州的数据库时,我遇到了这种情况)。但是即使数据是写在服务器上的,用它当前的时区,它仍然是模棱两可的。去年,在美国,夏令时于 11 月 1 日凌晨 2:00 关闭。假设我的服务器位于使用太平洋时区的加利福尼亚州,并且我在数据库中有值 2009-11-01 01:30:00。那是什么时候?那是太平洋夏令时间 11 月 1 日凌晨 1:30,还是太平洋标准时间 11 月 1 日凌晨 1:30(一小时后)?你完全没有办法知道。道德:始终以 GMT 存储日期/时间(不执行 DST),并在必要时转换为所需的时区。

【讨论】:

只是好奇,为什么我们必须自己设置时区然后检索它?那种违背目的不是吗?我的意思是,我想向 MySQL 询问时区,因为我不知道答案。也许我很困惑,弄错了。谁能解释一下? @Senthil mySQL DATETIME 类型不包含时区信息。因此,我认为这里的预期基本理念是让 mySQL 尽可能地无视时区 - 这意味着用户坚持使用一个时区,无论是 UTC 还是服务器所在的时区,将所有内容存储在该区域中,并且在应用程序级别或使用 CONVERT_TZ() (dev.mysql.com/doc/refman/5.0/en/…) 进行任何转换 谢谢,但是这个问题还没有解决,如何通过 PHP 中now() 的结果获取 tz 信息? 我完全同意“保存时间戳时坚持一个时区”部分..但是这个->“..或服务器所在的时区..”你是怎么发现的?假设您将所有时间戳值保存为 UTC。但是您的服务器位于其他时区,您希望根据 that 时区显示时间戳值。那么你怎么知道你的服务器在哪个时区呢?只有这样你才能将一些值传递给 CONVERT_TZ() 进行转换,对吗? @user198729:我刚刚更新了答案,但是坦率地说,最好的方法是自己在连接上设置时区(正如答案已经说过的那样),因为受影响的只是功能您将调用,不是存储在服务器中的数据。【参考方案3】:

下面的查询返回当前会话的时区。

select timediff(now(),convert_tz(now(),@@session.time_zone,'+00:00'));

【讨论】:

这确实是正确的答案,因为它表明'SYSTEM'在转换中被识别为时区,使其完全足以转换例如NOW() 进入任何时区。 谢谢,使用这个我能够得到我想要的格式:select time_format(timediff(now(),convert_tz(now(),@@session.time_zone,'+00:00')),'%H%i'); SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP) 更简单。 SELECT TIMESTAMPDIFF(SECOND, NOW(), UTC_TIMESTAMP); 以秒为单位。【参考方案4】:

简单地说 SELECT @@system_time_zone;

返回PST(或与您的系统相关的任何内容)。

如果您尝试确定会话时区,可以使用以下查询:SELECT IF(@@session.time_zone = 'SYSTEM', @@system_time_zone, @@session.time_zone);

如果会话时区与系统时区不同,它将返回会话时区。

【讨论】:

唯一的缺点是,如果时区由于夏令时更改而更改,它仍然会报告在启动服务器时“记住”的时区,请参阅mysql bug 9518 还有另一个缺点 - 看起来它返回了系统语言环境中的某些内容,因此它可以显示类似 �������� ���� (����)【参考方案5】:

正如Jakub Vrána(创建者或Adminer 和NotORM)在cmets 中提到的,在TIME 中选择当前时区偏移量使用:

SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);

如果您的时区在该日期是 +2:00,它将返回:02:00:00

我在这里做了一个备忘单:Should MySQL have its timezone set to UTC?

【讨论】:

SELECT TIMESTAMPDIFF(SECOND, NOW(), UTC_TIMESTAMP); 以秒为单位获得差异。 @philfreo 的附加组件 - 请注意,与 TIMEDIFF 相比,TIMESTAMPDIFF 中的参数应颠倒。举这个答案中给出的例子,如果TIMEDIFF返回02:00:00,如果单位是HOUR,则对应的TIMESTAMPDIFF将返回-2,如果单位是MINUTE,则返回-120等。要获得与时区对应的符号,请交换参数:SELECT TIMESTAMPDIFF(MINUTE, UTC_TIMESTAMP, NOW()) 将返回预期的120 时区 +2:00。指定分钟的原因是有几个时区偏移 30 或 45 分钟,请参阅en.wikipedia.org/wiki/Time_zone 这是一个比公认答案更好的答案,因为它直接回答了问题并给出了解决方案,而不仅仅是理论。【参考方案6】:

你只需要在更改系统时区后重新启动mysqld..

MySQL 的全球时区采用系统时区。当你改变系统的任何此类属性时,你只需要重新启动 Mysqld。

【讨论】:

在操作系统上更改时区后,mysql插入将使用新时区但选择now();并选择 current_timestamp;命令仍将使用旧时区。要同步所有这些,必须重新启动 mysql 服务。【参考方案7】:

如果您需要将 GMT 差异作为 整数

SELECT EXTRACT(HOUR FROM (TIMEDIFF(NOW(), UTC_TIMESTAMP))) AS `timezone`

【讨论】:

错了。不适用于 IRST 等不是精确整数小时的时区。 (+3:30)timeanddate.com/time/zones/irst【参考方案8】:

将虚拟记录插入您的一个具有时间戳的数据库中 选择该记录并获取时间戳的值。 删除那条记录。确定服务器用于写入数据的时区并忽略 PHP 时区。

【讨论】:

【参考方案9】:

可能是

select timediff(current_time(),utc_time())

您不会通过这种方式直接获取时区值。

@@global.time_zone不能使用,因为它是一个变量,它返回值'SYSTEM'

如果您需要使用session SET TIME_ZONE = 在更改时区的会话中使用您的查询,那么您将使用@@session.time_zone 来实现。如果查询@@global.time_zone,则得到'SYSTEM'

如果您尝试将datediffdate_subtimediffnow()utc_time() 结合使用,那么您可能会遇到转换问题。

但上面建议的内容可能至少适用于某些服务器版本。我的版本是 5.5.43-37,是托管解决方案。

【讨论】:

这并没有明确回答问题。也许你可以edit它来专注于提出的问题。【参考方案10】:

我的 PHP 框架使用

SET LOCAL time_zone='Whatever'

连接后开启,其中 'Whatever' == date_default_timezone_get()

不是我的解决方案,但这可以确保 MySQL 服务器的 SYSTEM 时区始终与 PHP 的时区相同

所以,是的,PHP 是高度参与的并且可以影响它

【讨论】:

【参考方案11】:

要获取 mysql 的当前时区,您可以执行以下操作:

 SELECT @@system_time_zone;   # from this you can get the system timezone 
 SELECT IF(@@session.time_zone = 'SYSTEM', @@system_time_zone, @@session.time_zone) # This will give you time zone if system timezone is different from global timezone

现在如果你想更改 mysql 时区,那么:

 SET GLOBAL time_zone = '+00:00';   # this will set mysql timezone in UTC
 SET @@session.time_zone = "+00:00";  # by this you can chnage the timezone only for your particular session 

【讨论】:

【参考方案12】:

您可以尝试以下方法:

select sec_to_time(TIME_TO_SEC( curtime()) + 48000);

在这里你可以指定你的时差为秒

【讨论】:

您不应该添加和减去偏移量。有日光说规则等,这是一个雷区【参考方案13】:

使用LPAD(TIME_FORMAT(TIMEDIFF(NOW(), UTC_TIMESTAMP),’%H:%i’),6,’+') 获取MySQL 时区格式的值,您可以方便地使用CONVERT_TZ()。请注意,您获得的时区偏移量仅在评估表达式的时刻有效,因为如果您有夏令时,偏移量可能会随时间变化。然而,该表达式与NOW() 一起用于存储与本地时间的偏移量,这消除了NOW() 产生的含义。 (在 DST 时区中,NOW() 每年跳回一小时,因此对于不同的时间点有一些重复值。

【讨论】:

【参考方案14】:

要根据您的时区获取当前时间,您可以使用以下命令(在我的情况下为“+5:30”)

选择 DATE_FORMAT(convert_tz(now(),@@session.time_zone,'+05:30') ,'%Y-%m-%d')

【讨论】:

【参考方案15】:

尝试使用以下代码:

//ASP CLASSIC
Set dbdate = Server.CreateObject("ADODB.Recordset")
dbdate.ActiveConnection = MM_connection
dbdate.Source = "SELECT NOW() AS currentserverdate "
dbdate.Open()
currentdate = dbdate.Fields("currentserverdate").Value
response.Write("Server Time is "&currentdate)
dbdate.Close()
Set dbdate = Nothing

【讨论】:

【参考方案16】:

描述中提到的命令返回“SYSTEM”,表示它采用服务器的时区。这对我们的查询没有用。

以下查询将有助于了解时区

SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP) as GMT_TIME_DIFF;

以上查询将为您提供相对于协调世界时 (UTC) 的时间间隔。因此,您可以轻松分析时区。如果数据库时区是 IST,则输出将为 5:30

UTC_TIMESTAMP

在 MySQL 中,UTC_TIMESTAMP 以 'YYYY-MM-DD HH:MM:SS' 或 YYYYMMDDHHMMSS.uuuuuu 格式返回当前 UTC 日期和时间值,具体取决于函数的用法,即在字符串或数字上下文中.

现在()

NOW() 函数。 MySQL NOW() 根据函数的上下文(数字或字符串)以 'YYYY-MM-DD HH:MM:SS' 格式或 YYYYMMDDHHMMSS.uuuuuu 格式返回当前日期和时间的值。 CURRENT_TIMESTAMP、CURRENT_TIMESTAMP()、LOCALTIME、LOCALTIME()、LOCALTIMESTAMP、LOCALTIMESTAMP() 是 NOW() 的同义词。

【讨论】:

【参考方案17】:

对于任何来查找mysql db的时区的人。

通过此查询,您可以获得当前时区:

mysql> SELECT @@system_time_zone as tz;
+-------+
|  tz   |
+-------+
|  CET  |
+-------+

【讨论】:

以上是关于如何获取 MySQL 的当前时区?的主要内容,如果未能解决你的问题,请参考以下文章

Rails:使用Heroku时如何获取当前用户的时区

如何在 Java 中获取时区的当前日期和时间?

如何在javascript中获取时区的当前日期

JS:如何获取时区

导入 pytz 失败时如何获取太平洋时区的当前时间?

如何在 Python 中获取或打印 GMT 时区的当前日期时间? [复制]