Преобразование строки в Date и DateTime

292

Если у меня есть строка PHP в формате mm-dd-YYYY(например, 10-16-2003), как мне правильно преобразовать ее в a, Dateа затем DateTimeв формат YYYY-mm-dd? Единственная причина , почему я прошу так Dateи DateTimeпотому , что я нужен в одном месте, а другой в другом месте.

Крис Пински
источник

Ответы:

480

Используйте strtotime()на первом свидании, date('Y-m-d')чтобы затем преобразовать его обратно:

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

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

echo $newformat;
// 2003-10-16

Запомните , что существует разница между использованием прямого слэша /и дефиса -в strtotime()функции. Цитировать с php.net:

Даты в форматах m / d / y или dmy устраняются, если посмотреть на разделитель между различными компонентами: если разделитель является косой чертой (/), то предполагается, что используется американский m / d / y; тогда как если разделителем является тире (-) или точка (.), то предполагается европейский формат dmy.

Чтобы избежать двусмысленности, лучше использовать даты ISO 8601 (ГГГГ-ММ-ДД) или DateTime :: createFromFormat (), когда это возможно.

Иб
источник
11
Это не сработает. PHP будет интерпретировать этот ввод как DD-MM-YYYY.
Мэтью
я добавил немного больше объяснений , чтобы мой код, благодаря @konforce
Ибу
9
Прочитайте следующий ответ для лучшего решения
Мануэль Битто
@ доставить вашу строку даты, скорее всего, не является правильной датой.
Ибу
8
Это не работает, потому что этот ответ вводит в заблуждение. strtotimeпринимает определенные форматы. Вы не можете кормить это что угодно. Вот почему DateTime::createFromFormatследует использовать вместо strtotime. К сожалению, у этого ответа слишком много отрицательных отзывов, чтобы кто-то обратил на него внимание. Это все копировать вставить в эти дни.
NB
432

Вы должны быть осторожны с форматами m / d / Y и mdY. PHP считает /означающим m / d / Y и -dmY. Я бы явно описал формат ввода в этом случае:

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

Таким образом, вы не в прихоти определенной интерпретации.

Мэтью
источник
37
Любопытно, почему это не принятый ответ ... Это гораздо более гибко, чем полагаться на причуды strtotime()функции.
jzimmerman2011
9
Важно отметить, что класс php DateTime доступен начиная с версии PHP 5.2 и createFromFormat начиная с версии 5.3
Diego Nemo
14
Как и для каждой функции, вы должны проверить, соответствует ли она минимальной версии, которую вы должны поддерживать. Но PHP 5.2 EOL был в январе 2011 года. Больше никто не должен его запускать; обслуживание этих людей просто позволяет им запускать устаревшее, небезопасное программное обеспечение.
Матфея
@ Матфея да, правильно. Но вы никогда, даже сегодня, я не нашел версию PHP4.1, все еще установленную ...
Роланд
29

Чтобы проанализировать дату, вы должны использовать: DateTime :: createFromFormat ();

Пример:

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

Однако, будьте осторожны, потому что это приведет к сбою:

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

Сначала вам нужно проверить, что форматирование прошло нормально:

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

Теперь вместо сбоя вы получите исключение, которое вы можете перехватить, распространить и т. Д.

$ dateDE имеет неправильный формат, он должен быть "16.10.2013";

user2707671
источник
Обратите внимание на то, что проверка $ dateObj таким образом только гарантирует, что формат соответствует маске, а не что дата действительно действительна. Например, такая дата, как 99/99/2010, прошла бы эту проверку, поскольку она совпадает с m / d / Y, но это не та дата, которую вы обычно хотите разрешить. Этот ответ решает эту ситуацию -> stackoverflow.com/a/10120725/995014
Килиан Пердомо Курбело
22
$d = new DateTime('10-16-2003');

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

Редактировать: вы также можете передать DateTimeZone в конструктор DateTime (), чтобы обеспечить создание даты для желаемого часового пояса, а не по умолчанию для сервера.

NB
источник
6
Я считаю, что это вызовет исключение, потому что 16-й месяц недействителен.
Матфея
Важно отметить, что класс php DateTime доступен начиная с версии PHP 5.2 и getTimestamp начиная с версии 5.3
Diego Nemo
2

Для первого свидания

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

На новую дату

$_newDate = date("Y-m-d",strtotime($_yourDateString));
Vi8L
источник
2

Если у вас есть формат dd-mm-yyyy, то в PHP он не будет работать должным образом. В документе PHP они имеют нижеследующее руководство.

Даты в форматах m / d / y или dmy устраняются, если посмотреть на разделитель между различными компонентами: если разделитель является косой чертой (/), то предполагается, что используется американский m / d / y; тогда как если разделителем является тире (-) или точка (.), то предполагается европейский формат dmy.

Таким образом, вы просто не можете использовать, как вы хотите. Когда вы попытаетесь использовать формат dd / mm / yyyy с этим, тогда он удалит FALSE. Вы можете настроить следующее.

$date = "23/02/2013";
$timestamp = strtotime($date);
if ($timestamp === FALSE) {
  $timestamp = strtotime(str_replace('/', '-', $date));
}
echo $timestamp; // prints 1361577600
МАУЛИК ​​МОДИ
источник
1

Как у нас есть дата "07 / May / 2018" и нам нужна дата "2018-05-07" как mysql совместимая

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

Меня устраивает. наслаждаться :)

Ньютон Сингх
источник
0

Поскольку никто не упомянул об этом, вот еще один способ:

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

Sodj
источник
0

Если вы хотите принимать даты, используя американский порядок (месяц, дата, год) для европейских стилевых форматов (используя тире или точку в качестве дня, месяца, года), при этом принимая другие форматы , вы можете расширить класс 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'

Или вы можете сделать функцию для приема mdY и вывода 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

для создания даты из любой строки используйте:
$ date = DateTime :: createFromFormat ('dmy H: i', '01 -01-01 01:00 '); echo $ date-> format ('Ymd H: i');

Азуз Мохамади
источник