CakePHP:来自没有时区的数据库的FrozenTime

时间:2016-03-23 13:24:07

标签: datetime cakephp cakephp-3.0

我在"欧洲/罗马":

debug(new \Cake\I18n\Time());

输出:

object(Cake\I18n\Time) {

    'time' => '2016-03-23T14:18:17+01:00',
    'timezone' => 'Europe/Rome',
    'fixedNowTime' => false

}

如果我保存帖子(例如),则正确处理数据时间 检索数据时出现问题。这篇文章刚刚保存:

debug($post->created);

输出:

object(Cake\I18n\FrozenTime) {

    'time' => '2016-03-23T14:14:45+00:00',
    'timezone' => 'UTC',
    'fixedNowTime' => false

}

日期时间是正确的,但当然不是时区。

现在,如果我这样做:

debug($post->created > new \Cake\I18n\Time());

结果显然是TRUE而不是FALSE(应该如此)。我的结论是,这是因为,在比较阶段,它显然使用相同的时区。

我在哪里做错了?感谢。

EDIT 我的bootstrap.php

date_default_timezone_set('UTC');

相反,我的php.ini(我认为它不相关):

date.timezone = Europe/Rome

所以我必须认为$post->created的价值是正确的 但是现在......为什么new \Cake\I18n\Time()使用正确的时区(未设置)以及为什么使用正确的时区保存帖子?

1 个答案:

答案 0 :(得分:1)

我有点怀疑new \Cake\I18n\Time()在使用date_default_timezone_set()之后会使用INI中设置的时区,因为后者应该胜过前者。也许有一个版本特定的行为/错误,这不会按预期工作,不确定,你必须调试你的环境来计算那里发生的事情。

话虽这么说,在读取数据时,ORM会将其转换为PHP数据类型。负责此操作的日期/时间类型类使用 cloned date/time class instances 而不是创建新的类,并且在首次构建类型实例和/或when the mutability is being set时创建该基本实例,当调用Type::build()时,通常会发生at bootstrapping time

如果您之后例如稍后更改时区,则基于\Cake\I18n\Time的新实例将使用新设置的时区,但日期/时间类型仍将使用创建的实例引导时的原始时区。

TL;博士

在引导程序中通过date_default_timezone_set()设置正确的时区,如果您需要稍后更改时区,那么您必须确保克隆的新基本类型实例正在进行中set,例如可以通过再次设置可变性来完成,比如

Type::build('time')->useImmutable();

这感觉有点麻烦,但您可能想要打开票证over at GitHub并报告此行为。