Avatar ·

Как правильно форматировать дату в JavaScript? (формат ДД.ММ.ГГГГ и другие)

Всем привет! Только начал изучать JavaScript и столкнулся с проблемой форматирования дат. Нужно вывести текущую дату в формате "12.05.2023" (день.месяц.год), но стандартный вывод new Date() даёт что-то вроде "Fri May 12 2023 14:30:00 GMT+0300". Это вообще нечитаемо для пользователя. Пробовал использовать методы getDate(), getMonth(), getFullYear(), но получается криво: ```javascript const now = new Date(); console.log(now.getDate() + '.' + now.getMonth() + '.' + now.getFullYear()); // Выводит: 12.4.2023 (месяц почему-то 4, а не 5!) ``` Ещё проблема: если день или месяц меньше 10, то нет ведущего нуля. Получается "1.5.2023", а нужно "01.05.2023". Подскажите, как правильно и красиво форматировать даты? Может есть встроенные методы или нужно писать свою функцию? И что делать с разными форматами — например, для международного формата "2023-05-12" или для вывода времени "14:30:05"? Буду благодарен за примеры кода и объяснение, как это работает. Заранее спасибо! <<>>

Правильное форматирование дат в JavaScript

Вы столкнулись с классической проблемой — в JavaScript нет встроенного метода для произвольного форматирования дат, а getMonth() возвращает месяцы от 0 (январь) до 11 (декабрь). Поэтому май (месяц 5) отображается как 4.

Вот три основных подхода к решению:

1. Ручное форматирование с помощью методов Date

Самый простой и понятный способ — написать свою функцию:

function formatDate(date, format = 'DD.MM.YYYY') {
  const day = String(date.getDate()).padStart(2, '0');
  const month = String(date.getMonth() + 1).padStart(2, '0'); // +1 так как месяцы с 0
  const year = date.getFullYear();
  const hours = String(date.getHours()).padStart(2, '0');
  const minutes = String(date.getMinutes()).padStart(2, '0');
  const seconds = String(date.getSeconds()).padStart(2, '0');

  switch (format) {
    case 'DD.MM.YYYY':
      return `${day}.${month}.${year}`;
    case 'YYYY-MM-DD':
      return `${year}-${month}-${day}`;
    case 'DD.MM.YYYY HH:mm:ss':
      return `${day}.${month}.${year} ${hours}:${minutes}:${seconds}`;
    default:
      return `${day}.${month}.${year}`;
  }
}

// Использование:
const now = new Date();
console.log(formatDate(now)); // "12.05.2023"
console.log(formatDate(now, 'YYYY-MM-DD')); // "2023-05-12"
console.log(formatDate(now, 'DD.MM.YYYY HH:mm:ss')); // "12.05.2023 14:30:05"

Важно: padStart(2, '0') добавляет ноль слева, если число меньше 10. А getMonth() + 1 исправляет нумерацию месяцев.

2. Использование Intl.DateTimeFormat (рекомендуется)

Это встроенный объект для локализованного форматирования дат:

const now = new Date();

// Русская локаль
const ruFormatter = new Intl.DateTimeFormat('ru-RU', {
  day: '2-digit',
  month: '2-digit',
  year: 'numeric',
  hour: '2-digit',
  minute: '2-digit',
  second: '2-digit'
});
console.log(ruFormatter.format(now)); // "12.05.2023, 14:30:05"

// Международный формат (ISO)
const isoFormatter = new Intl.DateTimeFormat('fr-CA', {
  year: 'numeric',
  month: '2-digit',
  day: '2-digit'
});
console.log(isoFormatter.format(now)); // "2023-05-12"

// Только дата без времени
const dateOnly = new Intl.DateTimeFormat('ru-RU', {
  day: '2-digit',
  month: '2-digit',
  year: 'numeric'
});
console.log(dateOnly.format(now)); // "12.05.2023"

3. Современный метод toLocaleDateString()

Более короткая запись того же самого:

const now = new Date();

// Русский формат
console.log(now.toLocaleDateString('ru-RU')); // "12.05.2023"

// С временем
console.log(now.toLocaleString('ru-RU')); // "12.05.2023, 14:30:05"

// Американский формат
console.log(now.toLocaleDateString('en-US')); // "5/12/2023"

// Кастомные опции
console.log(now.toLocaleDateString('ru-RU', {
  year: 'numeric',
  month: 'long',
  day: 'numeric'
})); // "12 мая 2023 г."

Рекомендации

  • Для простых проектов используйте ручное форматирование — оно прозрачно и не требует дополнительных знаний.
  • Для серьёзных проектов с локализацией — Intl.DateTimeFormat или toLocaleDateString().
  • Если нужно много работать с датами (сложение, вычитание, часовые пояса) — установите библиотеку date-fns или Luxon.

Пример с date-fns:

// npm install date-fns
import { format } from 'date-fns';

const now = new Date();
console.log(format(now, 'dd.MM.yyyy')); // "12.05.2023"
console.log(format(now, 'yyyy-MM-dd HH:mm:ss')); // "2023-05-12 14:30:05"

Главное — всегда помнить про getMonth() + 1 и использовать padStart() для ведущих нулей. Удачи в изучении JavaScript!

<<>>

Альтернативный подход: шаблонная функция форматирования

Можно сделать более гибкую функцию, которая принимает строку-шаблон с символами:

function formatDate(date, template) {
  const map = {
    'YYYY': date.getFullYear(),
    'YY': String(date.getFullYear()).slice(-2),
    'MM': String(date.getMonth() + 1).padStart(2, '0'),
    'M': date.getMonth() + 1,
    'DD': String(date.getDate()).padStart(2, '0'),
    'D': date.getDate(),
    'HH': String(date.getHours()).padStart(2, '0'),
    'H': date.getHours(),
    'mm': String(date.getMinutes()).padStart(2, '0'),
    'm': date.getMinutes(),
    'ss': String(date.getSeconds()).padStart(2, '0'),
    's': date.getSeconds()
  };

  return template.replace(/YYYY|YY|MM|M|DD|D|HH|H|mm|m|ss|s/g, match => map[match]);
}

// Использование:
const now = new Date();
console.log(formatDate(now, 'DD.MM.YYYY')); // "12.05.2023"
console.log(formatDate(now, 'YYYY-MM-DD HH:mm:ss')); // "2023-05-12 14:30:05"
console.log(formatDate(now, 'D/M/YY')); // "12/5/23" (без ведущих нулей)

Этот подход удобен, когда нужно много разных форматов — не нужно писать switch/case. Просто передаёте шаблон, и функция сама подставляет значения. Минус — регулярное выражение может быть медленнее при огромном количестве вызовов, но для обычных задач это незаметно.

Также обратите внимание на запись даты в ISO формате через .toISOString():

console.log(new Date().toISOString()); // "2023-05-12T11:30:05.123Z"

Это стандарт для передачи дат между сервером и клиентом.