JavaScript: останні 30 і 90 днів без помилок
27.05.2026Якщо вам потрібно швидко зробити фільтр “за останні 30 днів” або “за останні 90 днів” у JavaScript, найчастіше проблема не в самій арифметиці, а в порівнянні дат: локальний час, UTC, формат рядка та мутація об’єкта Date легко дають дивні результати. Нижче — прості й практичні підходи, які допоможуть коректно рахувати періоди та фільтрувати масиви без зайвої магії.
Як порахувати 30 або 90 днів тому в JavaScript
Найпростіша ідея така: беремо поточну дату, віднімаємо потрібну кількість днів і отримуємо “межу” для фільтра. У чистому JavaScript це можна зробити через Date та методи для роботи з мілісекундами.
const now = new Date();
const days = 30;
const startDate = new Date(now);
startDate.setDate(now.getDate() - days);
console.log(startDate);
Для 90 днів логіка та сама:
const now = new Date();
const days = 90;
const startDate = new Date(now);
startDate.setDate(now.getDate() - days);
Цей варіант зручний, але варто пам’ятати: Date — це об’єкт, який можна змінювати. Тому краще створювати новий екземпляр, а не “відкушувати” дні від оригінального now, якщо він ще десь використовується.
Як зробити фільтр за останні 30/90 днів
Найчастіший кейс — є масив об’єктів із полем createdAt або updatedAt, і потрібно залишити тільки ті записи, які потрапляють у потрібний період. Наприклад, для запиту на кшталт javascript last 30 days або javascript last 90 days date filter добре працює порівняння з пороговою датою.
const items = [
{ id: 1, createdAt: '2026-01-10T12:00:00Z' },
{ id: 2, createdAt: '2026-02-01T09:30:00Z' },
{ id: 3, createdAt: '2026-03-15T18:45:00Z' }
];
const days = 30;
const now = new Date();
const threshold = new Date(now);
threshold.setDate(now.getDate() - days);
const filtered = items.filter((item) => {
const createdAt = new Date(item.createdAt);
return createdAt >= threshold;
});
console.log(filtered);
Якщо потрібно зробити фільтр за 90 днів, змініть лише значення days. Такий підхід добре підходить для таблиць, CRM, аналітики та сторінок зі звітами, де важливо швидко відсіяти старі записи.
Варіант з відрізанням часу до початку дня
Іноді проблема не в самих днях, а в точності до години, хвилини й секунди. Якщо вам потрібно рахувати період “з початку дня N днів тому”, можна спочатку обнулити час у даті межі.
const threshold = new Date();
threshold.setDate(threshold.getDate() - 30);
threshold.setHours(0, 0, 0, 0);
Це корисно, коли фільтр має працювати по календарних днях, а не по точному моменту часу. Але тут особливо важливо розуміти часовий пояс, у якому ви обнуляєте час.
Чому виникають помилки через часові пояси
Найпоширеніша причина “плаваючих” результатів — змішування локального часу та UTC. Наприклад, дата з бекенда може приходити у форматі ISO з Z, тобто в UTC, а ви порівнюєте її з локальною датою браузера. У такому разі два значення, які виглядають однаково в інтерфейсі, можуть насправді відрізнятися на кілька годин.
Ще один нюанс: рядок на кшталт 2026-03-15 і рядок 2026-03-15T00:00:00Z можуть інтерпретуватися по-різному залежно від середовища та способу парсингу. Тому для фільтрації краще:
- зберігати дати в одному форматі;
- порівнювати вже перетворені об’єкти
Dateабо timestamps; - чітко розуміти, чи працюєте ви в UTC, чи в локальному часі.
Для багатьох задач безпечніше порівнювати числа — тобто мілісекунди від епохи — ніж рядки дати. Наприклад:
const thresholdMs = threshold.getTime();
const createdAtMs = new Date(item.createdAt).getTime();
return createdAtMs >= thresholdMs;
Такий підхід не вирішує всі можливі проблеми з часовими поясами, але він робить саме порівняння простішим і менш крихким.
Типові помилки з legacy Date
Коли люди шукають, як порахувати дні в JavaScript, вони часто натрапляють на рішення, які “працюють на моєму комп’ютері”, але ламаються в іншому середовищі. Ось кілька типових помилок.
1. Мутація вихідної дати
Якщо зробити так:
const now = new Date();
now.setDate(now.getDate() - 30);
ви зміните сам об’єкт now. Якщо далі він ще потрібен як “поточний момент”, отримаєте некоректну логіку. Безпечніше створювати копію.
2. Порівняння рядків замість дат
Рядкове порівняння може спрацювати для однакового ISO-формату, але це не універсальний підхід для всіх випадків. Якщо формат відрізняється, результат уже може бути несподіваним.
3. Змішування UTC і локального часу
Якщо частина системи зберігає дату в UTC, а частина відображає її в локальному часовому поясі, межі періоду можуть зрушитися. Особливо це помітно біля півночі, коли запис “ще сьогодні” для одного користувача вже може бути “завтра” для іншого.
Практичний шаблон для фільтрації
Ось зручний шаблон, який можна вставити у свій код і адаптувати під createdAt, updatedAt або будь-яке інше поле:
function filterByLastDays(items, dateField, days) {
const threshold = new Date();
threshold.setDate(threshold.getDate() - days);
const thresholdMs = threshold.getTime();
return items.filter((item) => {
const value = item[dateField];
if (!value) return false;
const itemDate = new Date(value);
return itemDate.getTime() >= thresholdMs;
});
}
const recent30 = filterByLastDays(items, 'createdAt', 30);
const recent90 = filterByLastDays(items, 'createdAt', 90);
Цей варіант зручний для повторного використання в таблицях, компонентах React, API-обробниках або утилітах для звітів.
Коли варто подумати про сучасні API
Legacy Date залишається корисним і широко доступним, але для нових проєктів варто оцінити, чи не краще використати сучасні інструменти для роботи з датами й часом. Особливо це актуально, якщо у вас складна логіка з часовими поясами, календарними датами, інтервалами або локалізацією.
Добра евристика проста: якщо задача — “порахувати 30 або 90 днів тому” і відфільтрувати записи, Date зазвичай достатньо. Якщо ж ви починаєте будувати календарі, складні звіти, планувальники або багатозонні сценарії, краще одразу перевірити, чи не потрібен сучасніший підхід.
Чекліст для дебагу дат
- Перевірте, у якому форматі приходить дата: ISO, timestamp чи локальний рядок.
- З’ясуйте, чи зберігає бекенд час у UTC.
- Не змінюйте вихідний об’єкт
Date, якщо він потрібен далі. - Порівнюйте числа часу, а не сирі рядки, коли це можливо.
- Уточніть, чи фільтр має працювати по календарних днях, чи по точному моменту часу.
- Перевірте результат у часовому поясі, який відповідає вашому сценарію.
Отже, якщо вам потрібен практичний спосіб вирішити задачу javascript last 30 days або javascript last 90 days date filter, почніть із простої межі дати, порівнюйте значення в мілісекундах і окремо продумайте часовий пояс. Це не зробить усю часову логіку “чарівно ідеальною”, але допоможе уникнути більшості типових багів у фільтрах і звітах.