推测UTC中的时间戳行为

时间:2013-01-16 14:11:33

标签: php mysql timestamp propel utc

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

<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时间戳行为的documentation,没有参数来指定时区。

我注意到时间戳行为默认情况下不设置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 timestampable行为?
  2. 如果不是,Propel在哪里设置日期格式/时区?使用pre挂钩并传递一个DateTime对象,并指定时区是在数据库中获取UTC时间的唯一方法(除了实现自定义行为)?
  3. 另外,如果我无法配置Propel时间戳行为的时区,那么首先它的全部目的是什么? (在数据库中设置UTC时间戳是一种很常见的做法)

2 个答案:

答案 0 :(得分: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”;

答案 1 :(得分:0)

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

  1. 该行为使用time(),每个PHP文档始终为UTC。
  2. 请参阅(1),不,Propel没有此类时区设置(虽然PHP does,但它不用于time(),而是用于mktime()。我认为如果你必须这样做,你的preInsert()钩子应该可以正常工作。
  3. 请参阅(1),时间戳行为非常简单,只使用time(),但您可以随时编写自己的行为!实际上,您只需复制existing behavior file,然后将其添加到您的构建属性(Propel doc for custom behaviors)。
  4. 祝你好运!