如何获取MySQL的当前时区?

时间:2010-05-29 07:48:53

标签: mysql timezone

任何人都知道MySQL中是否有这样的功能?

更新

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

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

或许MySQL本身无法准确知道所使用的time_zone,这没关系,我们可以在这里涉及PHP,只要我能获得有效信息而不是SYSTEM ..

16 个答案:

答案 0 :(得分:198)

从手册(section 9.6):

  

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

编辑如果MySQL设置为系统时区的从属设备,则上面返回SYSTEM,这不太有帮助。由于您使用的是PHP,如果MySQL的答案为SYSTEM,您可以通过date_default_timezone_get向系统询问的时区。 (当然,正如VolkerK所指出的那样,PHP可能在不同的服务器上运行,但是假设,假设它正在与之交谈的Web服务器和数据库服务器设置为 [如果不是实际 > ]同一时区不是巨大的跳跃。)但要注意(与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点关闭。假设我的服务器使用太平洋时区在加利福尼亚,我在数据库中有值2009-11-01 01:30:00。那是什么时候?这是太平洋标准时间11月1日凌晨1:30,也就是太平洋标准时间11月1日凌晨1:30(一小时后)?你完全没办法知道。道德:始终将日期/时间存储在GMT(不执行DST)并在必要时转换为所需的时区。

答案 1 :(得分:168)

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

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

答案 2 :(得分:80)

简单地 SELECT @@system_time_zone;

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

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

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

答案 3 :(得分:53)

在评论中提及Jakub Vrána(创作者或AdminerNotORM),在TIME中选择当前时区偏移量:

SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);

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

我在这里制作了一张备忘单:Should MySQL have its timezone set to UTC?

答案 4 :(得分:6)

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

这会将时区作为整数返回(例如:-6),处理正或负时间(这里是EXTRACT发挥作用的地方:HOUR函数单独返回负时区正)。

答案 5 :(得分:5)

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

  1. SELECT @@ system_time_zone; //从这里你可以获得系统时区
  2. SELECT IF(@@ session.time_zone ='SYSTEM',@@ system_time_zone,@@ session.time_zone)//如果系统时区与全球时区不同,这将为您提供时区
  3. 现在,如果你想改变mysql时区,那么:  1. SET GLOBAL time_zone ='+ 00:00'//这将以UTC格式设置mysql时区  2. SET @@ session.time_zone =“+00:00”; //通过这个你可以只为你的特定会话选择时区

答案 6 :(得分:3)

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

答案 7 :(得分:2)

选择sec_to_time(TIME_TO_SEC(curtime())+ 48000); 在这里你可以指定时间差异为秒

答案 8 :(得分:1)

我的PHP框架使用

SET LOCAL time_zone='Whatever'
在连接之后

,其中&#39;无论什么&#39; == date_default_timezone_get()

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

所以,是的,PHP被强烈包含并且可以影响它

答案 9 :(得分:1)

描述中提到的命令返回“ 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()

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

答案 10 :(得分:0)

您需要在更改System ..的时区后重新启动mysqld。

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

答案 11 :(得分:0)

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

答案 12 :(得分:0)

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

答案 13 :(得分:0)

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

  

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

答案 14 :(得分:-1)

这可能和这个一样愚蠢

选择timediff(current_time(),utc_time())

和整个mysql一样

你不会以这种方式直接获得时区价值,但如果没有别的办法......

@@ global.time_zone不能在视图中使用,因为它是一个变量 - 并且它返回非常不可用的值'SYSTEM'(我还没有得到有人为之烦恼的原因)

如果您需要在更改time_zone的会话中使用您的查询(通过会话SET TIME_ZONE =),您将获得 与@@ session.time_zone 如果你查询@@ global.time_zone,你会得到'SYSTEM' 赶上22

如果你用now()和utc_time()尝试使用datediff,date_sub或timediff,你可能会遇到由服务器静默输入的转换问题

我见过的最糟糕的文档我也没帮你。

每个人都做得很好!

但上面建议的内容可能至少可以用于某些服务器版本,就像我的(5.5.43-37)托管解决方案一样。

答案 15 :(得分:-2)

尝试使用以下代码:

//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