dsxxqndv41105 2018-02-15 07:24
浏览 72
已采纳

PHP日期间隔错误与夏令时

I've come across an issue when trying to calculate the amount of days between two dates. If the start date is before a daylight savings switch, the amount of days is calculated incorrectly.

Below is a quick test to reproduce the error:

/**
 * @dataProvider daysProvider
 */
public function testDays($start, $end, $expectedDays)
{
    $startDate = new \DateTime($start);
    $endDate = new \DateTime($end);
    $interval = $startDate->diff($endDate);
    $this->assertEquals($expectedDays, $interval->format('%a'));
}

/**
 * @dataProvider daysProvider
 */
public function testDaysSydney($start, $end, $expectedDays)
{
    $startDate = new \DateTime($start);
    $endDate = new \DateTime($end);
    $startDate->setTimezone(new \DateTimeZone('Australia/Sydney'));
    $endDate->setTimezone(new \DateTimeZone('Australia/Sydney'));
    $interval = $startDate->diff($endDate);
    $this->assertEquals($expectedDays, $interval->format('%a'));
}

public function daysProvider()
{
    return [
        ['2016-03-01', '2016-03-04', 3],
        ['2016-04-01', '2016-04-04', 3],
    ];
}

And the output:

PHPUnit 6.5.5 by Sebastian Bergmann and contributors.

...F

Time: 23 ms, Memory: 4.00MB

There was 1 failure:

1) TimingTest::testDaysSydney with data set #1 ('2016-04-01', '2016-04-04', 3)
Failed asserting that '2' matches expected 3.

I did find this Bug report: https://bugs.php.net/bug.php?id=63953 but apparently the issue is supposed to be fixed.

Any idea of a workaround for this? Thanks

  • 写回答

2条回答 默认 最新

  • dongzj2015 2018-02-15 08:13
    关注

    There is a difference between setting DateTimeZone via DateTime setter method (setTimezone) and setting it via DateTime constructor (as stated in this question). Try to set timezone via constructor:

    public function testDaysSydney($start, $end, $expectedDays)
    {
        $tz=new \DateTimeZone('Australia/Sydney');
        $startDate = new \DateTime($start, $tz);
        $endDate = new \DateTime($end, $tz);
        $interval = $startDate->diff($endDate);
        $this->assertEquals($expectedDays, $interval->format('%a'));
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥170 如图所示配置eNSP
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上