Miscalculation of a date using microseconds
未关闭
还没有人认领这个 Issue。
Bug
Extension: date
Status: Needs Triage
- 主要语言
- C
- 星标
- 40.4k
- 派生
- 8.2k
- 平均合并
- 2 天 13 小时
- 30 天内合并 PR
- 96
描述
Description
The following code:
<?php
date_default_timezone_set("UTC");
$beginningOfYear = new \DateTimeImmutable('1st january this year')
->setTime(0, 0);
$endOfYear = new \DateTimeImmutable('31th december this year')
->setTime(23, 59, 59, 999999);
$uuThisYear = (int) $endOfYear->format('Uu') - (int) $beginningOfYear->format('Uu');
$sThisYear = (int) $endOfYear->format('U') - (int) $beginningOfYear->format('U');
$usThisYear = (int) $endOfYear->format('u') - (int) $beginningOfYear->format('u');
$uuThisYear2 = (int) ($sThisYear . $usThisYear);
echo "<pre>" . var_export([
'from' => $beginningOfYear,
'fromMs' => (int) $beginningOfYear->format('Uu'),
'to' => $endOfYear,
'toMs' => (int) $endOfYear->format('Uu'),
'nbMicrosecondsBetweenToAndFrom' => $uuThisYear,
'nbMicrosecondsBetweenToAndFromOtherCalculation' => $uuThisYear2,
'equal' => $uuThisYear === $uuThisYear2,
'nbSecondsBetweenToAndFrom' => $sThisYear,
'nbUsecondsBetweenToAndFrom' => $usThisYear,
'shouldEqualToFromButDoesntWork' => (clone $endOfYear)->modify('-' . $uuThisYear . ' µsec'),
'shouldEqualToFromWorks' => (clone $endOfYear)
->modify('-' . $sThisYear . ' seconds')
->modify('-' . $usThisYear . ' microseconds'),
], true);
Resulted in this output:
array (
'from' =>
\DateTimeImmutable::__set_state(array(
'date' => '2025-01-01 00:00:00.000000',
'timezone_type' => 3,
'timezone' => 'UTC',
)),
'fromMs' => 1735689600000000,
'to' =>
\DateTimeImmutable::__set_state(array(
'date' => '2025-12-31 23:59:59.999999',
'timezone_type' => 3,
'timezone' => 'UTC',
)),
'toMs' => 1767225599999999,
'nbMicrosecondsBetweenToAndFrom' => 31535999999999,
'nbMicrosecondsBetweenToAndFromOtherCalculation' => 31535999999999,
'equal' => true,
'nbSecondsBetweenToAndFrom' => 31535999,
'nbUsecondsBetweenToAndFrom' => 999999,
'shouldEqualToFromButDoesntWork' =>
\DateTimeImmutable::__set_state(array(
'date' => '2026-01-01 09:59:59.999998',
'timezone_type' => 3,
'timezone' => 'UTC',
)),
'shouldEqualToFromWorks' =>
\DateTimeImmutable::__set_state(array(
'date' => '2025-01-01 00:00:00.000000',
'timezone_type' => 3,
'timezone' => 'UTC',
)),
)
But I expected this output instead:
array (
'from' =>
\DateTimeImmutable::__set_state(array(
'date' => '2025-01-01 00:00:00.000000',
'timezone_type' => 3,
'timezone' => 'UTC',
)),
'fromMs' => 1735689600000000,
'to' =>
\DateTimeImmutable::__set_state(array(
'date' => '2025-12-31 23:59:59.999999',
'timezone_type' => 3,
'timezone' => 'UTC',
)),
'toMs' => 1767225599999999,
'nbMicrosecondsBetweenToAndFrom' => 31535999999999,
'nbMicrosecondsBetweenToAndFromOtherCalculation' => 31535999999999,
'equal' => true,
'nbSecondsBetweenToAndFrom' => 31535999,
'nbUsecondsBetweenToAndFrom' => 999999,
'shouldEqualToFromButDoesntWork' =>
\DateTimeImmutable::__set_state(array(
'date' => '2025-01-01 00:00:00.000000',
'timezone_type' => 3,
'timezone' => 'UTC',
)),
'shouldEqualToFromWorks' =>
\DateTimeImmutable::__set_state(array(
'date' => '2025-01-01 00:00:00.000000',
'timezone_type' => 3,
'timezone' => 'UTC',
)),
)
Check the "shouldEqualToFromButDoesntWork" value.
PHP Version
8.4.14
Operating System
Mint 22.2 Zara
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
Start by reproducing the DateTimeImmutable::modify('-... µsec') case from the issue on PHP 8.4.14, then trace the date/time implementation that handles microsecond modifiers. Compare it with the separate seconds-and-microseconds calls; done when the single microsecond subtraction produces the same 2025-01-01 00:00:00.000000 result.
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- php
- 领域
- backend
- Issue 类型
- 缺陷
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 活跃度
- 停滞
- 描述清晰度
- 描述清楚
- 新手友好度
- 42/100