【问题标题】:Cakephp CakeTime DST handlingCakephp CakeTime DST 处理
【发布时间】:2013-02-09 23:14:46
【问题描述】:

我将所有日期以 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 点!

/EDIT:第一个例子是正确的。活动必须在凌晨 4 点举行。还有夏天

【问题讨论】:

  • 你用过date_default_timezone_set('UTC')和Configure::write('Config.timezone', 'UTC');吗?

标签: cakephp date time timezone dst


【解决方案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 一些时区,例如在印度北部的某个地方,有某种 negative 时区。我猜在这种情况下,“+ 1 小时”必须变为“- 1 小时”,反之亦然。

【讨论】:

    【解决方案2】:

    在您的示例中,您在这两种情况下都得到了错误的时间。如果您想以 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'));
    

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

    【讨论】:

    • 我以另一种方式存储它。为什么它不应该这样工作? CakeTime::toServer('2013-03-22 03:00', $this->Auth->user('timezone'))
    • 使用 CakeTime::toServer 将日期时间转换为可能不是 UTC 的服务器时区。
    • 但我有 date_default_timezone_set('UTC')、Configure::write('Config.timezone', 'UTC') 和 $this->query("SET time_zone = '+00:00' ”)。所以我的蛋糕和服务器应该在 UTC 中运行,并且 toServer() 应该将它正确地转换为 UTC。我认为确实如此!问题只是 DST。
    猜你喜欢
    • 2014-06-03
    • 2014-10-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-05
    • 2012-04-14
    • 1970-01-01
    相关资源
    最近更新 更多