Miscalculation of a date using microseconds
オープン
まだ誰も着手していません。
Bug
Extension: date
Status: Needs Triage
- 主要言語
- C
- スター
- 40.4k
- フォーク
- 8.2k
- 平均マージ
- 2日 13時間
- マージ済み PR(30日)
- 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 にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- 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