Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Чому з датами в JavaScript стільки проблем і як працювати з Date безпечно?

Об'єкт Date зберігає одну мить у часі - кількість мілісекунд від 1970-01-01 UTC. Часового поясу в ньому немає: методи на кшталт getHours() показують цю мить у поясі браузера користувача, а getUTCHours() - в UTC.

Головні пастки:

1. Місяці з нуля.

new Date(2026, 0, 31);   // 31 січня 2026
new Date(2026, 1, 31);   // 3 березня - «переповнення» тихо переноситься

2. Розбір рядків залежить від формату.

new Date('2026-10-04');        // північ за UTC (лише дата - як UTC)
new Date('2026-10-04T10:00');  // 10:00 за місцевим часом браузера
new Date('04.10.2026');        // залежить від рушія - не використовувати

Користувач у Києві побачить new Date('2026-10-04').getDate() як 4, а в Нью-Йорку - як 3: північ UTC там ще попередній день.

3. Об'єкт змінюваний.

const start = new Date();
const end = start;
end.setDate(end.getDate() + 7);   // змінили і start теж

4. Арифметика місяців. setMonth(month + 1) від 31 січня дає 3 березня (лютого 31-го не існує).

Як працювати безпечно:

  • обмінюватися з сервером у ISO 8601 з поясом: 2026-10-04T07:00:00Z чи з зміщенням +03:00. Laravel за замовчуванням серіалізує дати моделей саме так (UTC з Z);
  • зберігати й передавати мить у UTC, а в місцевий час перетворювати лише для показу;
  • показувати через Intl.DateTimeFormat, а не збирати рядок вручну:
new Intl.DateTimeFormat('uk', {
  dateStyle: 'long',
  timeStyle: 'short',
  timeZone: 'Europe/Kyiv',
}).format(new Date('2026-10-04T07:00:00Z'));
// '4 жовтня 2026 р. о 10:00'
  • «дата без часу» (день народження, дата події) - не перетворювати на Date взагалі, а тримати рядком '2026-10-04', інакше часовий пояс зсуне її на день;
  • відносний час - Intl.RelativeTimeFormat('uk') («3 дні тому»).

Що далі. Новий API Temporal розділяє поняття: Temporal.PlainDate (дата без часу й поясу), Temporal.ZonedDateTime (час у конкретному поясі), Temporal.Instant (мить) - і робить їх незмінними. Він поступово з'являється в браузерах; до повної підтримки - поліфіл або бібліотеки (date-fns, Day.js, Luxon).

Докладніше в документації: Date

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання