PHP 8 date week number inconsistent?

When I use (new DateTime(time()))->format("W") it sometimes returns the correct value (15 for time() = ‘1618404852’), but sometimes it returns an incorrect value (16 for time() = ‘1618404853’).

Those timestamps are not exactly between two weeks, because using ‘1618404855’ as a timestamp will result in 15 (which is correct).

My code testing this is:

echo (new DateTime("1618404852"))->format("W");
echo "n";
echo (new DateTime("1618404853"))->format("W");
echo "n";
echo (new DateTime("1618404854"))->format("W");
echo "n";
echo (new DateTime("1618404855"))->format("W");
echo "n";
echo (new DateTime("1618404856"))->format("W");

This results in:

15
16
16
15
15

which makes no sense to me. Am I doing something wrong here?

I’ve tried this on a local php-Server (8.0.0), as well as on a different machine running apache-php (7.4). Using a phpfiddle website results in the same problem.

Answer

Displaying the full date for each example with format(“Y-m-d H:i:s”) reveals what’s going on here (demo):

4852-04-14 16:18:40
4853-04-14 16:18:40
4854-04-14 16:18:40
4855-04-14 16:18:40
4856-04-14 16:18:40

The default constructor is trying to guess what your strings mean, and guessing that the last four digits are a year.

To force it to treat the strings as timestamps you can:

  • prefix them with an @
  • use createFromFormat with the ‘U’ format
  • create an object and then call setTimestamp on it
echo (new DateTime("1618404852"))->format("Y-m-d H:i:s");
// 4852-04-14 16:18:40
echo (new DateTime("@1618404852"))->format("Y-m-d H:i:s");
// 2021-04-14 12:54:12
echo DateTime::createFromFormat("U", "1618404852")->format("Y-m-d H:i:s");
// 2021-04-14 12:54:12
echo (new DateTime)->setTimestamp(1618404852)->format("Y-m-d H:i:s");
// 2021-04-14 12:54:12