php / php/php-src

DateTime setISODate() results in wrong timestamp?

Open
#13,267 9 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug Extension: date Status: Needs Triage
Dominant language
C
Stars
40.4k
Forks
8.1k
Avg merge
2d 13h
Merged PRs (30d)
96

Description

Description

I call every Monday a cronjob at 00:01. I want known the year and week from last week.

<?php
$dt = new DateTime('last week monday 00:00:01', new DateTimeZone('Europe/Berlin'));
$year = (int)$dt->format('Y');
$week = (int)$dt->format('W');

// After this, I call a second script with parameters ($year and $week) few times for different tasks

$dto = new DateTime();
$dto->setISODate($year, $week);

$fmt = new IntlDateFormatter('de_DE', IntlDateFormatter::NONE, IntlDateFormatter::NONE, 'Europe/Berlin');
$fmt->setPattern('LLL dd');

// Hint: $dto->getTimestamp() is the date a week ago, but with current time. So its always the time its called.

$week_start = $fmt->format($dto->getTimestamp());
$dto->modify('+6 days'); // for sunday
$week_end = $fmt->format($dto->getTimestamp());

echo $week_start . ' - ' . $week_end;

Resulted in this output:

Jan 23 - Jan 29

But I expected this output instead, for Timezone 'Europe/Berlin':

Jan 22 - Jan 28

The parameters $year and $week are only determined once. With these two values, the same script is called several times to create each time a graphic containing the date for the Monday and Sunday of the previous week. The script is called by a cronjob 00:01 every Monday. The graphics were created on the server at 00:01:23 and later. The script needs less than 1 second to create the graphics.

So I remove the images and call the script again ~9 o'clock and its shows me now the correct values "Jan 22 - Jan 28".
Is this a bug or am I doing something wrong here?

Because its worked for many years, but since 2024 its startet with wrong dates (one date shifted). Executed/Generated on:
✗ 03.01. wrong date for last week December.
✗ 08.01. again wrong date for first week January
15.01. shows the correct dates! "08 - 14"
22.01. shows the correct dates! "15 - 21"
✗ 29.01. again wrong date "23 - 29" must be "22 - 28"

So its strange.

Server timezone with timedatectl shows:

Local time: Mon 2024-01-29 10:53:00 CET
Universal time: Mon 2024-01-29 09:53:00 UTC
RTC time: Mon 2024-01-29 09:53:00
Time zone: Europe/Berlin (CET, +0100)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no

PHP Version

PHP 8.2.15

Operating System

AlmaLinux 8.9

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the supplied PHP 8.2.15 script around DateTime::setISODate(), timezone handling, and the retained time value. Compare the Monday and Sunday output at the reported execution times, then inspect the relevant date/time implementation and tests. Done means establishing whether this is incorrect behavior and adding a focused regression test or documenting the expected usage.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.