Konwertowanie ciągu na datę i datę i godzinę

292

Jeśli mam ciąg PHP w formacie mm-dd-YYYY(na przykład 10-16-2003), jak poprawnie przekonwertować go na format a, Datea następnie DateTimena format a YYYY-mm-dd? Jedynym powodem, dla którego proszę o jedno Datei drugie, DateTimejest to, że potrzebuję jednego w jednym miejscu, a drugiego w innym miejscu.

Chris Pinski
źródło

Odpowiedzi:

480

Użyj strtotime()pierwszej randki, a następnie date('Y-m-d')przekonwertuj ją z powrotem:

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

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

echo $newformat;
// 2003-10-16

Zwróć uwagę, że istnieje różnica między używaniem ukośnika /i łącznika -w strtotime()funkcji. Cytat z php.net:

Daty w formatach m / d / r lub dmy są jednoznaczne, patrząc na separator między różnymi składnikami: jeśli separator jest ukośnikiem (/), to zakłada się amerykański m / d / r; podczas gdy jeśli separatorem jest myślnik (-) lub kropka (.), wówczas przyjmuje się europejski format dmy.

Aby uniknąć potencjalnej niejednoznaczności, najlepiej stosować daty ISO 8601 (RRRR-MM-DD) lub DateTime :: createFromFormat (), jeśli to możliwe.

Ibu
źródło
11
To nie zadziała. PHP zinterpretuje to wejście jako DD-MM-RRRR.
Matthew
dodałem trochę więcej wyjaśnień do mojego kodu, dzięki @konforce
Ibu
9
Przeczytaj następną odpowiedź na lepsze rozwiązanie
Manuel Bitto
@delive data string najprawdopodobniej nie jest poprawną datą.
Ibu,
8
To nie działa, ponieważ ta odpowiedź jest myląca. strtotimeakceptuje niektóre formaty. Nie możesz tego nic karmić. Dlatego DateTime::createFromFormatnależy go używać zamiast strtotime. Niestety, ta odpowiedź ma zbyt wiele pozytywnych opinii, aby ktokolwiek mógł na nią zwrócić uwagę. Teraz wszystko kopiuje się.
NB
432

Należy zachować ostrożność w przypadku formatów m / d / Y i mdY. PHP uważa, /że oznacza m / d / Y i -dmY. W tym przypadku wyraźnie opisałbym format wejściowy:

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

W ten sposób nie jesteś kaprysem określonej interpretacji.

Mateusz
źródło
37
Ciekawe, dlaczego nie jest to akceptowana odpowiedź ... Jest to o wiele bardziej elastyczne niż poleganie na dziwactwach strtotime()funkcji.
jzimmerman2011
9
Ważne jest, aby zaznaczyć, że klasa PHP DateTime jest dostępna od wersji PHP 5.2 i createFromFormat od wersji 5.3
Diego Nemo
14
Jak w przypadku każdej funkcji, powinieneś sprawdzić, czy spełnia ona minimalną wersję, którą musisz obsługiwać. Ale PHP 5.2 EOL to styczeń 2011. Nikt nie powinien już go uruchamiać; catering dla tych ludzi pozwala im jedynie uruchamiać przestarzałe, niepewne oprogramowanie.
Matthew
@Mathew tak, poprawne. Ale nigdy teraz, nawet dzisiaj nie znalazłem wciąż zainstalowanej wersji PHP4.1 ...
Roland
29

Aby przeanalizować datę, należy użyć: DateTime :: createFromFormat ();

Dawny:

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

Jednak ostrożnie, ponieważ spowoduje to awarię:

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

Musisz sprawdzić, czy formatowanie poszło dobrze, najpierw:

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

Teraz zamiast upaść, otrzymasz wyjątek, który możesz złapać, propagować itp.

$ dateDE ma niewłaściwy format, powinien być „16.10.2013”;

użytkownik2707671
źródło
Zauważ, że sprawdzenie $ dateObj w ten sposób upewni się tylko, że format pasuje do maski, a nie, że data jest faktycznie ważna. Na przykład data taka jak 99/99/2010 przejdzie tę kontrolę, ponieważ pasuje do m / d / Y, ale nie jest to data, na którą zwykle chcesz zezwolić. Ta odpowiedź rozwiązuje tę sytuację -> 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

Edycja: możesz także przekazać konstruktorowi DateTimeZone do DateTime (), aby zapewnić utworzenie daty dla żądanej strefy czasowej, a nie domyślnej strefy serwera.

NB
źródło
6
Wierzę, że spowoduje to wyjątek, ponieważ 16 miesiąc jest nieprawidłowy.
Matthew
Ważne jest, aby zaznaczyć, że klasa PHP DateTime jest dostępna od wersji PHP 5.2, a getTimestamp od wersji 5.3
Diego Nemo
2

Na pierwszą randkę

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

Na nową datę

$_newDate = date("Y-m-d",strtotime($_yourDateString));
Vi8L
źródło
2

Jeśli masz format dd-mm-rrrr, to w PHP nie będzie działać zgodnie z oczekiwaniami. W dokumencie PHP mają poniższe wytyczne.

Daty w formatach m / d / r lub dmy są jednoznaczne, patrząc na separator między różnymi składnikami: jeśli separator jest ukośnikiem (/), to zakłada się amerykański m / d / r; podczas gdy jeśli separatorem jest myślnik (-) lub kropka (.), wówczas przyjmuje się europejski format dmy.

Więc po prostu nie możesz używać, jak chcesz. Kiedy spróbujesz użyć formatu dd / mm / rrrr, usuniesz FAŁSZ. Możesz dostosować za pomocą następujących elementów.

$date = "23/02/2013";
$timestamp = strtotime($date);
if ($timestamp === FALSE) {
  $timestamp = strtotime(str_replace('/', '-', $date));
}
echo $timestamp; // prints 1361577600
MAULIK MODI
źródło
1

Jakbyśmy mieli datę „07 / maj / 2018” i potrzebujemy daty „2018-05-07” jako zgodnej z mysql

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

Mi to pasuje. cieszyć się :)

Newton Singh
źródło
0

Ponieważ nikt o tym nie wspominał, oto inny sposób:

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

Sodj
źródło
0

Jeśli chcesz akceptować daty przy użyciu amerykańskiego porządku (miesiąc, data, rok) dla formatów w stylu europejskim (używając myślnika lub kropki jako dnia, miesiąca, roku), jednocześnie akceptując inne formaty , możesz przedłużyć klasę 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'

Lub możesz utworzyć funkcję, która będzie akceptować mdY i wyświetlać 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
źródło
0

aby utworzyć datę z dowolnego łańcucha, użyj:
$ date = DateTime :: createFromFormat ('dmy H: i', '01 -01-01 01:00 '); echo $ date-> format („Ymd H: i”);

Azouz Mohamadi
źródło