php / php/php-src

DateInterval issues with negative directions

Aperta
#16,220 4 commenti 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Bug Extension: date
Lingua principale
C
Stelle
40.4k
Fork
8.1k
Merge medio
2g 13h
PR unite (30g)
96

Descrizione

Description

I am going to put a few connected issues I have noticed around DateInterval and DatePeriod into a single report:

1: DateInterval->invert is "readonly"

DateInterval:::__construct() only allows positive $duration e.g. P1D not P-1D (I appreciate this is the correct behaviour as it is based around the ISO8601 which has no concept of negative periods). However... the DateInterval->invert which allows the period to be reversed can only be changed by manually setting that property and the docs explicitly say:

The available properties listed below depend on PHP version, and should be considered as readonly.

It would be good to be able to change this property safely.

2: DateInterval::createFromDateString allows negative periods

DateInterval::createFromDateString('-1 day') is accepted but this sets DateInterval->d = -1 rather than using the ::invert property. This is inconsistent with the always-positive periods which __construct allows.

I would expect it to:

  • Reject mixed positive and negative period values, what would +1 year -6 month even mean?
  • Accept if only negative periods passed but then set ::invert = 1 and the properties of ::y..f as +ve
3: DateInterval::createFromDateString('-1 day') leads to infinite loop in DatePeriod
$datePeriod = new \DatePeriod(
    new \DateTimeImmutable('2000-01-01'),
    \DateInterval::createFromDateString('-1 day'),
    new \DateTimeImmutable('2000-01-05'),
);

echo iterator_count($datePeriod); // stuck in infinite loop
4: DateInterval::createFromDateString('-1 day') still doesn't work if start and end reversed in DatePeriod
$datePeriod = new \DatePeriod(
    new \DateTimeImmutable('2000-01-05'),
    \DateInterval::createFromDateString('-1 day'),
    new \DateTimeImmutable('2000-01-01'),
);

echo iterator_count($datePeriod); // 0 (but would expect 4)
5: DatePeriod doesn't respect DateInterval->invert
$dateInterval = new \DateInterval('P1D');
$dateInterval->invert = 1;

# will not go backwards from high to low dates
$datePeriod = new \DatePeriod(
    new \DateTimeImmutable('2000-01-05'),
    $dateInterval,
    new \DateTimeImmutable('2000-01-01'),
);

echo iterator_count($datePeriod); // 0 (but would expect 4)

# incorrectly goes forward from low to high dates
$datePeriod = new \DatePeriod(
    new \DateTimeImmutable('2000-01-01'),
    $dateInterval,
    new \DateTimeImmutable('2000-01-05'),
);

echo iterator_count($datePeriod); // 4 (but would expect 0)
PHP Version

8.3.114

Operating System

Rocky 8

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia riproducendo gli esempi utilizzando i punti di ingresso DateInterval e DatePeriod, inclusi gli intervalli negativi, le date invertite e la proprietà invert. Esamina il comportamento esistente dei periodi di date e definisci una semantica coerente per le direzioni negative, i segni misti e gli intervalli invertiti. Il lavoro è completato quando i casi segnalati hanno un comportamento definito, senza loop, e una copertura di regressione.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
php
Ambito
backend
Tipo di issue
Bug
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.