2011-03-22 24 views
9

He estado desarrollando en php 5.3.php dateTime :: createFromFormat en 5.2?

Sin embargo, nuestro servidor de producción es 5.2.6.

He estado usando

$schedule = '31/03/2011 01:22 pm'; // example input 
if (empty($schedule)) 
    $schedule = date('Y-m-d H:i:s'); 
else { 
    $schedule = dateTime::createFromFormat('d/m/Y h:i a', $schedule); 
    $schedule = $schedule->format('Y-m-d H:i:s'); 
} 
echo $schedule; 

Sin embargo esa función no está disponible en 5,2

¿Cuál es la forma más fácil de evitar esto (no hay posibilidad de una actualización de PHP).

Respuesta

19

basta con incluir el siguiente código

function DEFINE_date_create_from_format() 
    { 

function date_create_from_format($dformat, $dvalue) 
    { 

    $schedule = $dvalue; 
    $schedule_format = str_replace(array('Y','m','d', 'H', 'i','a'),array('%Y','%m','%d', '%I', '%M', '%p') ,$dformat); 
    // %Y, %m and %d correspond to date()'s Y m and d. 
    // %I corresponds to H, %M to i and %p to a 
    $ugly = strptime($schedule, $schedule_format); 
    $ymd = sprintf(
     // This is a format string that takes six total decimal 
     // arguments, then left-pads them with zeros to either 
     // 4 or 2 characters, as needed 
     '%04d-%02d-%02d %02d:%02d:%02d', 
     $ugly['tm_year'] + 1900, // This will be "111", so we need to add 1900. 
     $ugly['tm_mon'] + 1,  // This will be the month minus one, so we add one. 
     $ugly['tm_mday'], 
     $ugly['tm_hour'], 
     $ugly['tm_min'], 
     $ugly['tm_sec'] 
    ); 
    $new_schedule = new DateTime($ymd); 

    return $new_schedule; 
    } 
} 

if(!function_exists("date_create_from_format")) 
DEFINE_date_create_from_format(); 
+0

Esta es una GRAN respuesta. ¡Realmente debería obtener más votos positivos! Gracias – andreapier

+0

Soporte para DateTime 'M': '' '$ schedule_format = str_replace (array ('M', 'Y', 'm', 'd', 'H', 'i', 'a'), array ('% b', '% Y', '% m', '% d', '% I', '% M', '% p'), $ dformat); '' ' – kenorb

+0

Hay un pequeño error, como 'H' debe reemplazarse a% H (formato de 24 horas), no a% I (formato de 12 horas). Así que aquí está la línea mejorada: '' '$ schedule_format = str_replace (array ('M', 'Y', 'm', 'd', 'H', 'i', 'a'), array ('% b ','% Y ','% m ','% d ','% H ','% M ','% p '), $ dformat); '' ' – kenorb

9

Porque strtotime tiene un mal rendimiento cuando se enfrenta con D/M/Y y date_create_from_format no está disponible, strptime puede ser su única esperanza aquí. Hace algunas cosas bastante anticuadas, como tratar con los años como si fueran la cantidad de años desde 1900 y lidiar con meses como si enero fuera el mes cero. Aquí hay un código de ejemplo horrible que utiliza sprintf para volver a montar la fecha en algo DateTime entiende:

$schedule = '31/03/2011 01:22 pm'; 
// %Y, %m and %d correspond to date()'s Y m and d. 
// %I corresponds to H, %M to i and %p to a 
$ugly = strptime($schedule, '%d/%m/%Y %I:%M %p'); 
$ymd = sprintf(
    // This is a format string that takes six total decimal 
    // arguments, then left-pads them with zeros to either 
    // 4 or 2 characters, as needed 
    '%04d-%02d-%02d %02d:%02d:%02d', 
    $ugly['tm_year'] + 1900, // This will be "111", so we need to add 1900. 
    $ugly['tm_mon'] + 1,  // This will be the month minus one, so we add one. 
    $ugly['tm_mday'], 
    $ugly['tm_hour'], 
    $ugly['tm_min'], 
    $ugly['tm_sec'] 
); 
echo $ymd; 
$new_schedule = new DateTime($ymd); 
echo $new_schedule->format('Y-m-d H:i:s'); 

Si funciona, debería ver la misma, la fecha y hora correcta dos veces impresa.

+0

por curiosidad, cuál es la diferencia entre su código y 'else { $ schedule = str_replace ('/', '-', $ schedule); $ schedule = date ('Y-m-d H: i: s', strtotime ($ schedule)); } ' – Hailwood

+0

