在过去的一年半左右的时间里,我们的数据库服务器一直在使用东部时间,而DATETIME类型几乎是唯一使用的,所以我们数据库中的日期时间一直是不受时区影响的,因为只存储了时间戳。我已经在应用程序中添加了一些代码,以便能够将时间转换为当地时区,以期待改变这种情况。
我知道最好的做法是始终使用UTC,现在我想 "切入 "到UTC。我想知道有什么简单的方法可以将所有数据库中的DATETIMEs从东方时间改为UTC。我的意思是,从字面上看,修改每条记录的任何DATETIME属性,因为改变服务器上的时区不会调整这些。有没有一个命令可以轻松做到这一点?
我一直在寻找一些使用convert的例子,但是这些例子似乎只是在飞行中做这些事情--而不是实际修改数据库中的数据。我正在寻找类似的东西。
UPDATE [all tables] SET [all DATETIME attributes] = [current server/DB time (Eastern Time) -> UTC]
(然后,我希望能把服务器时间改成UTC,没人会注意到发生了什么)
但是,更糟糕的是,在过去的一年半里,夏令时已经过去了好几次,所以在每个日期时间上加5个小时的简单方法也行不通。有没有一个简单的办法来解决这个烂摊子?会不会 CONVERT_TZ
足够了,还是会把事情搞得一团糟?
好了,这个过程不一定复杂,但也不像大家希望的那么明显,所以我发个答案。这是我的工作方法。
SELECT CONVERT_TZ(now(),'US/Eastern','US/Central');
无所不能首先,要确保上面的命令不会回到 NULL 当你执行它时。如果它确实返回 NULL就像我一样,完成下面的步骤1到4。
/usr/bin
./mysql_tzinfo_to_sql /usr/share/zoneinfo | ./mysql -u root -p --database=mysql
service mariadb restart
(或适当的命令)来重新启动DB服务。运行 SELECT CONVERT_TZ(now(),'US/Eastern','US/Central');
- 现在 现在应该可以了 (不返回 NULL)
运转 sudo timedatectl set-timezone Etc/UTC
现在运行 SET GLOBAL time_zone = 'Etc/UTC';
现在,服务器时间和数据库时间都是UTC。
现在,我们必须在数据库中手动更新所有合适的列到UTC。
对于每个适用的表和列组合,运行类似这样的程序。
UPDATE table SET `datetime` = CONVERT_TZ(`datetime`, 'America/New_York','Etc/UTC');
现在,数据库的时间已经更新了,所有的记录也都更新为UTC。
唯一需要注意的是,你可能要注意那些在更新表的同时被添加的记录。理想的情况是,你会把所有这些都准备成一个批处理的SQL语句,在改变服务器时间后立即执行,这样就不会有任何闪失。
最后,在最后,运行 service apache2 restart
来重新启动Web服务器。本例中的DB位于Web服务器上,由于某种原因,在重启Apache之前,时间没有调整好。
思考一下完整的问题。
当你把一个时间 "08:00 "存储到一个 DATETIME
. 世界各地的每个人都会 SELECT
即 "08:00"。
当你把 "08:00 "的时间存储到一个。TIMESTAMP
...
INSERTing
到UTC。SELECT
会根据读者的时区重新转换。 所以他可能不会看到 "08:00"。这些操作中的每一个对某些应用来说都是 "正确的",但对其他应用来说就不是了。
大约有5种模式;MySQLMariaDB只提供这两种模式。
你可以用笨拙的代码,分别跟踪时区,并在需要的地方进行调整。 但是,首先,看看是否正确配置和使用了 TIMESTAMP
会更简单。
还请注意 DATETIME
一年两次搞砸了(如果你所在的地区使用 "夏令时 "的话)--每年多一个小时,少一个小时。