【问题标题】:php datetime/datetimezone substract 2 hours instead of 1 [duplicate]php datetime/datetimezone减去2小时而不是1 [重复]
【发布时间】:2013-01-15 21:01:34
【问题描述】:

您好,我有一个特殊的时区,例如欧洲/柏林,我想在当前日期上增加 90 天。之后我检测到一个月的最后一天。

我在数据库中的日期以 UTC 格式保存。这就是为什么我必须在最后更改时区。

我的问题是,时区更改从欧​​洲/柏林和 UTC 之间的时间减去 2 小时。当我在将日期时间对象更改为 UTC 之前不修改它时,它只会减去 1 小时。谁能告诉我问题是什么或正确的解决方案?

//$timezone = 'Europe/Berlin';
private function getMaxTillDate($timezone)
{        
    $threemonth = new \DateTime('now', new \DateTimeZone($timezone) );
    $threemonth->setTime(23, 59, 59);
    $threemonth->add(new \DateInterval('P0Y90DT0H0M'));
    $maxday = $threemonth->format('t');        
    $threemonth->setDate($threemonth->format('Y'), $threemonth->format('m'), $maxday);
    $threemonth->setTimezone(new \DateTimeZone('UTC'));

    return $threemonth;
}

非常感谢

【问题讨论】:

  • 德国至少有半年时间实行夏令时,也就是UTC+2小时。
  • 是的,我知道,但它没有描述如果我在更改时区之前不操作日期对象,为什么 php 只减去 1 小时。

标签: php datetime timezone


【解决方案1】:

我测试了您的代码 - 它适用于我:

function getMaxTillDate($timezone){
    $threemonth = new \DateTime('now', new \DateTimeZone($timezone) );
    var_dump(1, $threemonth);
    $threemonth->setTime(23, 59, 59);
    var_dump(2, $threemonth);
    $threemonth->add(new \DateInterval('P0Y90DT0H0M'));
    var_dump(3, $threemonth);
    $maxday = $threemonth->format('t');
    var_dump(4, $threemonth, $maxday);
    $threemonth->setDate($threemonth->format('Y'), $threemonth->format('m'), $maxday);
    var_dump(5, $threemonth);
    $threemonth->setTimezone(new \DateTimeZone('UTC'));
    var_dump(6, $threemonth);
    return $threemonth;
}

$tz = "Europe/Berlin";

var_dump(getMaxTillDate($tz));

结果:

int(1)
class DateTime#1 (3) {
public $date =>
string(19) "2013-01-15 22:29:59"
public $timezone_type =>
int(3)
public $timezone =>
string(13) "Europe/Berlin"
}
int(2)
class DateTime#1 (3) {
public $date =>
string(19) "2013-01-15 23:59:59"
public $timezone_type =>
int(3)
public $timezone =>
string(13) "Europe/Berlin"
}
int(3)
class DateTime#1 (3) {
public $date =>
string(19) "2013-04-15 23:59:59"
public $timezone_type =>
int(3)
public $timezone =>
string(13) "Europe/Berlin"
}
int(4)
class DateTime#1 (3) {
public $date =>
string(19) "2013-04-15 23:59:59"
public $timezone_type =>
int(3)
public $timezone =>
string(13) "Europe/Berlin"
}
string(2) "30"
int(5)
class DateTime#1 (3) {
public $date =>
string(19) "2013-04-30 23:59:59"
public $timezone_type =>
int(3)
public $timezone =>
string(13) "Europe/Berlin"
}
int(6)
class DateTime#1 (3) {
public $date =>
string(19) "2013-04-30 21:59:59"
public $timezone_type =>
int(3)
public $timezone =>
string(3) "UTC"
}
class DateTime#1 (3) {
public $date =>
string(19) "2013-04-30 21:59:59"
public $timezone_type =>
int(3)
public $timezone =>
string(3) "UTC"
}

【讨论】:

  • 请取消注释这些行然后你会看到不同之处:$threemonth->setTime(23, 59, 59); $三个月->添加(新\DateInterval('P0Y90DT0H0M')); $maxday = $threemonth->format('t'); $threemonth->setDate($threemonth->format('Y'), $threemonth->format('m'), $maxday);
  • 如您所见,它们没有被评论。如果我将它们注释掉,我完全可以看到当前时区设置处于活动状态:今天“欧洲/柏林”时区现在是 22:50,我们处于冬季时间,例如“UTC+1”。从 2013 年 3 月 31 日开始,我们将在“UTC+2”。
  • 它没有解释为什么当我操纵日期时时区减去 2 小时,而当我对日期不做任何事情时只减去 1 小时。
  • 确实如此。您使用“欧洲/柏林时区规则适用”信息创建一个“时间点”。今天,这意味着您给出的时间是 UTC+1 - 将时区更改为 UTC 意味着同一时间点的小时数减少一小时。如果将日期移动到“从现在起 3 个月”,则不会先更改时区,也不会更改时间。现在您有了一个日期,时区规则表明它是“UTC+2”。这取决于 date add id 执行的方式:您只添加天数,如果更改 UTC 偏移量,则不会更改本地时间。
  • 非常感谢。现在我明白了。我完全忘记了。
猜你喜欢
  • 1970-01-01
  • 2016-11-17
  • 1970-01-01
  • 2012-09-04
  • 1970-01-01
  • 2011-08-11
  • 1970-01-01
  • 2020-09-12
  • 2015-11-19
相关资源
最近更新 更多