Convierte un formato de fecha a otro en PHP

336

¿Hay una manera simple de convertir un formato de fecha en otro formato de fecha en PHP?

Tengo esto:

$old_date = date('y-m-d-h-i-s');            // works

$middle = strtotime($old_date);             // returns bool(false)

$new_date = date('Y-m-d H:i:s', $middle);   // returns 1970-01-01 00:00:00

Pero, por supuesto, me gustaría devolver una fecha actual en lugar de la madrugada. ¿Qué estoy haciendo mal?

Tom
fuente

Respuestas:

293

El segundo parámetro date()debe ser una marca de tiempo adecuada (segundos desde el 1 de enero de 1970). Está pasando una cadena, que date () no puede reconocer.

Puede usar strtotime () para convertir una cadena de fecha en una marca de tiempo. Sin embargo, incluso strtotime () no reconoce el y-m-d-h-i-sformato.

PHP 5.3 y superior

Uso DateTime::createFromFormat. Le permite especificar una máscara exacta, utilizando la date()sintaxis, para analizar las fechas de cadena entrantes con.

PHP 5.2 y versiones inferiores

Deberá analizar los elementos (año, mes, día, hora, minuto, segundo) de forma manual utilizando substr()y entregar los resultados a mktime () que le generará una marca de tiempo.

¡Pero eso es mucho trabajo! Recomiendo usar un formato diferente que strftime () pueda entender. strftime () entiende cualquier entrada de fecha por debajo de the next time joe will slip on the ice. por ejemplo, esto funciona:

$old_date = date('l, F d y h:i:s');              // returns Saturday, January 30 10 02:06:34
$old_date_timestamp = strtotime($old_date);
$new_date = date('Y-m-d H:i:s', $old_date_timestamp);   
Pekka
fuente
Gracias, Pekka, que acaba de editar mi pregunta, lo intentó pero no parece funcionar.
Tom
Edité la respuesta mientras la aceptabas :) Agregué algunos ejemplos y referencias más.
Pekka
Te tengo, ese es el problema. Es un nombre de archivo fijo que necesito volver a convertir en una fecha (tiene que estar en ese formato), así que encontraré una solución alternativa.
Tom
Nota: Según php.net DateTimeexiste desde PHP 5.2 en el núcleo de PHP y DateTimese puede habilitar el soporte experimental para PHP 5.1 en la compilación. secure.php.net/manual/en/datetime.installation.php
Charlotte Dunois
108

La forma más fácil de hacer esto es

$myDateTime = DateTime::createFromFormat('Y-m-d', $dateString);
$newDateString = $myDateTime->format('m/d/Y');

Primero le está dando el formato en el que está $ dateString. Luego le está diciendo el formato en el que desea que esté $ newDateString.

Esto también evita el uso de strtotime, que a veces puede ser difícil de trabajar.

Si no se está transformando de un formato de fecha a otro, pero solo quiere la fecha actual (o fecha y hora) en un formato específico, entonces es aún más fácil:

$now = new DateTime();
$timestring = $now->format('Y-m-d h:i:s');

Esta otra pregunta también se refiere al mismo tema: Convertir formato de fecha aaaa-mm-dd => dd-mm-aaaa .

ceiroa
fuente
¿Y cómo es un duplicado si hice la pregunta antes de la que te refieres?
Tom
1
He editado la respuesta. Solo quería señalar que estas dos preguntas deberían estar vinculadas de alguna manera.
ceiroa
disponible en php 5.3+
Zorox
$timestring = $now->format('Y-m-d h:i:s');¿seguramente? mpor meses, ipor minutos
Mark Baker
@madlopt ~ métodos estáticos: secure.php.net/manual/en/language.oop5.static.php
ceiroa
53

Los basicos

La forma más simple de convertir un formato de fecha a otro es usar strtotime()con date(). strtotime()convertirá la fecha en una marca de tiempo de Unix . Esa marca de tiempo de Unix se puede pasar date()para convertirla al nuevo formato.

$timestamp = strtotime('2008-07-01T22:35:17.02');
$new_date_format = date('Y-m-d H:i:s', $timestamp);

O como una frase:

$new_date_format = date('Y-m-d H:i:s', strtotime('2008-07-01T22:35:17.02'));

