Пошук уроків, статей та іншого контенту
Навчитеся безпечно порівнювати дати, знаходити різницю між ними та працювати з мілісекундами.
У JavaScript дата представлена об’єктом Date. Усередині об’єкт зберігає кількість мілісекунд від початку Unix-епохи:
1 січня 1970 року, 00:00:00 UTC.
Це число називають часовою міткою або timestamp.
const now = new Date();
console.log(now);
console.log(now.getTime());Метод getTime() повертає кількість мілісекунд від Unix-епохи до моменту, який зберігає об’єкт Date.
Також часову мітку можна отримати за допомогою Date.now():
const timestamp = Date.now();
console.log(timestamp);Date.now() повертає час для поточного моменту, а getTime() — час для конкретного об’єкта Date.
const currentDate = new Date();
console.log(currentDate);Дата створюється на основі поточних налаштувань системи та поточного моменту.
Найнадійніший формат для передавання дати — ISO 8601:
const startDate = new Date("2025-03-01T10:00:00Z");
console.log(startDate);Символ Z означає UTC — всесвітній координований час.
Для однозначного результату краще явно вказувати часовий пояс:
const kyivDate = new Date("2025-03-01T10:00:00+02:00");
console.log(kyivDate);Конструктор Date може приймати рік, місяць, день та інші компоненти:
const date = new Date(2025, 2, 15);
console.log(date);Важливо: місяці нумеруються з нуля:
0 — січень;
1 — лютий;
2 — березень;
11 — грудень.
Тому new Date(2025, 2, 15) означає 15 березня 2025 року.
Щоб уникати плутанини, для збереження та передавання дат часто використовують ISO-рядки.
Якщо JavaScript не може розібрати рядок як дату, створюється об’єкт із некоректним значенням:
const invalidDate = new Date("це не дата");
console.log(invalidDate);
console.log(invalidDate.getTime());Для перевірки використовуйте Number.isNaN():
function isValidDate(value) {
const date = new Date(value);
return !Number.isNaN(date.getTime());
}
console.log(isValidDate("2025-03-01")); // true
console.log(isValidDate("це не дата")); // falseСамої перевірки date instanceof Date недостатньо: некоректне значення також є об’єктом Date.
Об’єкти Date можна порівнювати за допомогою операторів:
< — раніше;
> — пізніше;
<= — раніше або в цей момент;
>= — пізніше або в цей момент.
const firstDate = new Date("2025-03-01T10:00:00Z");
const secondDate = new Date("2025-03-10T10:00:00Z");
console.log(firstDate < secondDate); // true
console.log(firstDate > secondDate); // false
console.log(firstDate <= secondDate); // trueJavaScript під час такого порівняння фактично порівнює часові мітки дат.
Для перевірки, чи позначають дві дати один і той самий момент, використовуйте getTime():
const firstDate = new Date("2025-03-01T10:00:00Z");
const secondDate = new Date("2025-03-01T10:00:00Z");
console.log(firstDate === secondDate); // false
console.log(firstDate.getTime() === secondDate.getTime()); // true=== порівнює об’єкти за посиланням. Навіть якщо два об’єкти містять однакову дату, це різні об’єкти в пам’яті.
Зручно створити окрему функцію:
function areDatesEqual(firstDate, secondDate) {
return firstDate.getTime() === secondDate.getTime();
}
const firstDate = new Date("2025-03-01T10:00:00Z");
const secondDate = new Date("2025-03-01T10:00:00Z");
console.log(areDatesEqual(firstDate, secondDate)); // trueВіднімання двох об’єктів Date повертає різницю в мілісекундах:
const startDate = new Date("2025-03-01T10:00:00Z");
const endDate = new Date("2025-03-03T10:00:00Z");
const differenceInMilliseconds = endDate - startDate;
console.log(differenceInMilliseconds); // 172800000Дві доби містять:
2 × 24 × 60 × 60 × 1000 = 172800000 мілісекундТе саме можна записати через getTime():
const difference =
endDate.getTime() - startDate.getTime();
console.log(difference);Результат буде додатним, якщо endDate пізніше за startDate, і від’ємним — якщо раніше.
Для перетворень зручно використовувати константи:
const millisecondsInSecond = 1000;
const millisecondsInMinute = millisecondsInSecond * 60;
const millisecondsInHour = millisecondsInMinute * 60;
const millisecondsInDay = millisecondsInHour * 24;const firstDate = new Date("2025-03-01T10:00:00Z");
const secondDate = new Date("2025-03-01T10:01:30Z");
const differenceInMilliseconds = secondDate - firstDate;
const differenceInSeconds = differenceInMilliseconds / 1000;
console.log(differenceInSeconds); // 90const firstDate = new Date("2025-03-01T08:00:00Z");
const secondDate = new Date("2025-03-01T14:30:00Z");
const differenceInHours = (secondDate - firstDate) / (1000 * 60 * 60);
console.log(differenceInHours); // 6.5Якщо потрібна кількість повних діб, використовуйте Math.floor():
const startDate = new Date("2025-03-01T10:00:00Z");
const endDate = new Date("2025-03-03T09:00:00Z");
const millisecondsInDay = 24 * 60 * 60 * 1000;
const fullDays = Math.floor(
(endDate - startDate) / millisecondsInDay
);
console.log(fullDays); // 1Між цими датами минуло 47 годин, тобто лише одна повна доба.
Якщо потрібно округлити результат до найближчого цілого, використовуйте Math.round():
const approximateDays = Math.round(
(endDate - startDate) / millisecondsInDay
);
console.log(approximateDays); // 2Вибір функції залежить від задачі:
Math.floor() — кількість повністю завершених одиниць часу;
Math.ceil() — округлення вгору;
Math.round() — найближче ціле число.
Розглянемо функцію, яка визначає, чи завершився термін дії підписки:
function getSubscriptionStatus(expirationDateString) {
const expirationDate = new Date(expirationDateString);
if (Number.isNaN(expirationDate.getTime())) {
return "Некоректна дата";
}
const remainingMilliseconds = expirationDate.getTime() - Date.now();
if (remainingMilliseconds <= 0) {
return "Підписка завершилася";
}
const millisecondsInDay = 24 * 60 * 60 * 1000;
const remainingDays = Math.ceil(
remainingMilliseconds / millisecondsInDay
);
return `Залишилося днів: ${remainingDays}`;
}
console.log(
getSubscriptionStatus("2099-12-31T23:59:59Z")
);Тут:
рядок перетворюється на об’єкт Date;
перевіряється коректність дати;
з дати завершення віднімається поточний момент;
мілісекунди перетворюються на дні;
використовується Math.ceil(), щоб навіть неповний день рахувався як один день, що залишився.
Один і той самий момент може відображатися по-різному в різних часових поясах.
const date = new Date("2025-03-01T10:00:00Z");
console.log(date.toISOString());
console.log(date.toString());toISOString() завжди повертає дату в UTC. toString() зазвичай відображає дату в часовому поясі середовища, де виконується код.
Порівняння об’єктів Date працює коректно, якщо вони представляють той самий момент:
const firstDate = new Date("2025-03-01T10:00:00Z");
const secondDate = new Date("2025-03-01T12:00:00+02:00");
console.log(firstDate.getTime() === secondDate.getTime()); // trueОбидва записи позначають один момент часу: 10:00 за UTC.
Іноді час не має значення. Наприклад, потрібно перевірити, чи припадають дві події на один календарний день.
Для цього можна порівняти компоненти року, місяця та дня:
function isSameCalendarDay(firstDate, secondDate) {
return (
firstDate.getFullYear() === secondDate.getFullYear() &&
firstDate.getMonth() === secondDate.getMonth() &&
firstDate.getDate() === secondDate.getDate()
);
}
const firstDate = new Date(2025, 2, 1, 9, 0);
const secondDate = new Date(2025, 2, 1, 18, 30);
console.log(isSameCalendarDay(firstDate, secondDate)); // trueМетоди getFullYear(), getMonth() і getDate() працюють у локальному часовому поясі.
Для UTC-значень використовуйте відповідні методи:
getUTCFullYear();
getUTCMonth();
getUTCDate().
Вибір між локальними та UTC-методами має відповідати правилам вашої задачі.
Dateconst date = new Date("2025-03-15T12:30:45Z");
console.log(date.getFullYear()); // рік у локальному часовому поясі
console.log(date.getMonth()); // місяць від 0 до 11
console.log(date.getDate()); // день місяця від 1 до 31
console.log(date.getHours()); // година в локальному часовому поясі
console.log(date.getUTCFullYear()); // рік у UTC
console.log(date.getUTCMonth()); // місяць у UTC
console.log(date.getUTCDate()); // день у UTC
console.log(date.getUTCHours()); // година в UTC
console.log(date.toISOString()); // ISO-рядок у UTCДля порівняння та обчислень зазвичай достатньо:
new Date(...);
Date.now();
getTime();
арифметичних операторів;
toISOString().
Рядки не завжди можна безпечно порівнювати як дати:
console.log("10.03.2025" > "02.12.2024");Порядок символів у рядках не є надійним способом порівняння дат. Спочатку перетворюйте значення на Date.
Формат YYYY-MM-DD має лексикографічний порядок, який збігається з хронологічним, але для загального коду краще все одно явно працювати з датами.
===const firstDate = new Date("2025-03-01");
const secondDate = new Date("2025-03-01");
console.log(firstDate === secondDate); // falseПотрібно порівнювати часові мітки:
console.log(firstDate.getTime() === secondDate.getTime()); // trueconst date = new Date(2025, 1, 1);
console.log(date); // 1 лютого, а не 1 січняУ числовому конструкторі Date січень має індекс 0.
Ділення різниці на 24 * 60 * 60 * 1000 обчислює різницю між моментами тривалістю 24 години. Це не завжди те саме, що різниця календарних дат у локальному часовому поясі, особливо під час переходів на літній або зимовий час.
Якщо важливі саме календарні дні, потрібно заздалегідь визначити часовий пояс і правила обчислення.
const date = new Date(userInput);
const days = (date - new Date()) / (1000 * 60 * 60 * 24);Якщо userInput некоректний, результатом стане NaN. Перевіряйте getTime() перед подальшими обчисленнями.
Date представляє конкретний момент часу.
Внутрішнє значення дати вимірюється в мілісекундах від 1 січня 1970 року UTC.
Для порівняння дат можна використовувати <, >, <= і >=.
Для перевірки рівності використовуйте getTime(), а не ===.
Віднімання двох дат повертає різницю в мілісекундах.
Для перетворення мілісекунд використовуйте 1000, 60, 60 і 24.
Перевіряйте дату через Number.isNaN(date.getTime()).
Для однозначного передавання дат використовуйте ISO-рядки з явним часовим поясом.
Розрізняйте різницю між моментами часу та різницю між календарними датами.