Conversione di stringhe in Date e DateTime


292

Se ho una stringa PHP nel formato mm-dd-YYYY(ad esempio, 10-16-2003), come posso convertirla correttamente in a Datee poi a DateTimenel formato di YYYY-mm-dd? L'unico motivo per cui chiedo entrambi Dateed DateTimeè perché ho bisogno di uno in un punto e l'altro in un punto diverso.

Risposte:


480

Usa strtotime()al tuo primo appuntamento quindi date('Y-m-d')per riconvertirlo:

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

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

echo $newformat;
// 2003-10-16

Notare che esiste una differenza tra l'utilizzo della barra /e del trattino -nella strtotime()funzione. Per citare da php.net:

Le date nei formati m / d / y o dmy sono chiarite osservando il separatore tra i vari componenti: se il separatore è una barra (/), si assume l'americano m / d / y; mentre se il separatore è un trattino (-) o un punto (.), si assume il formato dmy europeo.

Per evitare potenziali ambiguità, è meglio utilizzare le date ISO 8601 (AAAA-MM-GG) o DateTime :: createFromFormat () quando possibile.


11
Questo non funzionerà. PHP interpreterà tale input come GG-MM-AAAA.
Matthew,

ho aggiunto una spiegazione in più al mio codice, grazie @konforce
Ibu,

9
Leggi la prossima risposta per una soluzione migliore
Manuel Bitto,

@delive molto probabilmente la tua stringa di date non è una data corretta.
Ibu,

8
Non funziona perché questa risposta è fuorviante. strtotimeaccetta determinati formati. Non puoi dargli da mangiare. Ecco perché DateTime::createFromFormatdovrebbe essere usato al posto di strtotime. Purtroppo, questa risposta ha troppi voti perché chiunque possa prestare attenzione. Al giorno d'oggi è tutto copia incolla.
NB

432

Devi stare attento con i formati m / d / Y e mdY. PHP considera /media m / d / Y e -media dmY. Descriverei esplicitamente il formato di input in questo caso:

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

In questo modo non sei per i capricci di una certa interpretazione.


37
Curioso del perché questa non è la risposta accettata ... Questo è molto più flessibile che fare affidamento sulle stranezze della strtotime()funzione.
jzimmerman2011,

9
È importante sottolineare che la classe php DateTime è disponibile dalla versione 5.2 di PHP e createFromFormat dal 5.3
Diego Nemo,

14
Come per ogni funzione, è necessario verificare se soddisfa la versione minima che è necessario supportare. Ma PHP 5.2 EOL era il gennaio 2011. Nessuno dovrebbe più eseguirlo; approvvigionare a quelle persone sta solo permettendo loro di eseguire software obsoleti e insicuri.
Matteo,

@Matthew sì, corretto. Ma mai ora, anche oggi ho trovato una versione di PHP4.1 ancora installata ...
Roland,

29

Per analizzare la data, è necessario utilizzare: DateTime :: createFromFormat ();

Ex:

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

Tuttavia, attenzione, perché questo si bloccherà con:

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

In realtà è necessario verificare che la formattazione sia andata bene, prima di tutto:

$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");

Ora invece di andare in crash, otterrai un'eccezione, che puoi catturare, propagare, ecc.

$ dateDE ha il formato sbagliato, dovrebbe essere "16.10.2013";


Notare che il controllo di $ dateObj in questo modo assicurerebbe solo che il formato corrisponda alla maschera, non che la data sia effettivamente valida. Ad esempio, una data come 99/99/2010 supererebbe questo controllo poiché corrisponde a m / d / Y ma non è una data che di solito si desidera consentire. Questa risposta risolve questa situazione -> 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

Modifica: puoi anche passare un costruttore DateTimeZone a DateTime () per garantire la creazione della data per il fuso orario desiderato, non quello predefinito del server.


6
Credo che ciò genererà un'eccezione perché il mese 16 non è valido.
Matthew,

È importante sottolineare che la classe DateTime di php è disponibile dalla versione 5.2 di PHP e getTimestamp dalla 5.3
Diego Nemo,

2

Per la prima data

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

Per la nuova data

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

2

Se hai il formato gg-mm-aaaa, in PHP non funzionerà come previsto. Nel documento PHP hanno le linee guida seguenti.

Le date nei formati m / d / y o dmy sono chiarite osservando il separatore tra i vari componenti: se il separatore è una barra (/), si assume l'americano m / d / y; mentre se il separatore è un trattino (-) o un punto (.), si assume il formato dmy europeo.

Quindi, non puoi semplicemente usare come desideri. Quando si tenta di utilizzare il formato gg / mm / aaaa con questo, verrà rimosso FALSO. Puoi modificare quanto segue.

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

1

Come se avessimo la data "07 / Maggio / 2018" e avessimo bisogno della data "2018-05-07" come compatibile con mysql

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

Per me funziona. godere :)


0

Poiché nessuno lo ha menzionato, ecco un altro modo:

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


0

Se si desidera accettare date utilizzando l'ordinamento americano (mese, data, anno) per i formati di stile europeo (utilizzando trattino o periodo come giorno, mese, anno) pur accettando altri formati , è possibile estendere la classe 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'

In alternativa, è possibile creare una funzione per accettare mdY e generare 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'); ?>

0

per creare la data da qualsiasi stringa usare:
$ date = DateTime :: createFromFormat ('dmy H: i', '01 -01-01 01:00 '); echo $ date-> format ('Ymd H: i');

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.