Библиотека Pikaday изначально предназначена для выбора даты и не содержит встроенного механизма работы со временем. Расширение функциональности до «дата + время» реализуется через надстройку над существующим календарём: добавление UI-компонентов, синхронизацию состояния и форматирование результата.
Основная идея заключается в разделении ответственности:
Date.Такой подход позволяет сохранить стабильность базовой библиотеки и избежать её модификации.
Базовая инициализация календаря остаётся неизменной и служит отправной точкой для дальнейшего расширения.
const picker = new Pikaday({
field: document.getElementById('datepicker'),
format: 'DD.MM.YYYY',
onSelect: function(date) {
console.log(date);
}
});
На этом этапе выбирается только дата. Объект Date
содержит время, но оно всегда равно 00:00:00, что создаёт
основу для дальнейшего расширения логики.
Расширение функциональности реализуется через дополнительную разметку, которая либо внедряется внутрь контейнера календаря, либо отображается рядом с ним.
Типичная структура включает:
Пример HTML-структуры:
<div class="time-picker">
<select id="hours"></select>
<select id="minutes"></select>
</div>
Заполнение значений производится динамически:
const hours = document.getElementById('hours');
const minutes = document.getElementById('minutes');
for (let i = 0; i < 24; i++) {
const option = document.createElement('option');
option.value = i;
option.textContent = String(i).padStart(2, '0');
hours.appendChild(option);
}
for (let i = 0; i < 60; i++) {
const option = document.createElement('option');
option.value = i;
option.textContent = String(i).padStart(2, '0');
minutes.appendChild(option);
}
Ключевая задача расширения заключается в корректном объединении даты, выбранной в календаре, и времени из дополнительных контролов.
function mergeDateTime(date, hours, minutes) {
const result = new Date(date);
result.setHours(hours);
result.setMinutes(minutes);
result.setSeconds(0);
result.setMilliseconds(0);
return result;
}
Интеграция с календарём:
picker.on('select', function() {
const date = picker.getDate();
const h = parseInt(hours.value, 10);
const m = parseInt(minutes.value, 10);
const merged = mergeDateTime(date, h, m);
console.log('Итоговое значение:', merged);
});
Такой подход гарантирует, что любое изменение времени автоматически отражается в итоговой дате.
Для обеспечения реактивности требуется обработка событий изменения элементов времени.
function updateFromTimeChange() {
const date = picker.getDate();
if (!date) return;
const h = parseInt(hours.value, 10);
const m = parseInt(minutes.value, 10);
const updated = mergeDateTime(date, h, m);
picker.setDate(updated, true);
}
hours.addEventListener('change', updateFromTimeChange);
minutes.addEventListener('change', updateFromTimeChange);
Параметр true в setDate предотвращает
повторный вызов событий выбора даты и снижает риск циклических
обновлений.
В зависимости от требований проекта форматирование может выполняться
либо через стандартные методы Date, либо через сторонние
библиотеки.
Пример форматирования через нативные средства:
function formatDateTime(date) {
const dd = String(date.getDate()).padStart(2, '0');
const mm = String(date.getMonth() + 1).padStart(2, '0');
const yyyy = date.getFullYear();
const hh = String(date.getHours()).padStart(2, '0');
const mi = String(date.getMinutes()).padStart(2, '0');
return `${dd}.${mm}.${yyyy} ${hh}:${mi}`;
}
При использовании временных библиотек возможна более гибкая работа с форматами и часовыми поясами, но принцип объединения данных остаётся неизменным.
Событие onSelect выступает центральной точкой
синхронизации состояния календаря и времени.
const state = {
date: null
};
const picker = new Pikaday({
field: document.getElementById('datepicker'),
onSelect: function(date) {
state.date = date;
const h = parseInt(hours.value, 10);
const m = parseInt(minutes.value, 10);
state.date = mergeDateTime(date, h, m);
document.getElementById('datepicker').value =
formatDateTime(state.date);
}
});
Такой подход позволяет отделить UI-слой от логики хранения данных, что упрощает интеграцию с формами и внешними API.
При установке значения извне важно синхронизировать не только календарь, но и элементы времени.
function setDateTime(date) {
picker.setDate(date, true);
hours.value = date.getHours();
minutes.value = date.getMinutes();
document.getElementById('datepicker').value =
formatDateTime(date);
}
Это предотвращает рассинхронизацию интерфейса при загрузке данных из сервера или восстановлении состояния формы.
Расширение Pikaday до режима «дата + время» накладывает ряд технических ограничений:
Дополнительно следует учитывать, что календарный компонент остаётся независимым от временной логики, поэтому любые изменения в одном слое должны явно отражаться в другом через контролируемые функции синхронизации.