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 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 用matlab 设计一个不动点迭代法求解非线性方程组的代码
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler
  • ¥15 oracle集群安装出bug
  • ¥15 关于#python#的问题:自动化测试