PHP DateTime-> diff()无法正常工作

mon*_*tie 5 php datetime

我遇到了一个有趣的案例,与课堂diff()方法有关DateTime

如果我尝试计算两个月中两个日期之间的差异,例如

$datetime1 = new \DateTime('June 2019');
$datetime2 = new \DateTime('July 2019');
$interval = $datetime1->diff($datetime2);
echo $interval->format('%m');
Run Code Online (Sandbox Code Playgroud)

结果我得到了0

为什么会这样?

Print_r的:

$ datetime1:

DateTime Object ( [date] => 2019-06-01 00:00:00.000000 
[timezone_type] => 3 [timezone] => Europe/Berlin )
Run Code Online (Sandbox Code Playgroud)

$ datetime2:

DateTime Object ( [date] => 2019-07-01 00:00:00.000000 
[timezone_type] => 3 [timezone] => Europe/Berlin )
Run Code Online (Sandbox Code Playgroud)

$ interval:

DateInterval Object ( [y] => 0 [m] => 0 [d] => 30 [h] => 0 [i] => 0 [s] => 0 [f] => 0 
[weekday] => 0 [weekday_behavior] => 0 [first_last_day_of] => 0 
[invert] => 0 [days] => 30 [special_type] => 0 [special_amount] => 0
 [have_weekday_relative] => 0 [have_special_relative] => 0 )
Run Code Online (Sandbox Code Playgroud)

jbr*_*olo 1

问题出在您的时区。

这里有一篇文章对此进行了解释。

看这个例子:

<?php

echo "----- Europe/Berlin -----\n";
date_default_timezone_set('Europe/Berlin'); 
$datetime1 = new \DateTime('June 2019');
$datetime2 = new \DateTime('July 2019');
print_r($datetime1);
print_r($datetime2);

$interval = $datetime1->diff($datetime2);
print_r($interval);

echo "%m = " . $interval->format('%m') . PHP_EOL;
echo "%a = " . $interval->format('%a') . PHP_EOL;
echo "%s = " . $interval->format('%s') . PHP_EOL;


echo "\n\n\n----- America/Sao_Paulo -----\n";
date_default_timezone_set('America/Sao_Paulo'); 
$datetime1 = new \DateTime('June 2019');
$datetime2 = new \DateTime('July 2019');
print_r($datetime1);
print_r($datetime2);

$interval = $datetime1->diff($datetime2);
print_r($interval);

echo "%m = " . $interval->format('%m') . PHP_EOL;
echo "%a = " . $interval->format('%a') . PHP_EOL;
echo "%s = " . $interval->format('%s') . PHP_EOL;
Run Code Online (Sandbox Code Playgroud)

和输出:

$ php date_diff.php 
----- Europe/Berlin -----
DateTime Object
(
    [date] => 2019-06-01 00:00:00.000000
    [timezone_type] => 3
    [timezone] => Europe/Berlin
)
DateTime Object
(
    [date] => 2019-07-01 00:00:00.000000
    [timezone_type] => 3
    [timezone] => Europe/Berlin
)
DateInterval Object
(
    [y] => 0
    [m] => 0
    [d] => 30
    [h] => 0
    [i] => 0
    [s] => 0
    [f] => 0
    [weekday] => 0
    [weekday_behavior] => 0
    [first_last_day_of] => 0
    [invert] => 0
    [days] => 30
    [special_type] => 0
    [special_amount] => 0
    [have_weekday_relative] => 0
    [have_special_relative] => 0
)
%m = 0
%a = 30
%s = 0



----- America/Sao_Paulo -----
DateTime Object
(
    [date] => 2019-06-01 00:00:00.000000
    [timezone_type] => 3
    [timezone] => America/Sao_Paulo
)
DateTime Object
(
    [date] => 2019-07-01 00:00:00.000000
    [timezone_type] => 3
    [timezone] => America/Sao_Paulo
)
DateInterval Object
(
    [y] => 0
    [m] => 1
    [d] => 0
    [h] => 0
    [i] => 0
    [s] => 0
    [f] => 0
    [weekday] => 0
    [weekday_behavior] => 0
    [first_last_day_of] => 0
    [invert] => 0
    [days] => 30
    [special_type] => 0
    [special_amount] => 0
    [have_weekday_relative] => 0
    [have_special_relative] => 0
)
%m = 1
%a = 30
%s = 0
Run Code Online (Sandbox Code Playgroud)

在我的时区$interval->format('%m');是 1。

您可以在日期上设置时区来计算它们之间的差异。

$datetime1 = new \DateTime('June 2019', new DateTimeZone('UTC'));
$datetime2 = new \DateTime('July 2019', new DateTimeZone('UTC'));
$interval = $datetime1->diff($datetime2);
print_r($interval);
echo "%m = " . $interval->format('%m') . PHP_EOL;

Run Code Online (Sandbox Code Playgroud)
$ php date_diff.php 
DateInterval Object
(
    [y] => 0
    [m] => 1
    [d] => 0
    [h] => 0
    [i] => 0
    [s] => 0
    [f] => 0
    [weekday] => 0
    [weekday_behavior] => 0
    [first_last_day_of] => 0
    [invert] => 0
    [days] => 30
    [special_type] => 0
    [special_amount] => 0
    [have_weekday_relative] => 0
    [have_special_relative] => 0
)
%m = 1
Run Code Online (Sandbox Code Playgroud)