Repository navigation
Fix GH-21616: DateTime::modify() wrong timestamp across DST transitions - #21669
MarcusXavierr wants to merge 6 commits into
Conversation
do_adjust_relative() adds h/i/s to wall-clock fields before converting to a Unix timestamp. Near a spring-forward gap that produces a nonexistent time, which resolves to the wrong offset. Fix: zero out relative h/i/s/us before timelib_update_ts(), apply them to sse directly. Same technique as timelib_add_wall(). y/m/d, weekday relatives, and first_last_day_of still go through timelib_update_ts. Also fixes phpGH-15880.
Always fold microseconds into seconds before SSE arithmetic instead of guarding with if-checks. Handle negative remainders correctly.
Remove section headers and redundant cases. Add -72h backward through fall-back, +61 minutes across spring-forward gap, and DateTimeImmutable.
Fix/gh 21616 84
|
Quoted below: written with Claude, an LLM, as CONTRIBUTING.md asks us to mark. The builds and test runs behind it are on my machine; the commands to repeat them are under the fold.
|
DateTime::modify()with relative h/i/s strings produces wrong timestamps near DST transitions.do_adjust_relative()adds hours, minutes, and seconds to wall-clock fields beforetimelib_update_ts()converts to a Unix timestamp. Near a spring-forward gap, that intermediate wall-clock time is ambiguous and resolves to the wrong side.add()/sub()don't have this problem —timelib_add_wall()adds h/i/s directly to SSE.In
php_date_modify(), striph,i,s, andusfrom the relative struct beforetimelib_update_ts(), then apply them viasse +=afterward. Full seconds are extracted from any microsecond overflow before the SSE step.timelib_update_ts()still handles y/m/d, weekdays, and special relatives, so calendar strings like'+3 days'and'first day of next month'are unaffected.Fixes GH-21616.
Fixes GH-15880.