如何获取MySQL的当前时区?


217

有人知道MySQL中是否有这样的功能吗?

更新

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

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

或者也许MySQL本身不知道确切time_zone使用了什么,那很好,我们可以PHP在这里涉及,只要我能获得不像SYSTEM...


3
“我们可以在这里使用PHP”-php的实例是否始终与MySQL服务器位于同一台计算机上?
VolkerK 2010年

是的,他们将在同一台机器上。
user198729 2010年

10
尝试@@system_time_zone按照我在下面的答案中所述。
安德鲁

由于提出了该问题,因此添加了更多答案,也许重新考虑接受的答案?
Timo Huovinen 2014年

1
即使MySQL服务器和PHP位于同一服务器上,它们也可以根据其设置选择不同的时区。这些时间可能不同于您的OS和PHP / MySQL所显示的时间。
Bimal Poudel,2014年

Answers:


226

从手册(第9.6节):

可以按以下方式检索全局时区和特定于客户时区的当前值:
mysql> SELECT @@global.time_zone, @@session.time_zone;

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

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

进一步讨论

如果您控制服务器,那么当然可以确保时区是已知数量。如果您不受服务器的控制,则可以这样设置连接使用的时区:

set time_zone = '+00:00';

这样now()会将时区设置为GMT,以便任何进一步的操作(如)都将使用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()等; 它并没有告诉您数据库数据中的日期正在使用哪个时区。您可能会选择假设它们是使用服务器的时区编写的,但是这种假设很可能是有缺陷的。要知道数据中存储的任何日期或时间的时区,您必须确保它们与时区信息一起存储,或者(就像我一样)确保它们始终位于格林尼治标准时间。

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


5
@ user198729:这并不是没有意义的,尽管它没有我希望的那样有用。这意味着什么:问操作系统,MySQL就是奴隶。
TJ Crowder 2010年

很好奇,为什么我们必须自己设置时区然后再检索?那种失败的目的不是吗?我的意思是,我想询问MySQL的时区,因为我不知道答案。也许我很困惑,弄错了事情。有人可以解释吗?
森希尔(Senthil)2010年

1
@Senthil mySQL DATETIME类型不包含时区信息。因此,我认为这里的基本逻辑是使mySQL尽可能避免时区盲目-这意味着用户必须坚持一个时区(UTC或服务器所在的时区),并将所有内容存储在该时区中,在应用程序级别或使用CONVERT_TZ()dev.mysql.com/doc/refman/5.0/en/…)进行任何转换,至少,这就是我一直了解mySQL在此字段中提供的稀疏选项的方式。
Pekka 2010年

谢谢,但是这仍然没有解决,如何通过now()PHP 的结果获取tz信息?
user198729

我完全同意“保存时间戳时坚持一个时区”这一部分。但是,这->“ ..或服务器所在的时区。”您如何发现这一点?假设您将所有时间戳记值都保存为UTC。但是您的服务器位于其他时区,并且您想根据时区显示时间戳值。那么,您如何知道服务器所在的时区?只有这样,您才能将某些值传递给CONVERT_TZ()进行转换,对吗?
Senthil

196

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

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

6
这确实是正确的答案,因为它表明“ SYSTEM”被识别为转换时区,从而足以将例如NOW()转换为任何时区。
nilskp 2011年

5
谢谢你,使用这个我能得到我想要的格式:select time_format(timediff(now(),convert_tz(now(),@@session.time_zone,'+00:00')),'%H%i');
jordanbtucker 2012年

97
SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP)更简单。
2013年

3
SELECT TIMESTAMPDIFF(SECOND, NOW(), UTC_TIMESTAMP);以秒为单位获得差异。
philfreo 2015年

106

只是 SELECT @@system_time_zone;

返回值PST(或与系统相关的任何值)。

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

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


6
唯一的缺点是,如果由于夏令时更改而导致时区更改,它仍将报告启动服务器时已“记住”的时区,请参见mysql bug 9518
标记

72