Tenga en cuenta que strtotime()requiere que la fecha esté en un formato válido . Si no se proporciona un formato válido, se strtotime()devolverá falso, lo que hará que su fecha sea 1969-12-31.

Utilizando DateTime()

A partir de PHP 5.2, PHP ofreció la DateTime()clase que nos ofrece herramientas más potentes para trabajar con fechas (y horas). Podemos reescribir el código anterior usando DateTime()así:

$date = new DateTime('2008-07-01T22:35:17.02');
$new_date_format = $date->format('Y-m-d H:i:s');

Trabajando con marcas de tiempo Unix

date() toma una marca de tiempo Unix como su segundo parámetro y le devuelve una fecha formateada:

$new_date_format = date('Y-m-d H:i:s', '1234567890');

DateTime () funciona con las marcas de tiempo de Unix agregando un @antes de la marca de tiempo:

$date = new DateTime('@1234567890');
$new_date_format = $date->format('Y-m-d H:i:s');

Si la marca de tiempo que tiene está en milisegundos (puede terminar 000y / o la marca de tiempo tiene trece caracteres), deberá convertirla a segundos antes de poder convertirla a otro formato. Hay dos formas de hacer esto:

  • Recorte los últimos tres dígitos usando substr()

Recortar los últimos tres dígitos se puede lograr de varias maneras, pero usar substr()es el más fácil:

$timestamp = substr('1234567899000', -3);
  • Divide el substr por 1000

También puede convertir la marca de tiempo en segundos dividiéndola entre 1000. Debido a que la marca de tiempo es demasiado grande para que los sistemas de 32 bits hagan cálculos matemáticos, deberá usar la biblioteca BCMath para hacer los cálculos matemáticos como cadenas:

$timestamp = bcdiv('1234567899000', '1000');

Para obtener una marca de tiempo Unix, puede usar la strtotime()que devuelve una marca de tiempo Unix:

$timestamp = strtotime('1973-04-18');

Con DateTime () puedes usar DateTime::getTimestamp()

$date = new DateTime('2008-07-01T22:35:17.02');
$timestamp = $date->getTimestamp();

Si está ejecutando PHP 5.2, puede usar la Uopción de formato en su lugar:

$date = new DateTime('2008-07-01T22:35:17.02');
$timestamp = $date->format('U');

Trabajar con formatos de fecha no estándar y ambiguos

Desafortunadamente, no todas las fechas con las que un desarrollador tiene que trabajar están en un formato estándar. Afortunadamente, PHP 5.3 nos proporcionó una solución para eso. DateTime::createFromFormat()nos permite decirle a PHP en qué formato se encuentra una cadena de fecha para que pueda analizarse con éxito en un objeto DateTime para su posterior manipulación.

$date = DateTime::createFromFormat('F-d-Y h:i A', 'April-18-1973 9:48 AM');
$new_date_format = $date->format('Y-m-d H:i:s');

En PHP 5.4 obtuvimos la capacidad de hacer que los miembros de la clase accedan a instancias que se agregaron, lo que nos permite convertir nuestro DateTime()código en una línea:

$new_date_format = (new DateTime('2008-07-01T22:35:17.02'))->format('Y-m-d H:i:s');

$new_date_format = DateTime::createFromFormat('F-d-Y h:i A', 'April-18-1973 9:48 AM')->format('Y-m-d H:i:s');
John Conde
fuente
27

Prueba esto:

$old_date = date('y-m-d-h-i-s');
$new_date = date('Y-m-d H:i:s', strtotime($old_date));
Sarfraz
fuente
No funcionará, strtotime () no reconoce el formato. Acabo de tratar.
Pekka
de acuerdo, acabo de poner el código de formato del interrogador, debe especificarse el formato adecuado
Sarfraz
Funcionó para mi. Mi $ old_date fue algo así como 2012-05-22T19: 16: 37 + 01: 00. ¡Por cierto, gracias!
VishwaKumar
15

Para convertir $datede dd-mm-yyyy hh:mm:ssa una fecha y hora adecuada de MySQL voy así:

$date = DateTime::createFromFormat('d-m-Y H:i:s',$date)->format('Y-m-d H:i:s');
Jelle de Fries
fuente
44
No debe encadenar estos métodos a menos que esté 110% seguro de que $ date es una fecha válida y se ajusta al formato. Con eso se dice, una fecha no válida que no coincida exactamente el formato volverá: Fatal error: Call to a member function format() on a non-object. Sólo un aviso!
Medio loco el
Es cierto que una mejor solución es hacerlo en 3 pasos con una verificación nula como paso intermedio.
Jelle de Fries
11

El siguiente es un método fácil para convertir fechas a diferentes formatos.

// Create a new DateTime object
$date = DateTime::createFromFormat('Y-m-d', '2016-03-25');

// Output the date in different formats
echo $date->format('Y-m-d')."\n";
echo $date->format('d-m-Y')."\n";
echo $date->format('m-d-Y')."\n";
Peter
fuente
10
$old_date = date('y-m-d-h-i-s');       // works

estás haciendo mal aquí, esto debería ser

$old_date = date('y-m-d h:i:s');       // works

separador de tiempo es ':'


Creo que esto ayudará...

$old_date = date('y-m-d-h-i-s');              // works

preg_match_all('/(\d+)-(\d+)-(\d+)-(\d+)-(\d+)-(\d+)/', $old_date, $out, PREG_SET_ORDER);
$out = $out[0];
$time = mktime($out[4], $out[5], $out[6], $out[2], $out[3], $out[1]);

$new_date = date('Y-m-d H:i:s', $time); 

O


$old_date = date('y-m-d-h-i-s');              // works

$out = explode('-', $old_date);
$time = mktime($out[3], $out[4], $out[5], $out[1], $out[2], $out[0]);

$new_date = date('Y-m-d H:i:s', $time); 
Rifat
fuente
Sí, claro, gracias, es un nombre de archivo GUID que quiero convertir de nuevo a un formato de fecha adecuado.
Tom
8

Esta forma nativa ayudará a convertir cualquier formato ingresado al formato deseado.

$formatInput = 'd-m-Y'; //Give any format here, this would be converted into your format
$dateInput = '01-02-2018'; //date in above format

$formatOut = 'Y-m-d'; // Your format
$dateOut = DateTime::createFromFormat($formatInput, $dateInput)->format($formatOut);
Nishad Up
fuente
7

Debe convertir $ old_date nuevamente en una marca de tiempo, ya que la función de fecha requiere una marca de tiempo como segundo argumento.

John Parker
fuente
7

strtotime lo resolverá. las fechas no son las mismas y todas están en formato estadounidense.

<?php
$e1 = strtotime("2013-07-22T12:00:03Z");
echo date('y.m.d H:i', $e1);
echo "2013-07-22T12:00:03Z";

$e2 = strtotime("2013-07-23T18:18:15Z");
echo date ('y.m.d H:i', $e2);
echo "2013-07-23T18:18:15Z";

$e1 = strtotime("2013-07-21T23:57:04Z");
echo date ('y.m.d H:i', $e2);
echo "2013-07-21T23:57:04Z";
?>
de_nuit
fuente
5

Prueba esto:

$tempDate = explode('-','03-23-15');
$date = '20'.$tempDate[2].'-'.$tempDate[0].'-'.$tempDate[1];
viña
fuente
5

Esto me resolvió

$old = '18-04-2018';
$new = date('Y-m-d', strtotime($old));
echo $new;

Salida: 2018-04-18

Ashokkumar C
fuente
2

Esta es la otra forma en que puede convertir el formato de fecha

 <?php
$pastDate = "Tuesday 11th October, 2016";
$pastDate = str_replace(",","",$pastDate);

$date = new DateTime($pastDate);
$new_date_format = $date->format('Y-m-d');

echo $new_date_format.' 23:59:59'; ?>
Varun Malhotra
fuente
1

Solo usando cadenas, para mí es una buena solución, menos problemas con mysql. Detecta el formato actual y lo cambia si es necesario, esta solución es solo para formato español / francés e inglés, sin usar la función de fecha y hora de php.

class dateTranslator {

