2011-01-11 11 views
5

Tengo un código (es parte de un complemento de WordPress) que toma una cadena de texto, y el especificador de formato dado a date(), e intenta analizarlo en una matriz que contiene hora, minuto, segundo, día, mes, año.Analizando cadenas de fechas localizadas en PHP

la actualidad, utilizo el siguiente código (tenga en cuenta que strtotime es terriblemente poco fiables con cosas como 01/02/03)

// $format contains the string originally given to date(), and $content is the rendered string 
if (function_exists('date_parse_from_format')) { 
    $content_parsed = date_parse_from_format($format, $content); 
} else { 
    $content = preg_replace("([0-9]st|nd|rd|th)","\\1",$content); 
    $content_parsed = strptime($content, dateFormatToStrftime($format)); 
    $content_parsed['hour']=$content_parsed['tm_hour']; 
    $content_parsed['minute']=$content_parsed['tm_min']; 
    $content_parsed['day']=$content_parsed['tm_mday']; 
    $content_parsed['month']=$content_parsed['tm_mon'] + 1; 
    $content_parsed['year']=$content_parsed['tm_year'] + 1900; 
} 

En realidad, esto funciona bastante bien, y parece manejar todas las combinaciones que he tirado en eso.

Sin embargo, hace poco alguien me dio 24 Ноябрь, 2010. Esto es ruso el 24 de noviembre de 2010 [el formato de fecha era j F, Y], y se analiza como year = 2010, month = null, day = 24.

¿Hay alguna función que pueda usar que sepa cómo traducir? ambos noviembre y Ноябрь en 11?

EDIT:

Correr print_r(setlocale(LC_ALL, 0));C rendimientos. Cambiar de nuevo a strptime() parece solucionar el problema, pero los documentos advierten:

Internamente, esta función llama a la función strptime() proporcionado por la librería C del sistema. Esta función puede mostrar un comportamiento notablemente diferente en diferentes sistemas operativos. El uso de date_parse_from_format(), que no sufre estos problemas, se recomienda en PHP 5.3.0 y posterior.

Es date_parse_from_format() la API correcta, y si es así, ¿cómo logro que reconozca el idioma?

Respuesta

3

intenta establecer la configuración regional a Rusia as hinted in the manual:

mes y día de la semana nombres y otras cadenas dependientes del idioma respetan la localización actual de conjunto con setlocale()(LC_TIME).

+0

El problema es que es un complemento que otros podrían usar ... sería bueno encontrar una solución "adecuada". Pero creo que me quedaré con 'strptime()' hasta que encuentre un caso cuando no esté funcionando ... – Mikeage

+0

@Mikeage A UnitTest es correcto :) Puede intentar si 'date_create_from_format' puede analizar cadenas localizadas. No creo que sí, pero pruébalo. – Gordon

+0

Intenté strptime() y date_create_from_format para analizar una fecha italiana, como 18 Mag 2013 (= 2013-05-18) sin éxito. – damko

1

puede tratar de tomar un parámetro de configuración regional y llamar a locale_set_default ($ locale) antes de realizar el análisis de la fecha.

$originalLocale = locale_get_default(); 
$locale ? $locale : $originalLocale; 
locale_set_default(locale); 

// date parsing code 

locale_set_default($originalLocale); 

No he probado esto pero es un intento de prueba. FYI, creo que la cadena local para ruso es "ru-Latn"

+0

Mi problema es que no sé cuál es la ubicación, y supongo que ya está configurado – Mikeage

0

Veo que la pregunta ya está respondida, pero ninguna de las soluciones proporcionadas funcionó para mí.

Esta es mi solución:

if(!preg_match('/^en_US/', $locale)){ 

    $months_short = array('jan' => t('jan'), 'feb' => t('feb'), 'mar' => t('mar'), 'apr' => t('apr'), 
      'may' => t('may'), 'jun' => t('giu'), 'jul' => t('lug'), 'aug' => t('ago'), 
      'sep' => t('set'), 'oct' => t('ott'), 'nov' => t('nov'), 'dec' => t('dec')); 

    foreach ($months_short as $month_short => $month_short_translated) { 
     $date = preg_replace('/'.$month_short_translated.'/', $month_short, strtolower($date)); 
    } 

} 

$pieces = date_parse_from_format($format,$date); 

if($pieces && $pieces['error_count'] == 0 && checkdate($pieces['month'], $pieces['day'], $pieces['year'])){ 

    return date('Y-m-d', mktime(0,0,0,$pieces['month'],$pieces['day'],$pieces['year'])); 

} 

Donde t() devuelve la abreviatura traducido para el mes.

Probablemente no sea la mejor solución (porque falla si no hay una traducción válida) pero funciona para mi caso.