Convertir cadena a fecha y fecha y hora

292

Si tengo una cadena PHP en el formato de mm-dd-YYYY(por ejemplo, 10-16-2003), ¿cómo puedo convertirla correctamente a ay Dateluego DateTimeen el formato de YYYY-mm-dd? La única razón por la que pido ambos Datey DateTimees porque necesito uno en un lugar y el otro en un lugar diferente.

Chris Pinski
fuente

Respuestas:

480

Use strtotime()en su primera fecha y luego date('Y-m-d')vuelva a convertirla:

$time = strtotime('10/16/2003');

$newformat = date('Y-m-d',$time);

echo $newformat;
// 2003-10-16

Tenga en cuenta que existe una diferencia entre usar la barra diagonal /y el guión -en la strtotime()función. Para citar de php.net:

Las fechas en los formatos m / d / y o dmy se desambiguan mirando el separador entre los diversos componentes: si el separador es una barra oblicua (/), entonces se supone el m / d / y estadounidense; mientras que si el separador es un guión (-) o un punto (.), entonces se supone el formato dmy europeo.

Para evitar posibles ambigüedades, es mejor usar fechas ISO 8601 (AAAA-MM-DD) o DateTime :: createFromFormat () cuando sea posible.

Ibu
fuente
11
Esto no funcionara. PHP interpretará esa entrada como DD-MM-AAAA.
Mateo
Agregué un poco más de explicación a mi código, gracias @konforce
Ibu
99
Lea la siguiente respuesta para una mejor solución
Manuel Bitto
@delive su cadena de fecha probablemente no sea una fecha correcta.
Ibu
8
No funciona porque esta respuesta es engañosa. strtotimeacepta ciertos formatos. No se puede alimentar lo que sea. Es por eso que DateTime::createFromFormatdebe usarse en lugar de strtotime. Lamentablemente, esta respuesta tiene demasiados votos a favor para que nadie preste atención. Todo es copiar y pegar en estos días.
NB
432

Debe tener cuidado con los formatos m / d / Y y mdY. PHP considera /que significa m / d / Y y -que significa dmY. Describiría explícitamente el formato de entrada en este caso:

$ymd = DateTime::createFromFormat('m-d-Y', '10-16-2003')->format('Y-m-d');

De esa manera no estás a los caprichos de una determinada interpretación.

Mateo
fuente
37
Curioso por qué esta no es la respuesta aceptada ... Esto es mucho más flexible que confiar en las peculiaridades de la strtotime()función.
jzimmerman2011
99
Es importante señalar que la clase DateTime de php está disponible desde PHP versión 5.2 y createFromFormat desde 5.3
Diego Nemo
14
Como con todas las funciones, debe verificar si cumple con la versión mínima que debe admitir. Pero PHP 5.2 EOL era enero de 2011. Ya nadie debería ejecutarlo; atender a esas personas solo les permite ejecutar software obsoleto e inseguro.
Mateo
@Matthew sí, correcto. Pero nunca ahora, incluso hoy encontré una versión PHP4.1 todavía instalada ...
Roland
29

Para analizar la fecha, debe usar: DateTime :: createFromFormat ();

Ex:

$dateDE = "16/10/2013";
$dateUS = \DateTime::createFromFormat("d.m.Y", $dateDE)->format("m/d/Y");

Sin embargo, cuidado, porque esto se bloqueará con:

PHP Fatal error: Call to a member function format() on a non-object 

En realidad, primero debe comprobar que el formato funcionó bien:

$dateDE = "16/10/2013";
$dateObj = \DateTime::createFromFormat("d.m.Y", $dateDE);
if (!$dateObj)
{
    throw new \UnexpectedValueException("Could not parse the date: $date");
}
$dateUS = $dateObj->format("m/d/Y");

Ahora, en lugar de estrellarse, obtendrá una excepción, que puede atrapar, propagar, etc.

$ dateDE tiene el formato incorrecto, debería ser "16.10.2013";

usuario2707671
fuente
Tenga en cuenta que marcar $ dateObj de esa manera solo aseguraría que el formato coincida con la máscara, no que la fecha sea realmente válida. Por ejemplo, una fecha como 99/99/2010 pasaría esta verificación, ya que coincide con m / d / Y, pero no es una fecha que generalmente desea permitir. Esta respuesta aborda esta situación -> stackoverflow.com/a/10120725/995014
Kilian Perdomo Curbelo
22
$d = new DateTime('10-16-2003');

$timestamp = $d->getTimestamp(); // Unix timestamp
$formatted_date = $d->format('Y-m-d'); // 2003-10-16