 public static function translate($date, $lang) {
      $divider = '';

      if (empty($date)){
           return null;   
      }
      if (strpos($date, '-') !== false) {
           $divider = '-';
      } else if (strpos($date, '/') !== false) {
           $divider = '/';
      }
      //spanish format DD/MM/YYYY hh:mm
      if (strcmp($lang, 'es') == 0) {

           $type = explode($divider, $date)[0];
           if (strlen($type) == 4) {
                $date = self::reverseDate($date,$divider);
           } 
           if (strcmp($divider, '-') == 0) {
                $date = str_replace("-", "/", $date);
           }
      //english format YYYY-MM-DD hh:mm
      } else {

           $type = explode($divider, $date)[0];
           if (strlen($type) == 2) {

                $date = self::reverseDate($date,$divider);
           } 
           if (strcmp($divider, '/') == 0) {
                $date = str_replace("/", "-", $date);

           }   
      }
      return $date;
 }

 public static function reverseDate($date) {
      $date2 = explode(' ', $date);
      if (count($date2) == 2) {
           $date = implode("-", array_reverse(preg_split("/\D/", $date2[0]))) . ' ' . $date2[1];
      } else {
           $date = implode("-", array_reverse(preg_split("/\D/", $date)));
      }

      return $date;
 }

UTILIZAR

dateTranslator::translate($date, 'en')
Alejandro Aranda
fuente
1

Sé que esto es antiguo, pero, al encontrarme con un proveedor que utiliza inconsistentemente 5 formatos de fecha diferentes en sus API (y servidores de prueba con una variedad de versiones de PHP desde los 5 hasta los últimos 7), decidí escribir un convertidor universal que funciona con una miríada de versiones de PHP.

Este convertidor tomará prácticamente cualquier entrada, incluido cualquier formato estándar de fecha y hora (incluso con o sin milisegundos) y cualquier representación de Epoch Time (incluso con o sin milisegundos) y lo convertirá a prácticamente cualquier otro formato.

Para llamarlo:

$TheDateTimeIWant=convertAnyDateTome_toMyDateTime([thedateIhave],[theformatIwant]);

Enviar nulo para el formato hará que la función devuelva la fecha y hora en Epoch / Unix Time. De lo contrario, envíe cualquier cadena de formato que date () admita, así como con ".u" durante milisegundos (también manejo milisegundos, aunque date () devuelve ceros).

Aquí está el código:

        <?php   
        function convertAnyDateTime_toMyDateTime($dttm,$dtFormat)
        {
            if (!isset($dttm))
            {
                return "";
            }
            $timepieces = array();
            if (is_numeric($dttm))
            {
                $rettime=$dttm;
            }
            else
            {
                $rettime=strtotime($dttm);
                if (strpos($dttm,".")>0 and strpos($dttm,"-",strpos($dttm,"."))>0)
                {
                    $rettime=$rettime.substr($dttm,strpos($dttm,"."),strpos($dttm,"-",strpos($dttm,"."))-strpos($dttm,"."));
                    $timepieces[1]="";
                }
                else if (strpos($dttm,".")>0 and strpos($dttm,"-",strpos($dttm,"."))==0)
                {               
                    preg_match('/([0-9]+)([^0-9]+)/',substr($dttm,strpos($dttm,"."))." ",$timepieces);
                    $rettime=$rettime.".".$timepieces[1];
                }
            }

            if (isset($dtFormat))
            {
                // RETURN as ANY date format sent
                if (strpos($dtFormat,".u")>0)       // Deal with milliseconds
                {
                    $rettime=date($dtFormat,$rettime);              
                    $rettime=substr($rettime,0,strripos($rettime,".")+1).$timepieces[1];                
                }
                else                                // NO milliseconds wanted
                {
                    $rettime=date($dtFormat,$rettime);
                }
            }
            else
            {
                // RETURN Epoch Time (do nothing, we already built Epoch Time)          
            }
            return $rettime;    
        }
    ?>

Aquí hay algunas llamadas de muestra: notará que también maneja los datos de la zona horaria (aunque, como se señaló anteriormente, cualquier hora no GMT se devuelve en su zona horaria).

        $utctime1="2018-10-30T06:10:11.2185007-07:00";
        $utctime2="2018-10-30T06:10:11.2185007";
        $utctime3="2018-10-30T06:10:11.2185007 PDT";
        $utctime4="2018-10-30T13:10:11.2185007Z";
        $utctime5="2018-10-30T13:10:11Z";
        $dttm="10/30/2018 09:10:11 AM EST";

