Кастомные форматтеры

Механизм форматирования в Pikaday основан на разделении двух задач: преобразование объекта Date в строку для отображения и обратное преобразование строки в Date для восстановления состояния компонента. Такая модель позволяет полностью контролировать представление даты без изменения внутренней логики календаря.


Базовая модель форматирования

В стандартной конфигурации Pikaday использует опцию format, которая определяет строковый шаблон вывода.

new Pikaday({
    field: document.getElementById('date'),
    format: 'DD.MM.YYYY'
});

Формат задаётся через токены, которые интерпретируются библиотекой. Однако этот механизм ограничен фиксированным набором правил и не всегда покрывает нестандартные сценарии, такие как локализация с бизнес-логикой или специфические календарные системы.


Ограничения строкового форматирования

Шаблонный формат в Pikaday:

  • не поддерживает произвольные вычисления;
  • ограничен набором токенов;
  • не позволяет внедрять условную логику;
  • сложно расширяется под нестандартные форматы (например, финансовые периоды или кастомные отчётные даты).

Эти ограничения приводят к необходимости использования кастомных форматтеров через переопределение методов toString и parse.


Использование кастомных функций форматирования

Pikaday позволяет заменить строковый формат функцией через параметр toString.

Базовый пример кастомного форматтера

new Pikaday({
    field: document.getElementById('date'),
    toString(date) {
        const day = String(date.getDate()).padStart(2, '0');
        const month = String(date.getMonth() + 1).padStart(2, '0');
        const year = date.getFullYear();

        return `${year}/${month}/${day}`;
    }
});

В этом случае форматирование полностью контролируется разработчиком, а встроенные токены игнорируются.


Обратное преобразование строки в Date

Кастомный форматтер в Pikaday обычно сопровождается функцией parse, которая отвечает за восстановление объекта Date.

new Pikaday({
    field: document.getElementById('date'),
    toString(date) {
        return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
    },
    parse(dateString) {
        const [year, month, day] = dateString.split('-').map(Number);
        return new Date(year, month - 1, day);
    }
});

Связка toString + parse формирует симметричный контракт сериализации и десериализации.


Использование Intl.DateTimeFormat

В современных приложениях часто применяется Intl.DateTimeFormat для локализованного форматирования.

const formatter = new Intl.DateTimeFormat('ru-RU');

new Pikaday({
    field: document.getElementById('date'),
    toString(date) {
        return formatter.format(date);
    },
    parse(dateString) {
        const parts = dateString.split('.');
        return new Date(parts[2], parts[1] - 1, parts[0]);
    }
});

Такой подход позволяет:

  • учитывать локаль браузера или пользователя;
  • избегать ручного формирования строк;
  • унифицировать отображение даты в приложении.

Интеграция с внешними библиотеками форматирования

Pikaday часто используется совместно с библиотеками форматирования дат, такими как moment.js или аналогами.

Пример с moment.js

new Pikaday({
    field: document.getElementById('date'),
    toString(date) {
        return moment(date).format('YYYY-MM-DD');
    },
    parse(dateString) {
        return moment(dateString, 'YYYY-MM-DD').toDate();
    }
});

Такая схема упрощает работу с:

  • сложными форматами;
  • временными зонами;
  • международными стандартами представления даты.

Разделение UI и внутреннего представления

Ключевая архитектурная особенность кастомных форматтеров в Pikaday заключается в разделении:

  • внутреннего состояния (Date);
  • визуального представления (строка в input).

Это позволяет:

  • хранить данные в стандартизированном виде;
  • отображать дату в любом формате;
  • менять формат без влияния на бизнес-логику.

Обработка пользовательского ввода

При использовании кастомных форматтеров важной частью становится корректная обработка ввода пользователя.

parse(dateString) {
    if (!dateString) return null;

    const normalized = dateString.trim();
    const parts = normalized.split('/');

    if (parts.length !== 3) return new Date();

    const [day, month, year] = parts.map(Number);

    return new Date(year, month - 1, day);
}

В рамках Pikaday подобные проверки позволяют избежать:

  • некорректных дат;
  • NaN-значений;
  • ошибок парсинга при частичном вводе.

Кастомные форматтеры и временные зоны

В стандартной реализации JavaScript Date зависит от локальной временной зоны окружения. При работе с Pikaday это может приводить к смещению даты при сериализации.

Типичный подход — нормализация через UTC:

toString(date) {
    return date.toISOString().split('T')[0];
},
parse(dateString) {
    return new Date(dateString + 'T00:00:00Z');
}

Такой вариант уменьшает риск рассинхронизации даты между клиентами с разными часовыми поясами.


Композиция форматтеров

Кастомные форматтеры в Pikaday могут быть вынесены в отдельные функции и переиспользоваться.

function createISOFormatter() {
    return {
        toString(date) {
            return date.toISOString().substring(0, 10);
        },
        parse(str) {
            return new Date(str + 'T00:00:00Z');
        }
    };
}

new Pikaday({
    field: document.getElementById('date'),
    ...createISOFormatter()
});

Такой подход повышает:

  • повторное использование;
  • тестируемость;
  • консистентность форматов в проекте.

Сценарии использования кастомных форматтеров

В контексте Pikaday кастомные форматтеры применяются в следующих случаях:

  • финансовые системы с отчётными периодами;
  • CRM-системы с локализованными датами;
  • аналитические панели с ISO-логированием;
  • мульти-региональные интерфейсы.

Каждый сценарий требует строгого контроля над тем, как дата преобразуется в строку и обратно.


Совмещение с валидацией

Кастомные форматтеры часто дополняются логикой валидации внутри parse.

parse(dateString) {
    const date = new Date(dateString);

    if (isNaN(date.getTime())) {
        return null;
    }

    return date;
}

В Pikaday это позволяет предотвратить установку некорректных значений в поле ввода и сохранить целостность данных.