php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #69205 DateTime for December 31st fails once every 400 years
Submitted: 2015-03-09 15:23 UTC Modified: 2021-04-08 07:53 UTC
Votes:6
Avg. Score:3.2 ± 1.2
Reproduced:4 of 4 (100.0%)
Same Version:2 (50.0%)
Same OS:1 (25.0%)
From: nd dot wortel at gmail dot com Assigned: derick (profile)
Status: Not a bug Package: Date/time related
PHP Version: 8.0.3 OS: Ubuntu 20.04
Private report: No CVE-ID: None
 [2015-03-09 15:23 UTC] nd dot wortel at gmail dot com
Description:
------------
A DateTime (or DateTimeImmutable) object can not be created with date '2369-12-31', '2769-12-31', '3169-12-31', etc. Instead, a DateTime object with date '2370-01-00' (or '2770-01-00', '3170-01-00', etc.) is created. This happens every 400 years on December 31st.

Years in the past are not affected: '1969-12-31' and '1569-12-31' work just fine. Therefore, this has probably something to do with the Unix time system.

Note: my PHP version is actually PHP 5.5.9-1ubuntu4.6.

This bug is probably also causing the behavior described here: https://bugs.php.net/bug.php?id=67993

Test script:
---------------
<?php

$dateTime = new DateTime('2369-12-31'); // or 2769, 3169, etc.

var_dump($dateTime);

Expected result:
----------------
object(DateTime)[1]
  public 'date' => string '2369-12-31 00:00:00' (length=19)
  public 'timezone_type' => int 3
  public 'timezone' => string 'Europe/Amsterdam' (length=16)

Actual result:
--------------
object(DateTime)[1]
  public 'date' => string '2370-01-00 00:00:00' (length=19)
  public 'timezone_type' => int 3
  public 'timezone' => string 'Europe/Amsterdam' (length=16)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-03-09 15:47 UTC] derick@php.net
-Assigned To: +Assigned To: derick
 [2015-06-15 11:31 UTC] riggsfolly at gmail dot com
This also appears to be demonstrating the same or similiar problem

<?php

$test = date_create("-1000-12-27");
echo date_format($test, 'Y-m-d H:i:s').PHP_EOL;
date_modify($test, '+1 day');
echo date_format($test, 'Y-m-d H:i:s').PHP_EOL.PHP_EOL;


$test = date_create("-2000-12-27");
echo date_format($test, 'Y-m-d H:i:s').PHP_EOL;
date_modify($test, '+1 day');
echo date_format($test, 'Y-m-d H:i:s').PHP_EOL.PHP_EOL;


$test = date_create("-3000-12-27");
echo date_format($test, 'Y-m-d H:i:s').PHP_EOL;
date_modify($test, '+1 day');
echo date_format($test, 'Y-m-d H:i:s').PHP_EOL.PHP_EOL;

RESULTS:
-1000-12-28 00:00:00
-1000-12-30 00:00:00

-2000-12-27 00:00:00
-2000-12-28 00:00:00

-3000-12-28 00:00:00
-3000-12-30 00:00:00
 [2015-06-15 11:35 UTC] riggsfolly at gmail dot com
This also appears to be a problem in all releases 

Errored in 5.3/5.4/5.5/5.6
 [2015-10-28 10:04 UTC] nd dot wortel at gmail dot com
The following test shows that this is a problem in PHP 5.4, 5.5, 5.6 and 7. PHP 5.3 does not seem to be affected: https://travis-ci.org/nicwortel/nicwortel/php-date-bug
 [2018-09-30 14:04 UTC] cmb@php.net
Confirmed: <https://3v4l.org/bDjLn>.  Obviously fixed in PHP 7.2+.
 [2019-05-11 11:10 UTC] cmb@php.net
Indeed, still good for all actively supported versions[1].

<https://www.php.net/supported-versions.php>
 [2019-05-11 13:31 UTC] nic at nicwortel dot nl
No, this is still an issue in PHP 7.2+: https://3v4l.org/pj2EK
 [2019-05-11 23:44 UTC] cmb@php.net
-Status: Assigned +Status: Re-Opened
 [2019-05-11 23:44 UTC] cmb@php.net
You're right.  Thanks!
 [2020-09-02 18:20 UTC] kevin at arcpointgroup dot com
This appears to be an incorrect implementation of the Gregorian calendar system. Note that years divisible by 100 are not leap years, but those divisible by 400 are leap years in the Gregorian calendar.

Running some spot checks on this bug reveals a pattern:

- Years that round up to a value evenly divisible by 400 present this issue.
- Years that round up to a value not evenly divisibly by 400 do not.

Examples:

- 2769 rounds to 2800 (a leap year) and presents the bug.
- 2869 rounds to 2900 (non leap year) and does not present the bug.

- 3169 rounds to 3200 (a leap year) and presents the bug.
- 3269 rounds to 3300 (non leap year) and does not present the bug.

- 3569 rounds to 3600 (a leap year) and presents the bug.
- 3669 rounds to 3700 (non leap year) and does not present the bug.

...
 [2021-04-05 16:04 UTC] derick@php.net
-Status: Re-Opened +Status: Not a bug
 [2021-04-05 16:04 UTC] derick@php.net
Thank you for taking the time to report a problem with PHP.
Unfortunately you are not using a current version of PHP --
the problem might already be fixed. Please download a new
PHP version from http://www.php.net/downloads.php

If you are able to reproduce the bug with one of the latest
versions of PHP, please change the PHP version on this bug report
to the version you tested and change the status back to "Open".
Again, thank you for your continued support of PHP.

This got fixed in PHP 7.2 already.
 [2021-04-08 07:53 UTC] nd dot wortel at gmail dot com
-Operating System: Ubuntu 14.04 +Operating System: Ubuntu 20.04 -PHP Version: 5.5.22 +PHP Version: 8.0.3
 [2021-04-08 07:53 UTC] nd dot wortel at gmail dot com
Please have a look at https://3v4l.org/fliGH. It seems like 2369-12-31 has been fixed with PHP 7.2.0, but 2769-12-31, 3169-12-31, etc. are still affected.
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Fri Apr 16 08:01:23 2021 UTC