        echo "<pre>";
        echo "<b>Epoch Time to a standard format</b><br>";
        echo "<br>Epoch Tm: 1540905011    to STD DateTime     ----RESULT: ".convertAnyDateTime_toMyDateTime("1540905011","Y-m-d H:i:s")."<hr>";
        echo "<br>Epoch Tm: 1540905011          to UTC        ----RESULT: ".convertAnyDateTime_toMyDateTime("1540905011","c");
        echo "<br>Epoch Tm: 1540905011.2185007  to UTC        ----RESULT: ".convertAnyDateTime_toMyDateTime("1540905011.2185007","c")."<hr>";
        echo "<b>Returned as Epoch Time (the number of seconds that have elapsed since 00:00:00 Thursday, 1 January 1970, Coordinated Universal Time (UTC), minus leap seconds.)";
        echo "</b><br>";
        echo "<br>UTCTime1: ".$utctime1." ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime1,null);
        echo "<br>UTCTime2: ".$utctime2."       ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime2,null);
        echo "<br>UTCTime3: ".$utctime3."   ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime3,null);
        echo "<br>UTCTime4: ".$utctime4."      ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime4,null);
        echo "<br>UTCTime5: ".$utctime5."              ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime5,null);
        echo "<br>NO MILIS: ".$dttm."        ----RESULT: ".convertAnyDateTime_toMyDateTime($dttm,null);
        echo "<hr>";
        echo "<hr>";
        echo "<b>Returned as whatever datetime format one desires</b>";
        echo "<br>UTCTime1: ".$utctime1." ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime1,"Y-m-d H:i:s")."              Y-m-d H:i:s";
        echo "<br>UTCTime2: ".$utctime2."       ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime2,"Y-m-d H:i:s.u")."      Y-m-d H:i:s.u";
        echo "<br>UTCTime3: ".$utctime3."   ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime3,"Y-m-d H:i:s.u")."      Y-m-d H:i:s.u";
        echo "<p><b>Returned as ISO8601</b>";
        echo "<br>UTCTime3: ".$utctime3."   ----RESULT: ".convertAnyDateTime_toMyDateTime($utctime3,"c")."        ISO8601";
        echo "</pre>";

Aquí está la salida:

Epoch Tm: 1540905011                        ----RESULT: 2018-10-30 09:10:11

Epoch Tm: 1540905011          to UTC        ----RESULT: 2018-10-30T09:10:11-04:00
Epoch Tm: 1540905011.2185007  to UTC        ----RESULT: 2018-10-30T09:10:11-04:00
Returned as Epoch Time (the number of seconds that have elapsed since 00:00:00 Thursday, 1 January 1970, Coordinated Universal Time (UTC), minus leap seconds.)

UTCTime1: 2018-10-30T06:10:11.2185007-07:00 ----RESULT: 1540905011.2185007
UTCTime2: 2018-10-30T06:10:11.2185007       ----RESULT: 1540894211.2185007
UTCTime3: 2018-10-30T06:10:11.2185007 PDT   ----RESULT: 1540905011.2185007
UTCTime4: 2018-10-30T13:10:11.2185007Z      ----RESULT: 1540905011.2185007
UTCTime5: 2018-10-30T13:10:11Z              ----RESULT: 1540905011
NO MILIS: 10/30/2018 09:10:11 AM EST        ----RESULT: 1540908611
Returned as whatever datetime format one desires
UTCTime1: 2018-10-30T06:10:11.2185007-07:00 ----RESULT: 2018-10-30 09:10:11              Y-m-d H:i:s
UTCTime2: 2018-10-30T06:10:11.2185007       ----RESULT: 2018-10-30 06:10:11.2185007      Y-m-d H:i:s.u
UTCTime3: 2018-10-30T06:10:11.2185007 PDT   ----RESULT: 2018-10-30 09:10:11.2185007      Y-m-d H:i:s.u
Returned as ISO8601
UTCTime3: 2018-10-30T06:10:11.2185007 PDT   ----RESULT: 2018-10-30T09:10:11-04:00        ISO8601

Lo único que no está en esta versión es la capacidad de seleccionar la zona horaria en la que desea que esté la fecha y hora devuelta. Originalmente, escribí esto para cambiar cualquier fecha y hora a Epoch Time, por lo que no necesitaba soporte de zona horaria. Sin embargo, es trivial agregar.

Robert Mauro
fuente