我正在使用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。
我的问题是:
pre
挂钩并传递一个DateTime
对象,并指定时区是在数据库中获取UTC时间的唯一方法(除了实现自定义行为)?答案 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 question和php documentation for time()
很明显time()
应该返回自Unix纪元以来的秒数,这将始终是UTC。实际上,在我使用Propel和时间戳行为的所有项目中都是如此。如果您的项目没有这样做,可能会有更深层次的问题(也就是说,它不是Propel中的问题)。那就是说,我对你问题的回答是:
time()
,每个PHP文档始终为UTC。time()
,而是用于mktime()
。我认为如果你必须这样做,你的preInsert()
钩子应该可以正常工作。time()
,但您可以随时编写自己的行为!实际上,您只需复制existing behavior file,然后将其添加到您的构建属性(Propel doc for custom behaviors)。