New DateTime always results in date = "now"

Hi all,

Any idea why the below is always falling back to date == “now” even though I’m passing it a string such as “Monday 1st of February 2010”?

function convert_date_to_rss_format($datetime, $timezone, $timeformat, $time_h = “12”, $time_m = “00”, $time_s = “00”)
{

$convert_date_obj = new DateTime(strtotime($datetime)); 
$convert_date_obj->setTimezone(new DateTimeZone($timezone)); 
$convert_date_obj->setTime($time_h,  $time_m,  $time_s);
$formatted_date = $convert_date_obj->format($timeformat); 
return $formatted_date;

}

Thanks,

Break it down into something a little simpler…


$date = new DateTime('1st February 2010');
$date->setTimezone(new DateTimeZone('Europe/London'));

echo $date->format('r'); #Mon, 01 Feb 2010 00:00:00 +0000

$date->setTime(15, 30, 59);
echo $date->format('r'); #Mon, 01 Feb 2010 15:30:59 +0000

Chances are it’s due to a fault function parameter, or more likely the fact you’re passing an int (unix timestamp) to the constructor of the DateTime object when it expects a string as per my example.

Thanks. The only problem with your example is that the below can’t be something I simply type in as static. It’s from a page read into a variable then passed to this function.

$date = new DateTime(‘1st February 2010’);

needs to be

$date = new DateTime(‘$myvar’);

where $myvar arrives in the format of:

'$myvar = ‘Monday 1st of February 2010’;

It needs to go back to the format of “D, j M Y G:i:s T” hence from this = “Monday 1st of February 2010” into this = “1 February 2010”* to comply with RSS rules.

*Mon, 1 of February 2010" would also suffice.

It’s failing because this is failing:

strtotime($datetime)

where $datetime is in the format = “1st February 2010”.

Because it’s failing it reverts back to now().

Now, to figure out why it’s failing strtotime().

The problem you have is that ‘Monday 1st of February 2010’ cannot be parsed by the object or strtotime.

If the original format is always going to be the same, it’s fairly trivial to manipulate it. However, if the original format is subject change, you’re going to need to write a little library to parse it.


function format_date($date_str, $timezone = 'Europe/London', $hour = 0, $minute = 0, $seconds = 0, $format = 'D, j M Y G:i:s T'){
    
    $elements = explode(' ', $date_str);
    
    $date = new DateTime(
        vsprintf(
            '%s %s %s',
            array(
                $elements[1],
                $elements[3],
                $elements[4]
            )
        )
    );
    
    $date->setTimezone(
        new DateTimeZone($timezone)
    );
    
    $date->setTime(
        $hour,
        $minute,
        $seconds
    );
    
    return $date->format($format);
}

echo format_date('Monday 1st of February 2010'); #Mon, 1 Feb 2010 0:00:00 GMT

I’ve tried your method and it produces the following error. It seems it’s also having problems with $date_str passed to it in the format ‘Monday 1st of February 2010’;

Fatal error: Uncaught exception ‘Exception’ with message ‘DateTime::__construct() [<a href=‘datetime.–construct’>datetime.–construct</a>]: Failed to parse time string (Monday of February) at position 7 (o): The timezone could not be found in the database’ in C:\wamp\www\create_rss.php:341 Stack trace: #0 C:\wamp\www\create_rss.php(341): DateTime->__construct(‘Monday of Febru…’) #1 C:\wamp\www\create_rss.php(198): format_date(’ Monday 1st of …', ‘Europe/London’, ‘D, j M Y G:i:s …’) #2 {main} thrown in C:\wamp\www\create_rss.php on line 341

It doesn’t like the look of this it would seem:

$date = new DateTime(
vsprintf(
‘%s %s %s’,
array(
$elements[1],
$elements[3],
$elements[4]
)
)
);

Test the script I posted in isolation, it will work. It looks like the string you’re passing to the function is malformed, or contains preceding white-space.

We’ll throw a trim call around the $date_str var before explode’ing it, but you need to add validation and learn how to debug this sort of thing. I do however, commend your persistance, you’re on the right track but just need to start a little smaller. :wink:

If a function fails, test it with expected values. If it works, your values (parameters) are wrong…


function format_date($date_str, $timezone = 'Europe/London', $hour = 0, $minutes = 0, $seconds = 0, $format = 'D, j M Y G:i:s T'){
    
    $elements = explode(' ', trim($date_str));
    
    $date = new DateTime(
        vsprintf(
            '&#37;s %s %s',
            array(
                $elements[1],
                $elements[3],
                $elements[4]
            )
        )
    );
    
    $date->setTimezone(
        new DateTimeZone($timezone)
    );
    
    $date->setTime(
        $hour,
        $minutes,
        $seconds
    );
    
    return $date->format($format);
}

echo format_date('Monday 1st of February 2010'); #Mon, 1 Feb 2010 0:00:00 GMT

Correction, it will work providing you force feed it with the trim() function :slight_smile:

And the funny thing is I’m not leaving any spaces when I assign the date, the date() function must be throwing in a space there to display on the web page.

Two minds better than one hey, thanks a lot.

Did you know there is a function already for parsing any formatted date string?
Well…for PHP 5.3 anyways…

http://us3.php.net/manual/en/function.date-parse-from-format.php

No I didn’t. Indeed there is. Thanks. Something to keep in mind once they update PHP to 5.3 as it’s currently 5.2 something.