Перетворення рядка в Date and DateTime


292

Якщо у мене є рядок PHP у форматі mm-dd-YYYY(наприклад, 10-16-2003), як я можу правильно перетворити Dateце DateTimeу формат a, а потім у формат 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 (РРРР-MM-DD) або DateTime :: createFromFormat (), коли це можливо.


11
Це не спрацює. PHP інтерпретуватиме цей вхід як DD-MM-YYYY.
Метью

я додав трохи більше пояснень , щоб мій код, завдяки @konforce
Ібу

9
Читайте наступну відповідь для кращого рішення
Мануель Бітто

@delive ваш рядок дати, швидше за все, не є правильною датою.
Ібу

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 року. Ніхто більше не повинен його виконувати; харчування для цих людей просто дозволяє їм запускати застаріле, небезпечне програмне забезпечення.
Матвій

@Matthew так, правильно. Але ви ніколи, навіть сьогодні я знайшов версію PHP4.1, як і раніше встановлену ...
Roland

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


Зауважте, що перевірка $ 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 (), щоб забезпечити створення дати для потрібного часового поясу, а не сервера за замовчуванням.


6
Я вважаю, що це призведе до виключення, оскільки 16 місяця недійсний.
Метью

Важливо зазначити, що клас PHP DateTime доступний з PHP версії 5.2 та getTimestamp з 5.3
Дієго Немо

2

Для першого побачення

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

Для нової дати

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

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 / травень / 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");


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-> формат ('Ymd H: i');

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.