php / php/php-src

Miscalculation of a date using microseconds

Abierto
#20,550 1 comentario 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Bug Extension: date Status: Needs Triage
Lenguaje dominante
C
Estrellas
40.4k
Forks
8.1k
Merge medio
2 d 13 h
PR fusionados (30 d)
96

Descripción

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

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

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.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
php
Área
backend
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Bien especificado
Aptitud para principiantes
42/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.