Cakephp CakeTime DST处理

时间:2013-02-24 20:33:43

标签: cakephp date time timezone dst

我将UTC中的所有日期存储在我的数据库中。 Cakephp以UTC格式运行并与UTC中的mysql通信。现在我有以下情况:

debug(CakeTime::format('Y-m-d H:i', '2013-03-22 03:00', false,
    new DateTimeZone('Europe/Berlin')));
//output is 2013-03-22 04:00

debug(CakeTime::format('Y-m-d H:i', '2013-04-05 03:00', false,
    new DateTimeZone('Europe/Berlin')));
//output is 2013-04-05 05:00

正如你所看到的,CakeTime在第二个例子中增加了2小时的偏移,我猜这是因为它考虑了DST(从2013年3月31日开始)。
然而,我想要做的是在日历中显示重复的事件,这个事件在每个星期五凌晨4点开始 - 即使在夏天。因此日历可能不会显示在凌晨5点!

/编辑:第一个例子是正确的。该活动必须在凌晨4点。而且在夏天

2 个答案:

答案 0 :(得分:1)

我使用这两个功能进行时间​​转换解决了这个问题 请记住,这是针对重复发生的事件,它始终在一天的同一时间(例如凌晨4点)开始,与DST无关。

public function dateTimeToSever($date, $user_timezone) {
    $DateTime = new DateTime($date, $user_timezone);
    $dst = $DateTime->format('I');
    $toServerDateTime = CakeTime::toServer($date, $user_timezone, 'Y-m-d H:i');
    if ($dst) {
        $toServerDateTime = date('Y-m-d H:i', strtotime($toServerDateTime . ' + 1 Hours'));
    }
    return $toServerDateTime;
}

public function dateTimeToUser($date, $user_timezone) {
    $DateTime = new DateTime($date, new DateTimeZone('UTC'));
    $DateTime->setTimezone($user_timezone);
    $dst = $DateTime->format('I');
    $userDateTime = CakeTime::format('Y-m-d H:i', $date, false, $user_timezone);
    if ($dst) {
        $userDateTime = date('Y-m-d H:i', strtotime($userDateTime . ' - 1 Hours'));
    }
    return $userDateTime;
}

这适用于使用正面 DST的所有时区。 AFAIK一些时区,例如在印度北部的某个地方,有某种负面时区。我想在那种情况下,“+ 1小时”必须变成“ - 1小时”,反之亦然。

答案 1 :(得分:0)

在您的示例中,您在两种情况下都得到错误的时间。如果您希望以UTC格式存储所有日期,则需要确保为用户所在的时区存储正确的UTC值。例如,如果您希望每周五下午3点在欧洲/柏林时区重新发生活动,然后执行以下操作。

// save your date like this
$date = new DateTime('2013-04-05 03:00', new DateTimeZone('Europe/Berlin'));
$utc = $date->getTimestamp();
// print them correctly like this
$utc = CakeTime::format('Y-m-d H:i', $utc, false, new DateTimeZone('Europe/Berlin'));

在对此方法的警告中,如果用户将其时区从使用DST的时区更改为没有(或反之亦然)的时区,则可能会遇到相同的问题。