正如JakubVrána(创建者或AdminerNotORM)在评论中提到的那样,选择正在TIME使用的当前时区偏移量:

SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);

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

我在这里做了一个备忘单:MySQL是否应该将其时区设置为UTC?


SELECT TIMESTAMPDIFF(SECOND, NOW(), UTC_TIMESTAMP);以秒为单位获得差异。
philfreo 2015年

@philfreo的附加组件-请注意,与TIMEDIFF相比,应该在TIMESTAMPDIFF中将参数反转。在这方面采取的答案给出的例子,如果TIMEDIFF回报02:00:00,相应TIMESTAMPDIFF将返回-2如果单位为小时,-120如果单位为分钟,等要得到符号对应于时区,交换的参数:SELECT TIMESTAMPDIFF(MINUTE, UTC_TIMESTAMP, NOW())将返回预期120的时区+2:00。指定分钟的原因是,有些时区偏移了30或45分钟,请参见en.wikipedia.org/wiki/Time_zone
ToolmakerSteve

1
这比公认的答案要好得多,因为它可以直接回答问题并提供解决方案,而不仅仅是理论。
san

10

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

 1. SELECT @@system_time_zone;   //from this you can get the system timezone 
 2. 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时区,则:

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

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

这将以整数形式返回时区(例如:)-6,处理正数或负数时间(此处EXTRACT起作用):HOUR仅函数将负时区作为正数返回。


6

任何人都可以找到mysql db的时区。

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

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

4

描述中提到的命令返回“ 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.uuuuuuu格式返回当前UTC日期和时间作为值,具体取决于函数的用法,即在字符串或数字上下文中。

现在()

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


2

查看MySQL服务器时区支持system_time_zone系统变量。有帮助吗?


@user,您能在问题中说明您究竟要查找的信息是什么(服务器的时区?客户端的?),以及可以使用哪些工具?您提到了PHP。您可以访问命令行吗?
Pekka 2010年

5
@user还,我发现您遇到了一些小家伙,他们对那些试图提供帮助的人并不满意,但并不是完全错误。我不介意投票或丢分,但您的态度并不鼓励您进一步寻求解决方案。
Pekka 2010年

3
就像我说的@user一样,您的态度并不会激励我为您寻找更多答案,尤其是考虑到您提供的信息很少。抱歉。
Pekka 2010年

3
@ user198729:哇,失去了态度。Pekka是真正帮助人们的那种人。如果仅靠礼貌不足以激发您的兴趣,请尝试自私。
TJ Crowder 2010年

2
只是我的想法:如果用户对我的帖子做同样的事情,我不会冒犯。我的意思是,截止日期的压力或沮丧确实会给人们带来一些粗糙的边缘,但是我认为我们应该在一定程度上允许它。也许我太原谅了:|
森希尔(Senthil)2010年

1

我的PHP框架使用

SET LOCAL time_zone='Whatever'

在连接后打开,其中“无论如何” == date_default_timezone_get()

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

因此,是的,PHP的发展非常强大,并且会对其产生影响


1

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

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


0

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

MySQL的全球时区为系统时区。更改系统的任何此类属性时,只需重启Mysqld。


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

0

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


0

您可以尝试以下方法:

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

您可以在此处将时差指定为秒


1
您不应添加和减去偏移量。与白天说规则等这是一个雷区
eweb

0

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


0

可能是

select timediff(current_time(),utc_time())

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

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

如果您需要通过使用在时区已更改的会话中使用查询 session SET TIME_ZONE =,则可以使用@@session.time_zone。如果您查询@@global.time_zone,那么您会得到'SYSTEM'

如果您尝试datediff,,date_subtimediff使用now()utc_time(),则可能会遇到转换问题。

但是以上建议的内容至少在某些服务器版本上可能有效。我的版本是5.5.43-37,是一个托管解决方案。


这并不能明确回答问题。也许您可以对其进行编辑以专注于所问的问题。
Mogsdad

-3

尝试使用以下代码:

//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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.