并将数据以UTC格式存储在数据库中


Yii2 and storing data in database as UTC

我使用的是Yii2,我想知道它如何决定将数据存储在数据库中的时区?

我注意到$defaultTimezone,它似乎表明它只是控制什么时区你的输入数据应该是当它传递给函数,如asTime函数,它使用格式化器时区说的数据转换成正确的时间输出。

但是我想知道你如何确保它在正确的时区插入数据到数据库中,这样$defaultTimezone的值就可以被信任了?

是否有必要为MySQL运行这样的东西:

SET time_zone = timezonename;

如果您希望在应用程序中只使用一个时区,您可以在配置文件或入口脚本(默认为web/index.php)中添加以下行:

date_default_timezone_set('UTC');

好了,下面是我的发现:

时间戳:

MySQL将自动将此值存储为UTC,并将根据MySQL服务器时区将其转换为UTC和返回。

然而,一些注释:

我建议将服务器时区设置为UTC,如下所示:
SET time_zone = 'UTC';

如果你在世界各地都有服务器,那就没关系了,你总是会在每个服务器上得到相同的数据——这将是你传递给它的相同数据,所以这将基于你的PHP时区,所以如果你想要传递回一个UTC时间,那么你应该使用NOW() myswl函数来存储时间戳。

如果你不设置服务器时区,MySQL通常会依赖于SYSTEM时区,每个服务器会根据他们的时区得到不同的时间戳。

如果您想在现有的系统中实现UTC更改,那么它的行为将不同。无论你传递什么,它似乎总是返回日期为UTC

如果你把你的服务器时区设置为UTC,然后你把它改为其他的,那么事情就开始看起来有点麻烦了。

datetime

据我所知,这些只是存储和返回你给他们的确切数据。

存储unix时间戳:

如上所述,这些将只存储您给它们的任何值,因为您只是将它们存储为任何旧的integer;但是如果你想用UTC存储时间戳,那么你可以使用UNIX_TIMESTAMP如@Ngô vunin Thao所述,或者如果你需要在PHP中这样做,那么你可以这样做:

$tz = new DateTimeZone('UTC'); 
$dt = new DateTime("now", $tz);
$utc_timestamp = $dt->format('U');

U表示php date函数中的unix时间戳格式选项;如果您想以其他格式返回日期,可以使用任何格式选项。

所以简而言之…

  • 使用SET time_zone = 'UTC'设置服务器时间为UTC
  • TIMESTAMP字段中插入数据时使用NOW()
  • 使用UNIX_TIMESTAMP()或上面提供的代码在UTC
  • 中存储unix timestamps

这样做应该总是确保你得到UTC格式的相关时间/日期。

我找到了一个解决方案:https://gist.github.com/SilverFire/6f98d2605a6574bd02f7

它为我工作得很好,特别是因为我在docker容器中使用mysql。

在你的"config/db.php"中添加下面的配置,但记住用UTC替换'America/Manaus':

return [
    // ... your database config goes here, and after:
    'on afterOpen' => function($event) {
        // $event->sender refers to the DB connection
        $event->sender->createCommand("SET time_zone = 'America/Manaus'")->execute();
    }
];