Типы данных

Библиотека Flatpickr строится вокруг работы с датами, однако в процессе конфигурации и взаимодействия с экземпляром календаря используется несколько различных типов данных. Несмотря на то, что JavaScript не является строго типизированным языком, Flatpickr опирается на предсказуемые структуры: Date, строки, числа (timestamp), массивы и специализированные внутренние представления.

Корректное понимание типов данных определяет стабильность работы календаря, отсутствие ошибок парсинга и правильную интеграцию с API.


Date как основной тип данных

Центральным типом данных в Flatpickr является объект Date.

Практически все внутренние вычисления выполняются именно с ним:

  • выбранная дата (selectedDates) хранится как массив Date
  • минимальные и максимальные ограничения (minDate, maxDate) принимают Date
  • обработчики событий получают Date-объекты
  • вычисления диапазонов опираются на Date.getTime()

Пример базового использования:

flatpickr("#input", {
  onChange: function(selectedDates) {
    const date = selectedDates[0];
    console.log(date instanceof Date);
  }
});

Особенность Flatpickr заключается в том, что даже если входные данные представлены строкой или числом, внутри библиотеки они почти всегда преобразуются в Date.


Строковые представления дат

Строки используются в Flatpickr как внешний формат данных. Они применяются в нескольких контекстах:

  • defaultDate в виде строки
  • minDate и maxDate как строковые ограничения
  • пользовательский ввод в <input>
  • сериализация/десериализация состояния

Пример:

flatpickr("#input", {
  defaultDate: "2026-06-01"
});

Строки интерпретируются на основе параметра dateFormat. Если формат не совпадает, Flatpickr пытается выполнить fallback-парсинг через нативный Date.parse, что может приводить к нестабильному поведению.


Форматы и парсинг строк

Ключевым механизмом работы со строками является параметр dateFormat.

Он определяет:

  • как строка преобразуется в Date
  • как Date преобразуется в строку
  • как отображается значение в input

Пример:

flatpickr("#input", {
  dateFormat: "d.m.Y"
});

Внутри Flatpickr используется собственный парсер, который разбивает строку по токенам:

  • d — день
  • m — месяц
  • Y — год
  • H — часы
  • i — минуты

Тип данных здесь фактически двусторонний:

  • вход: string
  • внутреннее представление: Date
  • вывод: string

Массивы дат (multiple mode)

При включении режима множественного выбора (mode: "multiple"), Flatpickr начинает использовать массив дат как основной тип результата.

flatpickr("#input", {
  mode: "multiple"
});

В этом режиме:

  • selectedDates становится массивом Date[]
  • значение input — строка с разделителями
  • каждая дата хранится независимо

Пример структуры:

[
  Date,
  Date,
  Date
]

Важная особенность: порядок дат в массиве не всегда гарантирован пользователем, но Flatpickr старается поддерживать хронологическую сортировку при внутренних операциях.


Диапазоны дат (range mode)

Режим диапазона (mode: "range") вводит специфическую модель данных: пара дат, интерпретируемая как начало и конец периода.

flatpickr("#input", {
  mode: "range"
});

Внутреннее представление:

  • selectedDates[0] — начало диапазона
  • selectedDates[1] — конец диапазона (может отсутствовать)

Тип данных:

Date | undefined

При обработке диапазонов Flatpickr использует дополнительные проверки:

  • если конец меньше начала — значения меняются местами
  • при повторном выборе диапазон сбрасывается

Timestamp и Unix-время

Flatpickr поддерживает использование числовых значений, интерпретируемых как timestamp.

flatpickr("#input", {
  defaultDate: 1717200000000
});

Числовой тип:

  • number (миллисекунды с 1970-01-01)
  • преобразуется в Date через new Date(timestamp)

Особенности:

  • поддерживаются только миллисекунды, не секунды
  • дробные значения приводят к округлению
  • используется при интеграции с API и backend

minDate и maxDate: гибридные типы

Ограничения диапазона дат допускают несколько типов значений:

  • Date
  • string
  • number (timestamp)
flatpickr("#input", {
  minDate: "2026-01-01",
  maxDate: new Date()
});

Flatpickr приводит все варианты к внутреннему Date, но логика сравнения всегда выполняется через числовое представление:

