【问题标题】:Yii2 and storing data in database as UTCYii2 并将数据以 UTC 格式存储在数据库中
【发布时间】:2015-08-28 16:16:45
【问题描述】:

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

我注意到$defaultTimezone 似乎表明它只是控制您的输入 数据在传递给asTime 等函数时应该使用的时区,并且它使用formatter timezone 将所述数据转换为正确的时间输出。

但我想知道如何确保它在正确的时区将数据插入到您的数据库中,以便可以信任 $defaultTimezone 的值?

是否需要为MySQL 运行类似的东西:

SET time_zone = timezonename;

【问题讨论】:

  • 试试这个 date_default_timezone_set("you time zone");在你的配置 ..file
  • @SahilManchal 这几乎就是应用程序时区的作用。
  • unix_timestamp 最好注意时区
  • @NgôVănThao 我可能最常使用 unix 时间戳,我知道它们的定义是 UTC,但我想让我感到困惑的是你会得到一个不同的输出整数在 PHP 中取决于您的时区设置;所以我想确保它存储为 UTC。
  • 没有。 unix_timestamp不受时区影响

标签: php mysql yii timezone yii2


【解决方案1】:

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

date_default_timezone_set('UTC');

【讨论】:

  • 不,我只需要确保它以UTC 的身份插入到数据库中。
  • 然后使用TIMESTAMP,这样你就知道MySQL会将值修改为UTC,使用服务器时区作为要插入的原始值的时区。
  • 这是否意味着服务器时区应该与 PHP 时区设置相匹配?
  • nvm... 我找到了答案;你没有。即使 PHP 时区和 mysql 时区不同,mysql 似乎也会返回您传递的相同值。
【解决方案2】:

好的,以下是我对此的发现:

时间戳:

MySQL 会自动将此值存储为UTC,并将根据 mysql 服务器时区将您提供的值转换为 UTC 并返回。

但是,一些注意事项:

我建议您将服务器时区设置为 UTC,如下所示:

SET time_zone = 'UTC';

那么,如果您在世界各地都有服务器,那么您将始终在每台服务器上获得相同的数据 - 这将与您传递给它的数据相同,因此这将基于您的 PHP时区,所以如果您希望它传回 UTC 时间,那么您应该使用 NOW() myswl 函数来存储 TIMESTAMP。

如果您不设置服务器时区,MySQL 通常会依赖 SYSTEM 时区,并且每个服务器会根据其时区返回不同的时间戳。

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

如果您将服务器时区设置为 UTC,然后将其更改为其他内容,那么事情就会开始变得有些棘手。

日期日期时间

据我所知,这些只是存储并返回您提供给他们的确切数据。

存储 unix 时间戳:

如上所述,这些只会存储您给它们的任何值,因为您只是将它们存储为任何旧的integer但是如果您想以 UTC 格式存储时间戳,那么您可以使用 @Ngô Văn Thao 所述的UNIX_TIMESTAMP,或者如果您需要在 PHP 中执行此操作,那么您可以执行以下操作:

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

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

总之...

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

执行上述操作应始终确保您以 UTC 格式获取相关时间/日期。

【讨论】:

  • $timestamp = time() - date('Z');。这只是一个评论,不是正式文件,最重要的是,这是一个错误。让我们试试: ini_set('date.timezone', 'Europe/Berlin'); echo '欧洲/柏林-->'.time().'
    '; ini_set('date.timezone', 'UTC'); echo 'UTC:time-->'.time().'
    ';
  • 所以你实际上是在说$timestamp = time() - date('Z'); 不会得到当前的UTC 时间戳?
  • UNIX_TIMESTAMP 不关心时区。因为它始终是 UTC。为什么不阅读第一条评论(116 票赞成):php.net/manual/en/function.time.php#100220 阅读更多关于 UNIX_TIMESTAMP 的信息:en.wikipedia.org/wiki/Unix_time
  • @NgôVănThao 没错,时区无关。这意味着它将根据时区返回 不同的 值。 time() in UTC 的值 != ``time()` 在另一个时区的值。
【解决方案3】:

我在这里找到了解决方案:https://gist.github.com/SilverFire/6f98d2605a6574bd02f7

它非常适合我,特别是因为我在 docker 容器中使用 mysql。

在您的“config/db.php”中添加以下配置,但请记住将“America/Manaus”替换为您的 UTC:

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();
    }
];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-27
    • 1970-01-01
    • 2016-05-18
    • 1970-01-01
    • 2011-04-17
    • 2013-06-14
    • 1970-01-01
    • 2020-03-11
    相关资源
    最近更新 更多