php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78496 date_create rolls a day back on year 0000 timestamp
Submitted: 2019-09-05 15:56 UTC Modified: 2021-10-01 17:11 UTC
From: dzuczek at dlc-solutions dot com Assigned: cmb (profile)
Status: Duplicate Package: Date/time related
PHP Version: 7.2.22 OS: Linux
Private report: No CVE-ID: None
 [2019-09-05 15:56 UTC] dzuczek at dlc-solutions dot com
Description:
------------
date_create seems to roll back a day when given a timestamp in the year 0000

this worked as expected in PHP 7.1, does not work in PHP 7.2 or greater

Test script:
---------------
Not working (year 0000): https://3v4l.org/manbk
Working (year 0001): https://3v4l.org/uMjtB

<?php
$timestamp = strtotime('0000-02-20 00:00:00 UTC'); // has issues
$timestamp2 = strtotime('0001-02-20 00:00:00 UTC'); // this is okay

// this has issues
print $timestamp . "\n";
$date_time = date_create('@' . $timestamp);
print_r($date_time);

// this is fine
print $timestamp2 . "\n";
$date_time2 = date_create('@' . $timestamp2);
print_r($date_time2);
?>

Expected result:
----------------
Using 0000-02-20 00:00:00 UTC

Expected (PHP 7.1)

DateTime Object
(
    [date] => 0000-02-20 00:00:00.000000
    [timezone_type] => 1
    [timezone] => +00:00
)

Actual result:
--------------
Using 0000-02-20 00:00:00 UTC

Actual (PHP 7.2+)

DateTime Object
(
    [date] => 0000-02-19 00:00:00.000000
    [timezone_type] => 1
    [timezone] => +00:00
)

The resulting date has been rolled back a day.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-09-05 16:02 UTC] dzuczek at dlc-solutions dot co
Passing a date instead of seconds does work:

https://3v4l.org/cRcKS

<?php

$date_time = date_create('0000-02-20 00:00:00 UTC');
print_r($date_time);

$date_time = date_create('0001-02-20 00:00:00 UTC');
print_r($date_time);
?>
 [2019-09-05 16:24 UTC] dzuczek at dlc-solutions dot com
More tests, looks like it's just February dates...

0000-01-20 00:00:00 UTC (works) https://3v4l.org/2hPTv
0000-02-20 00:00:00 UTC (fails) https://3v4l.org/manbk
0000-03-20 00:00:00 UTC (works) https://3v4l.org/SMI46
 [2019-09-05 16:47 UTC] cmb@php.net
Well, actually there is no year 0 in the Gregorian calendar.
 [2019-09-05 23:41 UTC] alexanderpas at gmail dot com
ISO 8601 defines the year zero as the year 1 BC in the Gregorian calendar.

The last few days in January are also affected.
 [2020-01-20 17:14 UTC] girgias@php.net
-Assigned To: +Assigned To: derick
 [2020-04-17 06:31 UTC] alexanderpas at gmail dot com
This also affects getting a timestamp out of a DateTime object created with a timestamp. (Where the output should always be the same as the input)

See https://bugs.php.net/bug.php?id=78499 which has some additional testcases.
 [2021-02-08 05:01 UTC] justinpor119 at gmail dot com
The date was parsed in UTC (GMT) because you provided a date-only string without any time zone indicator. If you had given a date/time string w/o an indicator instead (new Date("2011-09-24T00:00:00")), it would have been parsed in your local timezone.
 [2021-10-01 17:11 UTC] cmb@php.net
-Status: Assigned +Status: Duplicate -Assigned To: derick +Assigned To: cmb
 [2021-10-01 17:11 UTC] cmb@php.net
> ISO 8601 defines the year zero as the year 1 BC in the Gregorian
> calendar.

Oh, right.  They also say that "values in the range [0000] through
[1582] shall only be used by mutual agreement of the partners in
information interchange."

Anyhow, this is a duplicate of bug #77243.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 07 14:01:28 2024 UTC