date.getTime()

Это позволяет унифицировать сравнение независимо от входного формата.


defaultDate и его вариативность

defaultDate — один из наиболее гибких параметров по типу данных.

Он может принимать:

  • Date
  • string
  • number
  • массив значений (Date[] | string[] | number[])

Пример:

flatpickr("#input", {
  defaultDate: ["2026-01-01", "2026-01-10"]
});

В зависимости от режима (single, multiple, range) Flatpickr интерпретирует массив по-разному:

  • single — берётся первый элемент
  • multiple — все элементы добавляются в selection
  • range — первые два элемента формируют диапазон

Конвертация типов внутри Flatpickr

Внутренний цикл обработки данных включает несколько стадий:

  1. Input normalization

    • строка / число / Date приводится к единому виду
  2. Parsing

    • строки преобразуются через parseDate
  3. Normalization

    • все значения приводятся к Date
  4. Storage

    • хранение в selectedDates
  5. Formatting

    • преобразование в строку для отображения

Схематично:

input (string | number | Date)
        ↓
   normalize
        ↓
     Date
        ↓
 selectedDates[]
        ↓
  formatDate → string

Типы данных input и altInput

Flatpickr поддерживает разделение между реальным значением и отображаемым:

  • input — скрытое или основное значение
  • altInput — пользовательское отображение

Типы данных:

  • input.value всегда string
  • altInput.value также string
  • внутреннее состояние — Date

Пример:

flatpickr("#input", {
  altInput: true,
  altFormat: "F j, Y",
  dateFormat: "Y-m-d"
});

Здесь происходит разделение:

  • пользователь видит: "June 1, 2026"
  • сохраняется: "2026-06-01"
  • внутренняя модель: Date

Работа со временем (time types)

Flatpickr поддерживает время как часть даты, расширяя тип Date.

Используемые значения:

  • часы (H)
  • минуты (i)
  • секунды (S)
flatpickr("#input", {
  enableTime: true,
  dateFormat: "Y-m-d H:i"
});

Тип данных не меняется — всё ещё Date, но с расширенными полями времени.

Важно учитывать:

  • JavaScript Date хранит время в UTC-основанной структуре
  • отображение зависит от локальной таймзоны

Сериализация и обмен данными

При передаче данных во внешние системы Flatpickr не использует собственный формат сериализации. Обычно применяются:

  • ISO строки
  • timestamp
  • пользовательский dateFormat

Пример преобразования:

const iso = selectedDates[0].toISOString();
const ts = selectedDates[0].getTime();

Рекомендуемая модель обмена:

  • backend: timestamp или ISO
  • frontend: Date
  • UI: строка

Типичные ошибки при работе с типами

Несоответствие типов данных приводит к предсказуемым ошибкам:

1. Строка без формата

defaultDate: "01/02/03"

Неоднозначная интерпретация приводит к разным результатам в разных браузерах.

2. Использование секунд вместо миллисекунд

defaultDate: 1717200000 // ошибка

3. Несовместимые массивы в range mode

defaultDate: ["2026-01-10", "2026-01-01"]

Требует внутренней нормализации.

4. Смешивание типов

defaultDate: [new Date(), "2026-01-01", 1717200000000]

Работает, но усложняет предсказуемость логики.


Преобразование и унификация типов

Для стабильной работы с Flatpickr часто используется явное приведение типов:

function normalizeDate(value) {
  return new Date(value);
}

Или более строгий подход:

function toTimestamp(date) {
  return date instanceof Date ? date.getTime() : new Date(date).getTime();
}

Такая унификация особенно важна при интеграции с API и серверными данными.


Взаимосвязь типов и режимов работы

Тип данных в Flatpickr напрямую зависит от режима:

  • singleDate
  • multipleDate[]
  • range[Date, Date | undefined]

Это создаёт динамическую типизацию на уровне конфигурации, что требует аккуратного обращения с результатами selectedDates.


Итоговая модель данных Flatpickr

Внутренняя модель может быть представлена как:

value: string (UI)
selectedDates: Date[]
config input: string | Date | number | array
internal model: Date
output API: Date | string | number[]

Такая многослойная структура обеспечивает гибкость, но требует строгого понимания типов при разработке интеграций и расширений.