1

我将所有日期以 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 点举行。但也在夏天

4

2 回答 2

1

我使用这两个函数进行时间转换解决了这个问题。
请记住,这是针对经常性事件,无论夏令时如何,总是在一天中的同一时间(例如凌晨 4 点)开始。

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 小时”,反之亦然。

于 2013-02-26T15:55:40.240 回答
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'));

关于这种方法的警告,如果用户将他们的时区从有夏令时的时区更改为没有夏令时的时区(反之亦然),他们可能会遇到同样的问题。

于 2013-02-24T21:37:54.380 回答