我如何获得MySQL的当前时区?
任何人都知道在MySQL中是否有这样的function?
UPDATE
这不会输出任何有效的信息:
mysql> SELECT @@global.time_zone, @@session.time_zone; +--------------------+---------------------+ | @@global.time_zone | @@session.time_zone | +--------------------+---------------------+ | SYSTEM | SYSTEM | +--------------------+---------------------+
或者,也许MySQL本身不能确切地知道time_zone
使用,没关系,我们可以涉及PHP
在这里,只要我可以得到有效的信息不像SYSTEM
…
从手册( 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。
但请注意,时间和date值不会与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()
等。 它不会告诉你什么时区数据库数据中的date正在使用。 你可能会select假定它们是使用服务器的时区编写的,但是这个假设可能是有缺陷的。 要知道存储在数据中的任何date或时间的时区,您必须确保它们与时区信息一起存储,或者(像我一样)确保它们总是在GMT时间。
为什么假设数据是使用服务器时区写的? 那么,首先,数据可能是使用设置不同时区的连接编写的。 数据库可能已经从一个服务器移动到另一个服务器在不同的时区(当我inheritance从德克萨斯州到加利福尼亚州的数据库时遇到这种情况)。 但即使数据写在服务器上,与当前的时区一样,仍然是不明确的。 去年在美国,11月1日凌晨2点,夏令时closures。 假设我的服务器在加州使用太平洋时区,我在数据库中的值为2009-11-01 01:30:00
。 那是什么时候? 是11月1日上午1:30 PDT,还是PST 11月1日上午1:30(一小时后)? 你绝对没有办法知道。 道德:始终存储date/时间格林尼治标准时间(不做DST),并根据需要转换为所需的时区。
下面的查询返回当前会话的时区。
select timediff(now(),convert_tz(now(),@@session.time_zone,'+00:00'));
只需SELECT @@system_time_zone;
返回PST
(或与您的系统相关的任何内容)。
如果您正在尝试确定会话时区,则可以使用此查询:
SELECT IF(@@session.time_zone = 'SYSTEM', @@system_time_zone, @@session.time_zone);
如果与系统时区不同,会返回会话时区。
由于Jakub Vrna (创build者或Adminer和NotORM )在评论中提到,要在TIME
select当前的时区偏移,请使用:
SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);
如果您的时区为该date的+2:00,它将返回: 02:00:00
:00:00
我在这里做了一个cheatsheet: 如果MySQL的时区设置为UTC?
SELECT EXTRACT(HOUR FROM (TIMEDIFF(NOW(), UTC_TIMESTAMP))) AS `timezone`
这将以整数(例如: -6
)返回时区,处理正数或负数的时间(这里是EXTRACT
作用: HOUR
函数将负时区作为正数返回)。
要获得MySQL的当前时区,您可以执行以下操作:
- SELECT @@ system_time_zone; //从这里你可以得到系统时区
- SELECT IF(@@ session.time_zone ='SYSTEM',@@ system_time_zone,@@ session.time_zone)//如果系统时区与全球时区不同,这将为您提供时区
现在,如果你想改变MySQL的时区,那么:1. SET GLOBAL time_zone ='+00:00'//这将设置UTC时区的MySQL时区2. SET @@ session.time_zone =“+00:00”; //通过这个,你可以只为你的特定会话提供时区
查看mySQL中的时区支持和time_zone
系统variables。 这有帮助吗?
selectsec_to_time(TIME_TO_SEC(curtime())+ 48000); 在这里你可以指定你的时间不同秒为秒
修改System的时区后,您只需重新启动mysqld。
MySQL的全球时区需要System的时区。 当你改变任何这样的系统属性时,你只需要重新启动Mysqld。
将虚拟logging插入到具有时间戳记的数据库之一中select该logging并获取时间戳记的值。 删除该logging。 获取服务器用于写入数据的时区,并忽略PHP时区。
我的PHP框架使用
SET LOCAL time_zone='Whatever'
在连接之后,'Whatever'== date_default_timezone_get()
不是我的解决scheme,但是这确保了MySQL服务器的SYSTEM
时区总是和PHP一样
所以,是的,PHP是强烈的环境,可以影响它
使用LPAD(TIME_FORMAT(TIMEDIFF(NOW(),UTC_TIMESTAMP),'%H:%i'),6,'+')来获取MySQL时区格式的值,您可以方便地使用CONVERT_TZ()。 请注意,您所获得的时区偏移量仅在评估expression式的时刻才有效,因为如果您有夏令时,偏移量可能随时间而改变。 然而这个expression式与NOW()一起用来存储当前时间的偏移量,这会消除NOW()产生的结果。 (在DST时区,NOW()每年跳回一个小时,因此在不同时间点有一些重复的值)。
要根据您的时区获得当前时间,您可以使用以下(在我的情况下它的'+5:30')
selectDATE_FORMAT(convert_tz(now(),@@ session.time_zone,'+ 05:30'),'%Y-%m-%d')
这可能像这样愚蠢
selecttimediff(current_time(),utc_time())
至于整个MySQL
你不会这样直接获得时区价值,但是如果没有其他方法的话…
@@ global.time_zone不能在视图中使用,因为它是一个variables – 它返回相当不可用的值“系统”(我没有得到为什么有人打扰它)
如果您需要在会话中更改time_zone(按会话SET TIME_ZONE =)使用您的查询,则可以通过@@ session.time_zone获得该查询,如果查询@@ global.time_zone,则会得到'SYSTEM'catch 22
如果你用now()和utc_time()试着用datediff,date_sub或者timediff,你可能会碰到服务器正在悄无声息地转换的转换问题
我见过的最糟糕的文档也不帮你。
出色的工作,每个人!
但是,上面提到的东西可能至less与我的(5.5.43-37)托pipe的解决scheme一些服务器版本。