Avatar ·

Формат даты PHP для вставки в поле DATETIME в MySQL: как избежать ошибок?

Всем привет! Я новичок в PHP и MySQL, и у меня возникла проблема с сохранением даты в базу данных.

У меня есть форма, где пользователь вводит дату в формате дд.мм.гггг (например, 25.12.2023). Я хочу сохранить эту дату в поле DATETIME в MySQL. Я использую PHP-функцию date() для форматирования, но ничего не работает правильно.

Вот мой код:

<?php
$user_date = $_POST['user_date']; // Приходит "25.12.2023"
$formatted_date = date('Y-m-d H:i:s', strtotime($user_date));

$query = "INSERT INTO events (event_date) VALUES ('$formatted_date')";
mysqli_query($conn, $query);
?>

Проблема в том, что в базу данных записывается 1970-01-01 00:00:00 или вообще пустая строка. Я пробовал разные форматы в date(), но результат один и тот же. Подскажите, какой правильный формат даты нужен для MySQL поля DATETIME? И почему strtotime() не может распарсить мой формат?

Заранее спасибо за помощь!

<<>>

Правильный формат даты для MySQL DATETIME и решение проблемы

Проблема в вашем коде типична для новичков. Давайте разберём её по шагам.

Почему ваш код не работает?

MySQL ожидает дату в формате YYYY-MM-DD HH:MM:SS (ISO 8601). Функция date('Y-m-d H:i:s') выдаёт правильный формат, но проблема в strtotime(). Она не понимает русский формат дд.мм.гггг (с точками) — она ожидает американский мм/дд/гггг или международный гггг-мм-дд. Поэтому strtotime('25.12.2023') возвращает false, и date() преобразует false в 1970-01-01 (начало эпохи Unix).

Решение: используйте DateTime и createFromFormat()

Лучший способ — явно указать формат входной даты с помощью класса DateTime:

<?php
$user_date = $_POST['user_date']; // "25.12.2023"

// Создаём объект DateTime из строки с указанием формата
$date = DateTime::createFromFormat('d.m.Y', $user_date);

if (!$date) {
    die('Неверный формат даты. Ожидается: дд.мм.гггг');
}

// Форматируем для MySQL
$formatted_date = $date->format('Y-m-d H:i:s');

// Если нужно только дата (без времени), можно так:
// $formatted_date = $date->format('Y-m-d') . ' 00:00:00';

$query = "INSERT INTO events (event_date) VALUES ('$formatted_date')";
mysqli_query($conn, $query);
?>

Важные моменты:

  • Всегда проверяйте входные данные — используйте DateTime::createFromFormat(), он возвращает false при ошибке.
  • Используйте подготовленные запросы — это защитит от SQL-инъекций и упростит работу с датами:
<?php
$stmt = $conn->prepare("INSERT INTO events (event_date) VALUES (?)");
$stmt->bind_param("s", $formatted_date);
$stmt->execute();
?>

Другие популярные форматы ввода и их парсинг:

  • 25-12-2023 → DateTime::createFromFormat('d-m-Y', $date)
  • 2023/12/25 → DateTime::createFromFormat('Y/m/d', $date)
  • 25 December 2023 → DateTime::createFromFormat('d F Y', $date)
  • Если дата приходит из <input type="date"> — она уже в формате Y-m-d, можно сразу использовать.

Если нужно только текущая дата/время:

<?php
$now = new DateTime(); // текущий момент
$formatted = $now->format('Y-m-d H:i:s');
// или проще: $formatted = date('Y-m-d H:i:s');
?>

Используя DateTime, вы получаете гибкость, читаемость и избегаете ошибок, связанных с локалью сервера.

<<>>

Альтернативный подход: преобразование вручную

Если по каким-то причинам вы не можете использовать DateTime (например, старая версия PHP < 5.2), можно разобрать строку вручную с помощью explode() и mktime():

<?php
$user_date = $_POST['user_date']; // "25.12.2023"
$parts = explode('.', $user_date);

if (count($parts) !== 3) {
    die('Неверный формат');
}

$day = (int)$parts[0];
$month = (int)$parts[1];
$year = (int)$parts[2];

// Проверка корректности даты
if (!checkdate($month, $day, $year)) {
    die('Некорректная дата');
}

$timestamp = mktime(0, 0, 0, $month, $day, $year);
$formatted_date = date('Y-m-d H:i:s', $timestamp);
?>

Этот метод даёт полный контроль, но требует больше кода и ручной проверки. Рекомендую всё же использовать DateTime — он надёжнее и короче.