views:

614

answers:

2

The real, full contents of the file:

<?php

error_reporting(E_ALL);
ini_set(display_errors, 'on');

try {

    //$x = strtotime('blah');
    $x = new DateTime('lol');

} catch ( Exception $e ) {
        echo $e->getMessage();
}

The DateTime constructor accepts a string, which should throw an exception if it can't parse it. This runs fine on my local machine but on one of my remote servers the exception is not caught ( and again, I am using try/catch and the SAME EXACT code ):

Fatal error: Uncaught exception 'Exception' with message 'DateTime::__construct() [function.DateTime---construct]: Failed to parse time string (lol) at position 0 (l): The timezone could not be found in the database' in /var/www/html/site_com/rez/date.php:9 Stack trace: #0 /var/www/html/site_com/rez/date.php(9): DateTime->__construct('lol') #1 {main} thrown in /var/www/html/site_com/rez/date.php on line 9

Settings for remote server where the exception is not caught:

PHP Version 5.2.5

date date/time support enabled "Olson" Timezone Database Version 2007.9 Timezone Database internal Default timezone America/Chicago

Directive Local Value Master Value date.default_latitude 31.7667 31.7667 date.default_longitude 35.2333 35.2333 date.sunrise_zenith 90.583333 90.583333 date.sunset_zenith 90.583333 90.583333 date.timezone no value no value

My local settings where it does work:

PHP 5.2.10

date date/time support enabled "Olson" Timezone Database Version 0.system Timezone Database internal Default timezone System/Localtime

Directive Local Value Master Value date.default_latitude 31.7667 31.7667 date.default_longitude 35.2333 35.2333 date.sunrise_zenith 90.583333 90.583333 date.sunset_zenith 90.583333 90.583333 date.timezone no value no value

Locally, it catches the exception and prints the error out. The date.timezone on both is no value.

Perhaps it's just my internal system's timezones which are off? My local box is Ubuntu and my remote is CentOS, they're probably inconsistent but shouldn't PHP still catch the exception?

FYI I can't update PHP on the remote box since I don't have admin rights.

A: 

Not sure about the exact issue but try setting the time zone using this function:

date_default_timezone_set('Europe/London'); // or whatever timezone

And see if this works.

Sarfraz
The server that is not catching the exception already has one set (Default timezone America/Chicago).
Brock Batsell
yeah I already tried this before and it didn't seem to do anything.
meder
this is a weird problem then, let's see what is the solution for it then
Sarfraz
+3  A: 

My bet is on a php bug. I know that php used to have issues with catching exceptions thrown in constructors, and that seems to be what's going on here.

Because it's a bug, your options are

  1. Update the server's php version; you said this isn't an option
  2. Use strtotime() to find the date or, if you need or want access to the object-oriented style of DateTime, catch the error with strtotime()

For example:

<?php

try {

    if (@strtotime($str)) !== false) {
        $x = new DateTime($str);
    } else {
        throw new Exception("Failed to parse string ({$str})");
    }

} catch ( Exception $e ) {
    echo $e->getMessage();
}
Frankie
You might even try extending the DateTime class, and overriding the constructor with the code above, except instead of new DateTime you would use parent::__construct(). Remember that the prototype has to be the same, so your construct should take two parameters (string $str, DateTimeZone $timezone = null). This has the added benefit of determining whether the __construct() uncatchable exception bug is the source of your problems.
Frankie
Yeah I'm currently using strtotime and making sure it doesn't fail, then feeding it to the DateTime constructor - I'll try extending.
meder