Avatar ·

Как правильно форматировать дату и время в JavaScript? Нет встроенного метода?

Всем привет! Я только начал изучать JavaScript и столкнулся с проблемой форматирования даты. Мне нужно вывести текущую дату в формате "ДД.ММ.ГГГГ ЧЧ:ММ", но я не могу найти встроенный метод, который бы это делал. Вот что я пробовал: ```javascript const now = new Date(); console.log(now); // Выводит что-то вроде "Fri Jan 12 2024 15:30:45 GMT+0300" ``` Мне нужен именно русский формат с точками и двузначными числами. Я знаю, что есть методы `.getDate()`, `.getMonth()` и т.д., но они возвращают числа без ведущих нулей. Например, 5 января показывает "5", а не "05". И месяц начинается с 0, так что январь — это 0, а не 1. Это очень неудобно! Я слышал про библиотеки вроде moment.js, но мне кажется странным подключать целую библиотеку только для форматирования даты. Неужели в современном JavaScript нет нормального способа сделать это нативно? Подскажите, как правильно и красиво форматировать даты в чистом JavaScript? Может быть, есть какой-то стандартный метод, о котором я не знаю? Или придется каждый раз писать свою функцию с ручным добавлением нулей и преобразованием месяца? Буду благодарен за примеры кода и объяснение для новичков. <<>>

Нативное форматирование дат в JavaScript: полное руководство

Вы правы — в JavaScript долгое время не было удобного встроенного способа форматирования дат. Но хорошая новость: начиная с ES2017 (и особенно с современными браузерами), у нас есть мощный инструмент — Intl.DateTimeFormat. Никаких библиотек не нужно!

1. Базовое форматирование с Intl.DateTimeFormat

Вот как решить вашу задачу — получить "ДД.ММ.ГГГГ ЧЧ:ММ":

const now = new Date();
const formatter = new Intl.DateTimeFormat('ru-RU', {
    day: '2-digit',
    month: '2-digit',
    year: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
    hour12: false // 24-часовой формат
});

console.log(formatter.format(now)); // "12.01.2024 15:30"

Этот метод автоматически добавляет ведущие нули, использует русскую локаль и не требует ручного преобразования месяцев.

2. Ручной способ (для понимания)

Если вы хотите понять, как это работает "под капотом", вот классический подход:

function formatDate(date) {
    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');
    
    return `${day}.${month}.${year} ${hours}:${minutes}`;
}

console.log(formatDate(new Date())); // "12.01.2024 15:30"

Метод padStart(2, '0') гарантирует, что число будет минимум двузначным (5 → "05", 12 → "12").

3. Расширенные возможности Intl.DateTimeFormat

Объект Intl.DateTimeFormat умеет гораздо больше. Вот несколько полезных опций:

const date = new Date(2024, 0, 12, 15, 30, 45); // 12 января 2024, 15:30:45

// Полная дата с названиями
const fullFormatter = new Intl.DateTimeFormat('ru-RU', {
    weekday: 'long',
    year: 'numeric',
    month: 'long',
    day: 'numeric'
});
console.log(fullFormatter.format(date)); // "пятница, 12 января 2024 г."

// Только время с секундами
const timeFormatter = new Intl.DateTimeFormat('ru-RU', {
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    hour12: false
});
console.log(timeFormatter.format(date)); // "15:30:45"

// Короткая дата без времени
const shortFormatter = new Intl.DateTimeFormat('ru-RU', {
    dateStyle: 'short'
});
console.log(shortFormatter.format(date)); // "12.01.2024"

4. Форматирование для разных локалей

Вы можете легко переключаться между форматами разных стран:

const date = new Date(2024, 0, 12);

// США
const usFormatter = new Intl.DateTimeFormat('en-US');
console.log(usFormatter.format(date)); // "1/12/2024"

// Германия
const deFormatter = new Intl.DateTimeFormat('de-DE');
console.log(deFormatter.format(date)); // "12.1.2024"

// Япония
const jpFormatter = new Intl.DateTimeFormat('ja-JP');
console.log(jpFormatter.format(date)); // "2024/1/12"

5. Важные замечания

  • Месяцы с 0: В JavaScript месяцы нумеруются с 0 (январь = 0). Не забывайте прибавлять 1 при ручном форматировании.
  • Intl.DateTimeFormat поддерживается во всех современных браузерах и Node.js (с версии 0.12).
  • Производительность: Если вы форматируете много дат, создайте один экземпляр Intl.DateTimeFormat и переиспользуйте его — это быстрее, чем создавать новый каждый раз.
  • Часовые пояса: По умолчанию используется часовой пояс пользователя. Можно указать другой через опцию timeZone.

Используйте Intl.DateTimeFormat — это современный, гибкий и производительный способ форматирования дат без внешних зависимостей.

<<>>

Альтернативный подход: шаблонные строки и toLocaleString()

Есть ещё один удобный метод — toLocaleString(), который работает напрямую с объектом Date:

const now = new Date();
const formatted = now.toLocaleString('ru-RU', {
    day: '2-digit',
    month: '2-digit',
    year: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
    hour12: false
});
console.log(formatted); // "12.01.2024, 15:30"

Разница с Intl.DateTimeFormat в том, что toLocaleString() создаёт новый форматтер при каждом вызове. Для одноразового использования это нормально, но для частых вызовов лучше создать экземпляр Intl.DateTimeFormat заранее.

Также можно использовать toLocaleDateString() и toLocaleTimeString() по отдельности:

const now = new Date();
const datePart = now.toLocaleDateString('ru-RU'); // "12.01.2024"
const timePart = now.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' }); // "15:30"
console.log(`${datePart} ${timePart}`); // "12.01.2024 15:30"

Дополнительный совет: Если вам нужно только получить компоненты даты без форматирования, используйте Intl.DateTimeFormat с опцией formatToParts():

const formatter = new Intl.DateTimeFormat('ru-RU', {
    day: 'numeric', month: 'numeric', year: 'numeric'
});
const parts = formatter.formatToParts(new Date());
console.log(parts);
// [
//   { type: 'day', value: '12' },
//   { type: 'month', value: '1' },
//   { type: 'year', value: '2024' }
// ]

Этот метод возвращает массив объектов, что удобно для кастомной обработки.