我将所有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小时的偏移量,我想这是因为它考虑了夏令时(从2013年3月31日开始)。
然而,我想做的是在日历中显示重复发生的事件,该事件每周五凌晨4点开始,即使在夏天也是如此。因此,日历可能不会显示为凌晨5点!
/编辑:第一个例子是正确的。活动必须在凌晨4点举行。而且在夏季
我使用这两个函数进行时间转换,解决了这个问题
请记住,这是针对重复发生的事件,无论夏令时如何,这些事件总是在一天中的同一时间(例如凌晨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;
}
这应该适用于所有使用正夏令时的时区。AFAIK一些时区,例如北印度的某个地方,有某种负时区。我想在这种情况下,"+1小时"必须变成"-1小时",反之亦然。
在您的示例中,您在这两种情况下都得到了错误的时间。如果您希望以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'));
需要注意的是,如果用户将时区从有夏令时的时区更改为没有夏令时的(反之亦然),他们可能会遇到同样的问题。