Editar: también puede pasar un constructor DateTimeZone a DateTime () para garantizar la creación de la fecha para la zona horaria deseada, no la predeterminada del servidor.

nótese bien
fuente
66
Creo que esto arrojará una excepción porque el mes 16 no es válido.
Mateo
Es importante señalar que la clase php DateTime está disponible desde PHP versión 5.2 y getTimestamp desde 5.3
Diego Nemo
2

Para la primera cita

$_firstDate = date("m-d-Y", strtotime($_yourDateString));

Para nueva fecha

$_newDate = date("Y-m-d",strtotime($_yourDateString));
Vi8L
fuente
2

Si tiene el formato dd-mm-aaaa, entonces en PHP no funcionará como se esperaba. En el documento PHP tienen la siguiente guía.

Las fechas en los formatos m / d / y o dmy se desambiguan mirando el separador entre los diversos componentes: si el separador es una barra oblicua (/), entonces se supone el m / d / y estadounidense; mientras que si el separador es un guión (-) o un punto (.), entonces se supone el formato dmy europeo.

Por lo tanto, simplemente no puede usar lo que desee. Cuando intente utilizar el formato dd / mm / aaaa con esto, eliminará FALSO. Puede ajustar con lo siguiente.

$date = "23/02/2013";
$timestamp = strtotime($date);
if ($timestamp === FALSE) {
  $timestamp = strtotime(str_replace('/', '-', $date));
}
echo $timestamp; // prints 1361577600
MAULIK MODI
fuente
1

Al igual que tenemos la fecha "07 / May / 2018" y necesitamos la fecha "2018-05-07" como compatible con mysql

if (!empty($date)) {
    $timestamp = strtotime($date);
    if ($timestamp === FALSE) {
         $timestamp = strtotime(str_replace('/', '-', $date));
     }
         $date = date('Y-m-d', $timestamp);
  }

Esto funciona para mi. disfruta :)

Newton Singh
fuente
0

Como nadie mencionó esto, aquí hay otra forma:

$date = date_create_from_format("m-d-Y", "10-16-2003")->format("Y-m-d");

Sodj
fuente
0

Si desea aceptar fechas usando pedidos estadounidenses (mes, fecha, año) para formatos de estilo europeo (usando guión o período como día, mes, año) mientras aún acepta otros formatos , puede extender la clase DateTime:

/**
 * Quietly convert European format to American format
 *
 * Accepts m-d-Y, m-d-y, m.d.Y, m.d.y, Y-m-d, Y.m.d
 * as well as all other built-in formats
 * 
 */
class CustomDateTime extends DateTime 
{
  public function __construct(string $time="now", DateTimeZone $timezone = null) 
  {
    // convert m-d-y or m.d.y to m/d/y to avoid PHP parsing as d-m-Y (substr avoids microtime error)
    $time = str_replace(['-','.'], '/', substr($time, 0, 10)) . substr($time, 10 );

    parent::__construct($time, $timezone);
  }
}

// usage:
$date = new CustomDateTime('7-24-2019');
print $date->format('Y-m-d');

// => '2019-07-24'

O bien, puede realizar una función para aceptar mdY y generar Ymd:

/**
 * Accept dates in various m, d, y formats and return as Y-m-d
 * 
 * Changes PHP's default behaviour for dates with dashes or dots.
 * Accepts:
 *   m-d-y, m-d-Y, Y-m-d,
 *   m.d.y, m.d.Y, Y.m.d,
 *   m/d/y, m/d/Y, Y/m/d,
 *   ... and all other formats natively supported 
 * 
 * Unsupported formats or invalid dates will generate an Exception
 * 
 * @see https://www.php.net/manual/en/datetime.formats.date.php PHP formats supported
 * @param  string $d various representations of date
 * @return string    Y-m-d or '----' for null or blank
 */
function asYmd($d) {
  if(is_null($d) || $d=='') { return '----'; }

  // convert m-d-y or m.d.y to m/d/y to avoid PHP parsing as d-m-Y
  $d = str_replace(['-','.'], '/', $d);

  return (new DateTime($d))->format('Y-m-d');
}

// usage:

<?= asYmd('7-24-2019') ?>

// or

<?php echo asYmd('7-24-2019'); ?>
Tim Morton
fuente
0

para crear la fecha desde cualquier cadena use:
$ date = DateTime :: createFromFormat ('dmy H: i', '01 -01-01 01:00 '); echo $ fecha-> formato ('Ymd H: i');

Azouz Mohamadi
fuente