Consistent dates in PHP?
It’s really interesting how small changes in core PHP functionality could break whole website and take hours to find the cause of the bug.
I am building website which takes some use of dates, stored in MySQL database as Date format for simplicity
Those dates are optional fields in my application and sometimes they have Zero Date format: ‘0000-00-00‘ which works perfectly on my development environment. Locally I am using PHP 5.3.4 not latest but allows me to spot any backward compatibility issues and probably it’s more laziness for not upgrading than any other sophisticated reason. Anyhow on production I run PHP 5.3.24 and so far everything has been just OK, running smoothly with no issues.
The dates needed to be transferred from MySQL format to human-readable format on the front-end and once submitted through a form back to MySQL format so I added some logic to handle the dates format. Once I moved the code to production suddenly I got an odd error:
[cc lang=”php”]DateTime::__construct() [datetime.–construct]: Failed to parse time string (30-11–0001) at position 0 (3): Unexpected character[/cc]
That was the whole message no file lines or any other trace output. So I started digging and found the code that was causing the problem but it wasn’t very clear why. Same code worked differently on both environments so next step was RTFM so I’ve read the manual and found something interesting, this piece of code:
[cc lang=”php”]$d = new DateTime(“0000-00-00”);
$d->format(“d-m-Y”); // “-0001-11-30″[/cc]
In my code I was parsing the value from the database once and I was trying to format it second time on the front-end something like:
[cc lang=”php”]$date = new DateTime(‘0000-00-00’)->toFormat(‘d-m-Y’); // -0001-11-30
$date = new DateTime($date); // Fatal error[/cc]
This also valid for the following code:
[cc lang=”php”]date(‘d-m-Y’, strtotime(‘0000-00-00’)); // 30-11–0001[/cc]
In my local version the same code was working because the above functions were returning different results, e.g.:
[cc lang=”php”]date(‘d-m-Y’, strtotime(‘0000-00-00’)); // 01-01-1970[/cc]
So one option to solve the problem is to prevent saving zero dates in the database with PHP validation and setting to time() just so you know in MySQL you can’t use a function like NOW() for a default value for Date/DateTime fields or any other fields too.