Esta es probablemente la mejor solución a menos que pueda tener más control sobre la entrada y asegúrese de estar utilizando [Formatos de fecha y hora compatibles] (http://www.php.net/manual/en/datetime.formats. php). – Jacob

+0

'strtotime' no comprende D/M/Y. Solo puede manejar Y/M/D y M/D/Y. Si intentas pasarle una D/M/Y, fallará. 'strtotime ('20/02/2003 ')' devuelve 'false'. Tendría que pasar ''20 .03.2003'' (¡tenga en cuenta los puntos!) Para obtener ese formato reconocido, que no es el formato de fecha que espera. – Charles

6

Creo que es mucho más limpio para extender la clase DateTime e implementar createFromFormat() a sí mismo de esta manera: -

class MyDateTime extends DateTime 
{ 
    public static function createFromFormat($format, $time, $timezone = null) 
    { 
     if(!$timezone) $timezone = new DateTimeZone(date_default_timezone_get()); 
     $version = explode('.', phpversion()); 
     if(((int)$version[0] >= 5 && (int)$version[1] >= 2 && (int)$version[2] > 17)){ 
      return parent::createFromFormat($format, $time, $timezone); 
     } 
     return new DateTime(date($format, strtotime($time)), $timezone); 
    } 
} 

$dateTime = MyDateTime::createFromFormat('Y-m-d', '2013-6-13'); 
var_dump($dateTime); 
var_dump($dateTime->format('Y-m-d')); 

Esto funciona en todas las versiones de PHP > = 5.2.0.

Ver aquí para una demostración http://3v4l.org/djucq

+0

Esto funciona' FANTÁSTICO' gracias !! ! – degenerate

+0

Esto no funciona en 5.2.x con un formato no inglés habitual como 'd/m/Y', pero funciona si reemplaza '/' con '-'. – morgar

+0

Como 5.2.x llegó a [EOL] (http://php.net/eol.php) hace casi 6 años, no me preocupa demasiado. Gracias por avisarme de todos modos. – vascowhite

-1
$your_datetime_object=new DateTime($date); 
$date_format_modified=date_format($your_datetime_object,'D M d Y');//Change the format of date time 

tuve el mismo problema con el servidor de producción en el 5,2, por lo que utiliza la fecha y hora arriba para crear un objeto y luego cambiar el formato de mi agrado que el anterior.

-1

de fecha y hora sólo se

$dateTime = DateTime::createFromFormat('Y-m-d\TH:i:s', '2015-04-20T18:56:42'); 

ISO8601 no hay dos puntos

$dateTime = DateTime::createFromFormat('Y-m-d\TH:i:sO', '2015-04-20T18:56:42+0000'); 

ISO8601 con dos puntos formato

$date = $dateTime->format('c'); 

Salesforce ISO8601

DateTime::createFromFormat('Y-m-d\TH:i:s.uO', '2015-04-20T18:56:42.000+0000'); 

Espero que esto le ahorre tiempo a alguien!

+0

Acabo de leer la pregunta, por favor, perdóneme, tiene la intención de publicar en la pregunta correspondiente, pero estaba emocionado de haber finalmente resuelto el problema y no tengo idea de cómo eliminar esto, mi mal. –

0

Dado que esto realmente no muestra cómo convertir YYYY: DDD: HH: MM: SS time a unix segundos usando la opción "z", debe crear sus propias funciones para convertir el DOY a mes y día del mes. Esto es lo que hice:

function _IsLeapYear ($Year) 
{ 
    $LeapYear = 0; 
    # Leap years are divisible by 4, but not by 100, unless by 400 
    if (($Year % 4 == 0) || ($Year % 100 == 0) || ($Year % 400 == 0)) { 
     $LeapYear = 1; 
    } 
    return $LeapYear; 
} 

function _DaysInMonth ($Year, $Month) 
{ 

    $DaysInMonth = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); 

    return ((_IsLeapYear($Year) && $Month == 2) ? 29 : $DaysInMonth[$Month - 1]); 
} 

function yydddhhssmmToTime($Year, $DOY, $Hour, $Min, $Sec) 
{ 
    $Day = $DOY; 
    for ($Month = 1; $Day > _DaysInMonth($Year, $Month); $Month++) { 
    $Day -= _DaysInMonth($Year, $Month); 
    } 

    $DayOfMonth = $Day; 

    return mktime($Hour, $Min, $Sec, $Month, $DayOfMonth, $Year); 
} 

$timeSec = yydddhhssmmToTime(2016, 365, 23, 23, 23); 
$str = date("m/d/Y H:i:s", $timeSec); 
echo "unix seconds: " . $timeis . " " . $str ."<br>"; 

La salida en la página de muestra de su trabajo ya que puedo convertir de nuevo los segundos a los valores de entrada originales. segundos unix: 1483140203 30/12/2016 23:23:23

Cuestiones relacionadas