英文:
Can someone explain why there's a one-year difference in the results of PHP's date diff function for these two dates with the same timezone?
问题
$a = new DateTime("2023-05-31", new DateTimeZone('Europe/Rome'));
$b = new DateTime("1970-05-31", new DateTimeZone('Europe/Rome'));
var_dump($a->diff($b)->y);
// int(52)
$a = new DateTime("2023-05-30", new DateTimeZone('Europe/Rome'));
$b = new DateTime("1970-05-30", new DateTimeZone('Europe/Rome'));
var_dump($a->diff($b)->y);
// int(53)
英文:
$a = new DateTime("2023-05-31", new DateTimeZone('Europe/Rome'));
$b = new DateTime("1970-05-31", new DateTimeZone('Europe/Rome'));
var_dump($a->diff($b)->y);
// int(52)
$a = new DateTime("2023-05-30", new DateTimeZone('Europe/Rome'));
$b = new DateTime("1970-05-30", new DateTimeZone('Europe/Rome'));
var_dump($a->diff($b)->y);
// int(53)
Why in the first case the diff is 52?
I expect 53 for both cases
答案1
得分: 1
以下是翻译好的部分:
似乎总体来说,意大利有些问题。可能是因为某年他们没有进行夏令时调整,这可能会导致功能出现混淆(这只是一个猜测)。
foreach ($zones as $zone){
$tz = new DateTimeZone($zone);
$a = new DateTime("2023-05-31", $tz);
$b = new DateTime("1970-05-31", $tz);
if ($a->diff($b)->y != 53) {
printf(" !!! %s diff = %d\n", $zone, $a->diff($b)->y);
} else {
//printf("%s diff = %d\n", $zone, $a->diff($b)->y);
}
}
结果
!!! Europe/Rome diff = 52
!!! Europe/Malta diff = 52
!!! Europe/San_Marino diff = 52
!!! Europe/Vatican diff = 52
如果从1971年开始就没有这个问题,所以可能有问题的年份是1970年。
在 https://www.timeanddate.com/time/change/italy/rome?year=1970
上找到了以下信息,这可能有助于解释。
1970年5月31日 - 夏令时开始
当地标准时间即将达到
1970年5月31日星期日,00:00:00 时钟被向前调整1小时至
1970年5月31日星期日,01:00:00 当地夏令时。
与前一天相比,1970年5月31日的日出和日落时间要晚大约1小时。
当天晚上有更多的光。
也称为“春季前进时间”、“夏令时”和“节约时间”。
英文:
There seems to be something about Italy in general. Possibly they didnt do a Summer time one year that is confusing the function (Thats a guess)
$zones = [
'Europe/Rome', 'Europe/Malta', 'Europe/San_Marino', 'Europe/Vatican',
'Europe/Amsterdam', 'Europe/Andorra', 'Europe/Astrakhan', 'Europe/Athens',
'Europe/Belgrade', 'Europe/Berlin', 'Europe/Bratislava', 'Europe/Brussels',
'Europe/Bucharest' ,'Europe/Budapest', 'Europe/Busingen', 'Europe/Chisinau',
'Europe/Copenhagen', 'Europe/Dublin', 'Europe/Gibraltar', 'Europe/Guernsey',
'Europe/Helsinki', 'Europe/Isle_of_Man', 'Europe/Istanbul', 'Europe/Jersey',
'Europe/Kaliningrad', 'Europe/Kirov' , 'Europe/Kyiv', 'Europe/Lisbon',
'Europe/Ljubljana', 'Europe/London', 'Europe/Luxembourg', 'Europe/Madrid',
'Europe/Mariehamn', 'Europe/Minsk', 'Europe/Monaco',
'Europe/Moscow', 'Europe/Oslo', 'Europe/Paris', 'Europe/Podgorica',
'Europe/Prague','Europe/Riga' , 'Europe/Samara',
'Europe/Sarajevo' , 'Europe/Saratov', 'Europe/Simferopol',
'Europe/Skopje', 'Europe/Sofia' , 'Europe/Stockholm', 'Europe/Tallinn',
'Europe/Tirane', 'Europe/Ulyanovsk', 'Europe/Vaduz',
'Europe/Vienna', 'Europe/Vilnius', 'Europe/Volgograd', 'Europe/Warsaw',
'Europe/Zagreb', 'Europe/Zurich'];
foreach ( $zones as $zone){
$tz = new DateTimeZone($zone);
$a = new DateTime("2023-05-31", $tz);
$b = new DateTime("1970-05-31", $tz);
if ( $a->diff($b)->y != 53) {
printf (" !!! %s diff = %d\n", $zone, $a->diff($b)->y);
} else {
#printf ("%s diff = %d\n", $zone, $a->diff($b)->y);
}
}
RESULTS
!!! Europe/Rome diff = 52
!!! Europe/Malta diff = 52
!!! Europe/San_Marino diff = 52
!!! Europe/Vatican diff = 52
>It also does not happen if you start from 1971, so maybe the year with an issue is 1970
Found this on https://www.timeanddate.com/time/change/italy/rome?year=1970
which may go some way to explain.
31 May 1970 - Daylight Saving Time Started
When local standard time was about to reach
Sunday, 31 May 1970, 00:00:00 clocks were turned forward 1 hour to
Sunday, 31 May 1970, 01:00:00 local daylight time instead.
Sunrise and sunset were about 1 hour later on 31 May 1970 than the day before.
There was more light in the evening.
Also called Spring Forward, Summer Time, and Daylight Savings Time.
</details>
# 答案2
**得分**: 1
我自己测试了一下,发现了一些有趣的事情。正如我在评论中提到的,31号之间有一个小时的差异,但后来我注意到这一点:
$b = new DateTime("1970-05-31", new DateTimeZone('Europe/Rome'));
// = DateTime @12956400 {#7126
// date: 1970-05-31 01:00:00.0 Europe/Rome (+02:00),
// }
$b = new DateTime("1970-05-30", new DateTimeZone('Europe/Rome'));
// = DateTime @12870000 {#7124
// date: 1970-05-30 00:00:00.0 Europe/Rome (+01:00),
// }
如你所见,在31日有2小时的偏移,但在30日有1小时的偏移。通过查看https://www.timeanddate.com/time/zone/italy/rome ,我发现1970年5月31日凌晨12:00时,时间发生了变化,实际上并不存在12:00时,而是跳到了1:00时。比较是完整的比较,因此实际差异是`52年11个月30天23:00:00.0`。
<details>
<summary>英文:</summary>
Tested it myself, and I noticed something interesting. As I mentioned in my comment, there was a 1 hour difference between the 31st dates, but then I noticed this:
$b = new DateTime("1970-05-31", new DateTimeZone('Europe/Rome'));
// = DateTime @12956400 {#7126
// date: 1970-05-31 01:00:00.0 Europe/Rome (+02:00),
// }
$b = new DateTime("1970-05-30", new DateTimeZone('Europe/Rome'));
// = DateTime @12870000 {#7124
// date: 1970-05-30 00:00:00.0 Europe/Rome (+01:00),
// }
As you can see, on the 31st, there's a 2 hour offset, but on the 30th, there's a 1 hour offset. Checking with https://www.timeanddate.com/time/zone/italy/rome , the time changed on May 31st, 1970 at 12:00 am, so the 12am hour didn't actually exist, and it jumped to 1am. The comparison does a full comparison, and so the difference is actually `52y 11m 30d 23:00:00.0`
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论