0

我正在使用带有 MySql 的 Propel 1.6。我在所有表上设置了时间戳行为,如下所示:

<database name="default" >
    <behavior name="timestampable">
        <parameter name="create_column" value="creation_date" />
        <parameter name="update_column" value="last_modified" />
    </behavior>

    <table name="book" phpName="Book">
        <!-- table colums omitted -->
    </table>
</database>

根据 Propel 时间戳行为的文档,没有指定时区的参数。

我注意到时间戳行为默认情况下不会设置 UTC 时间。例如,在我的例子中,它设置 UTC+1。

做了一些调查,我发现如果我使用preInsert()钩子来设置时间而不是行为并且我传递了 Unix 时间戳:

public function preInsert(PropelPDO $con = null)
{
    $this->setCreationDate(time());
    return true;
}

结果时间仍然是 UTC+1。如果我使用DateTime对象而不是 Unix 时间戳设置时间:

public function preInsert(PropelPDO $con = null)
{
    $this->setCreationDate(new DateTime('now', new DateTimeZone('UTC')));
    return true;
}

我在数据库中获得了正确的 UTC 时间。

我检查了代码,发现 bahavior 设置了通过 Unix 时间戳的时间,因此导致数据库上的 UTC+1。

我的问题是:

  1. 是否可以在 UTC 中配置 Propel 可时间戳行为?
  2. 如果不是,Propel 在哪里设置日期格式/时区?是否使用pre钩子并传递具有DateTime指定时区的对象是在数据库中获取 UTC 时间的唯一方法(除了实现自定义行为)?
  3. 另外,如果我无法配置 Propel 可时间戳行为的时区,那么它的全部目的首先是什么?(在数据库中设置 UTC 时间戳是一种很常见的做法)
4

2 回答 2

0

该文档没有特别提到时区,但你应该能够设置它做这样的事情......

$objSourceTimezone = new DateTimeZone('America/Los_Angeles');
$objDestinationTimezone = new DateTimeZone('UTC');

$objTime = new DateTime([some date], $objSourceTimezone);
$objTime->setTimeZone($objDestinationTimezone);

$objPropel->setTimestamp($time->format('Y-m-d H:i:s'));

我正在使用我当地的太平洋时区(但你可以使用任何你想要的)并将其转换为与 MySQL 和 Propel 的TIMESTAMP专栏兼容的 UTC 格式。

您可以通过执行相反的操作来检索此数据并将其显示在不同的时区...

$objSourceTimezone = new DateTimeZone('UTC');
$objDestinationTimezone = new DateTimeZone('America/New_York');

$objTime = new DateTime($objPropel->getTimestamp(), $objSourceTimezone);
$objTime->setTimeZone($objDestinationTimezone);

print $time->format('Y-m-d H:i:s').”\n”;
于 2013-01-16T15:35:13.627 回答
0

根据这个问题php 文档,time()很明显time()应该返回自 Unix 纪元以来的秒数,该秒数将始终为 UTC。事实上,在我所有使用 Propel 和可时间戳行为的项目中都是如此。如果你的项目没有这样做,可能有更深层次的问题(也就是说,这不是 Propel 中的问题)。也就是说,我对您的问题的回答是:

  1. 根据 PHP 文档,行为使用time()的始终为 UTC。
  2. 见(1),不,Propel 没有这样的时区设置(虽然PHP 有,但它不是用于time(),而是用于mktime())。我认为preInsert()如果你必须这样做,你的钩子应该可以作为一种解决方法。
  3. 参见 (1),可时间戳行为非常简单,只需使用time(),但您始终可以自己编写!事实上,您可以只复制现有的行为文件,然后将其添加到您的构建属性(自定义行为的 Propel 文档)。

祝你好运!

于 2013-01-16T16:18:53.660 回答