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: 2019-05-11 23:44 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: Re-Opened Package: Date/time related
PHP Version: 5.5.22 OS: Ubuntu 14.04
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [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.

...
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Wed Oct 21 22:01:23 2020 UTC