views:

242

answers:

2

Hello folks. Last week a released a 2.0 beta version of my Events Manager plugin, which produces a list of events. Among the many bugs floating around, there is one I cannot fix. The bug seems to manifest itself only on a tester's server with PHP 4.4.8; works allright on PHP 5. When I try to use the H:i php time format, I always get midnight (00:00). The issue is with the wordpress function mysql2date. This function is a wrapper around the date function.
I isolated the problem and inserted this in the website template:

echo (mysql2date("H:i", "0000-00-00 13:24:00"));

The result was

00:00

At first I thought it was a wordpress bug, but then I rewrote my function to employ date() straightaway. The result was even stranger, instead of midnight I got 11:59. Quite strangerly, both mysql2date and date seem to work allright on every other part of the plugin. Also, as I said, I cannot reproduce the bug on my server, only 2 users signalled it.

Since I was asked, here's the mysql2date code; it's part of Wordpress:

/**
 * Converts MySQL DATETIME field to user specified date format.
 *
 * If $dateformatstring has 'G' value, then gmmktime() function will be used to
 * make the time. If $dateformatstring is set to 'U', then mktime() function
 * will be used to make the time.
 *
 * The $translate will only be used, if it is set to true and it is by default
 * and if the $wp_locale object has the month and weekday set.
 *
 * @since 0.71
 *
 * @param string $dateformatstring Either 'G', 'U', or php date format.
 * @param string $mysqlstring Time from mysql DATETIME field.
 * @param bool $translate Optional. Default is true. Will switch format to locale.
 * @return string Date formated by $dateformatstring or locale (if available).
 */
function mysql2date( $dateformatstring, $mysqlstring, $translate = true ) {
 global $wp_locale;
 $m = $mysqlstring;
 if ( empty( $m ) )
  return false;

 if( 'G' == $dateformatstring ) {
  return gmmktime(
   (int) substr( $m, 11, 2 ), (int) substr( $m, 14, 2 ), (int) substr( $m, 17, 2 ),
   (int) substr( $m, 5, 2 ), (int) substr( $m, 8, 2 ), (int) substr( $m, 0, 4 )
  );
 }

 $i = mktime(
  (int) substr( $m, 11, 2 ), (int) substr( $m, 14, 2 ), (int) substr( $m, 17, 2 ),
  (int) substr( $m, 5, 2 ), (int) substr( $m, 8, 2 ), (int) substr( $m, 0, 4 )
 );

 if( 'U' == $dateformatstring )
  return $i;

 if ( -1 == $i || false == $i )
  $i = 0;

 if ( !empty( $wp_locale->month ) && !empty( $wp_locale->weekday ) && $translate ) {
  $datemonth = $wp_locale->get_month( date( 'm', $i ) );
  $datemonth_abbrev = $wp_locale->get_month_abbrev( $datemonth );
  $dateweekday = $wp_locale->get_weekday( date( 'w', $i ) );
  $dateweekday_abbrev = $wp_locale->get_weekday_abbrev( $dateweekday );
  $datemeridiem = $wp_locale->get_meridiem( date( 'a', $i ) );
  $datemeridiem_capital = $wp_locale->get_meridiem( date( 'A', $i ) );
  $dateformatstring = ' ' . $dateformatstring;
  $dateformatstring = preg_replace( "/([^\\\])D/", "\\1" . backslashit( $dateweekday_abbrev ), $dateformatstring );
  $dateformatstring = preg_replace( "/([^\\\])F/", "\\1" . backslashit( $datemonth ), $dateformatstring );
  $dateformatstring = preg_replace( "/([^\\\])l/", "\\1" . backslashit( $dateweekday ), $dateformatstring );
  $dateformatstring = preg_replace( "/([^\\\])M/", "\\1" . backslashit( $datemonth_abbrev ), $dateformatstring );
  $dateformatstring = preg_replace( "/([^\\\])a/", "\\1" . backslashit( $datemeridiem ), $dateformatstring );
  $dateformatstring = preg_replace( "/([^\\\])A/", "\\1" . backslashit( $datemeridiem_capital ), $dateformatstring );

  $dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 );
 }
 $j = @date( $dateformatstring, $i );

 /*
 if ( !$j ) // for debug purposes
  echo $i." ".$mysqlstring;
 */

 return $j;
}

If you're interested, you can download the code of my plugin here, the problem is on line 613 of events-manager.php.

Can this have something to do with PHP or apache settings?

Thanks in advance for any suggestion.

Davide

A: 

Not a fix, but an alternative - use UNIX_TIMESTAMP in your mysql statement instead of converting it afterwards.

SELECT UNIX_TIMESTAMP(date_created) AS date

adam
Thanks for the suggestion. I actually ended up implementing another workaround, but this is alsoa good idea.
nutsmuggler
A: 

I guess I have solved this issue. The problem was 0000-00-00, apparently not a valid time mysql2date value in some PHP/MySql combos (quite understandably, I am looking at you, month 00...) . I ended up using echo (mysql2date("H:i", "2000-10-10 13:24:00"));

Since I am just interested in the hours and minute a more casual date does the job. Problem solved.

nutsmuggler