Работа с секундами и миллисекундами

Работа с секундами в Cleave.js строится вокруг механизма масок, где каждая часть времени разбивается на логические блоки. Базовый подход заключается в использовании комбинации числовых блоков и разделителей, позволяющих фиксировать структуру ввода без необходимости ручной валидации строки.

Для формата HH:mm:ss используется разбиение на три блока:

  • часы — 2 цифры
  • минуты — 2 цифры
  • секунды — 2 цифры

Конфигурация маски задаётся через blocks и delimiter:

const cleave = new Cleave(input, {
  delimiters: [':', ':'],
  blocks: [2, 2, 2],
  numericOnly: true
});

Такой подход обеспечивает строгую структуру ввода, где секунда всегда занимает фиксированное положение и не может «съехать» в другой сегмент строки.

Контроль допустимого диапазона секунд

Cleave.js не выполняет семантическую валидацию временных значений (например, ограничение 0–59 для секунд). Маска отвечает только за структуру ввода, поэтому контроль диапазонов реализуется отдельно.

Типовой способ — обработка события onChange:

const cleave = new Cleave(input, {
  delimiters: [':', ':'],
  blocks: [2, 2, 2],
  numericOnly: true,
  onValueChanged: (e) => {
    const parts = e.target.rawValue.match(/.{1,2}/g) || [];
    const seconds = parseInt(parts[2] || '0', 10);

    if (seconds > 59) {
      console.log('Некорректное значение секунд');
    }
  }
});

Подобная схема разделяет задачи: Cleave.js отвечает за формат, внешняя логика — за смысловое ограничение.

Миллисекунды как расширение временного формата

Добавление миллисекунд усложняет структуру маски, поскольку появляется дробная часть секунды. Стандартный формат выглядит как HH:mm:ss.SSS.

В Cleave.js это реализуется через дополнительный блок и отдельный разделитель:

const cleave = new Cleave(input, {
  delimiters: [':', ':', '.'],
  blocks: [2, 2, 2, 3],
  numericOnly: true
});

Здесь последний блок фиксирует три цифры, соответствующие миллисекундам. Такой подход сохраняет симметрию структуры времени и упрощает последующую сериализацию значения.

Особенности ввода миллисекунд

При работе с миллисекундами возникает несколько технических нюансов:

  1. Фиксированная длина блока Миллисекунды всегда требуют трёх знаков, даже если значение меньше 100.

  2. Автозаполнение нулями При частичном вводе значение может интерпретироваться как 1100.

  3. Отсутствие семантической проверки Cleave.js не ограничивает диапазон 000–999, поэтому логика интерпретации полностью выносится наружу.

Пример нормализации:

function normalizeMilliseconds(value) {
  return value.padEnd(3, '0').slice(0, 3);
}

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

В некоторых интерфейсах требуется динамическое переключение между форматом HH:mm:ss и HH:mm:ss.SSS. Это достигается пересозданием экземпляра Cleave.js или изменением конфигурации.

Пример переключения:

function setMillisecondsMode(enabled) {
  return new Cleave(input, {
    delimiters: enabled ? [':', ':', '.'] : [':', ':'],
    blocks: enabled ? [2, 2, 2, 3] : [2, 2, 2],
    numericOnly: true
  });
}

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

Работа с пользовательским вводом и rawValue

Для секунд и миллисекунд критично различать отображаемое значение и «сырое» значение (rawValue). Cleave.js хранит очищенную строку без разделителей, что упрощает дальнейшую обработку.

Пример:

const value = cleave.getRawValue();
// пример: "123045678" -> 12:30:45.678

Разбиение rawValue на компоненты позволяет унифицировать обработку времени независимо от формата отображения.

Инкрементальная обработка секунд

При вводе времени посимвольно Cleave.js пересчитывает блоки на каждом изменении. Это важно для секунд, поскольку пользователь может вводить значение не полностью:

  • 101
  • 1212
  • 123 → интерпретация как 12:3

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

Синхронизация с объектом Date

При необходимости преобразования значения в объект Date используется ручной парсинг:

function parseTime(raw) {
  const h = raw.slice(0, 2);
  const m = raw.slice(2, 4);
  const s = raw.slice(4, 6);
  const ms = raw.slice(6, 9) || '000';

  return new Date(0, 0, 0, h, m, s, ms);
}

Такой подход позволяет использовать Cleave.js исключительно как слой ввода, не перегружая его логикой времени.

Ограничения при работе с миллисекундами

При использовании Cleave.js для высокоточного времени важно учитывать архитектурные ограничения:

  • отсутствие встроенной поддержки временных единиц ниже секунд
  • отсутствие проверки переполнения (например, 1000 мс → +1 секунда)
  • невозможность автоматического округления

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

Формирование унифицированных временных строк

Для хранения и передачи данных часто используется единый формат HH:mm:ss.SSS, независимо от того, вводились ли миллисекунды.

Функция нормализации:

function formatTime(h, m, s, ms = 0) {
  return `${String(h).padStart(2, '0')}:` +
         `${String(m).padStart(2, '0')}:` +
         `${String(s).padStart(2, '0')}.` +
         `${String(ms).padStart(3, '0')}`;
}

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

Обработка некорректных значений секунд и миллисекунд

При пользовательском вводе возможны состояния, выходящие за пределы допустимого диапазона. Основной подход — нормализация:

function clampTime({ h, m, s, ms }) {
  s = Math.min(Math.max(s, 0), 59);
  ms = Math.min(Math.max(ms, 0), 999);

  return { h, m, s, ms };
}

Cleave.js не вмешивается в эту логику, сохраняя роль исключительно форматирующего слоя.

Взаимодействие маски и UX при точном вводе времени

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

Поэтому часто применяется комбинированный подход:

  • упрощённая маска для основного ввода (HH:mm:ss)
  • расширенный режим для детализированного времени (HH:mm:ss.SSS)
  • внешняя логика переключения форматов без изменения бизнес-логики