Метод normalize

Назначение нормализации длительности

Метод normalize() относится к объекту Duration в библиотеке Luxon и используется для приведения значений длительности к каноническому виду. Внутренне Duration может хранить значения в произвольной комбинации единиц времени (например, 90 секунд, 120 минут, 1000 миллисекунд), при этом каждая единица не обязана находиться в «нормальном» диапазоне.

Ключевая задача normalize() — перераспределить значения между единицами так, чтобы меньшие единицы «переползали» в старшие (секунды → минуты, минуты → часы и т. д.), формируя согласованное представление длительности.


Поведение метода

normalize() не изменяет исходный объект, а возвращает новый экземпляр Duration с перерасчитанными значениями.

Основные принципы работы:

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

Пример базовой нормализации

import { Duration } from "luxon";

const d = Duration.fromObject({
  minutes: 2,
  seconds: 90
});

const normalized = d.normalize();

console.log(normalized.toObject());
// { minutes: 3, seconds: 30 }

Здесь 90 секунд преобразуются в 1 минуту и 30 секунд, после чего суммируются с исходными 2 минутами.


Нормализация больших значений

const d = Duration.fromObject({
  hours: 1,
  minutes: 125,
  seconds: 3665
});

const normalized = d.normalize();

console.log(normalized.toObject());

Результат:

  • 3665 секунд → 1 час 1 минута 5 секунд
  • 125 минут → 2 часа 5 минут

Итоговая структура:

{
  hours: 4,
  minutes: 6,
  seconds: 5
}

Влияние на структуру единиц

Duration в Luxon не всегда хранит значения строго по классической системе времени. До нормализации возможны состояния:

  • секунды больше 59
  • минуты больше 59
  • часы больше 23
  • смешанные дробные значения

После применения normalize() данные приводятся к стандартной иерархии времени.


Отличие от shiftTo

Метод normalize() часто сравнивается с shiftTo(), однако их семантика различается:

  • normalize() перераспределяет существующие единицы без изменения выбранного набора шкал
  • shiftTo() принудительно переводит длительность в указанные единицы

Пример различия:

const d = Duration.fromObject({ seconds: 3600 });

d.normalize().toObject();
// { hours: 1, minutes: 0, seconds: 0 }

d.shiftTo("minutes").toObject();
// { minutes: 60 }

normalize() стремится к естественной структуре времени, тогда как shiftTo() подчиняется заданной шкале.


Поведение с дробными значениями

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

const d = Duration.fromObject({
  seconds: 90.5
});

const normalized = d.normalize();

console.log(normalized.toObject());
// { seconds: 30, milliseconds: 500, minutes: 1 }

Значение дробной секунды корректно распределяется в миллисекунды и старшие единицы.


Отрицательные длительности

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

const d = Duration.fromObject({
  minutes: -1,
  seconds: -90
});

const normalized = d.normalize();

console.log(normalized.toObject());
// { minutes: -2, seconds: -30 }

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


Ограничения и особенности

  • нормализация не приводит длительность к «календарному контексту» (месяцы и годы не учитывают реальную длину месяцев);
  • результат зависит только от арифметического перераспределения;
  • порядок полей в результате не фиксирован и определяется внутренним представлением Luxon;
  • метод не мутирует исходный объект, что важно при цепочках вызовов.

Использование в цепочках преобразований

normalize() часто применяется после операций сложения или создания сложных длительностей:

const a = Duration.fromObject({ minutes: 50 });
const b = Duration.fromObject({ seconds: 200 });

const result = a.plus(b).normalize();

console.log(result.toObject());
// { minutes: 53, seconds: 20 }

Без нормализации результат может содержать «переполненные» значения, неудобные для отображения или дальнейших вычислений.


Внутренний смысл нормализации

Логика метода основана на приведении структуры длительности к инвариантному виду:

  • сумма всех единиц остаётся неизменной;
  • перераспределение выполняется по правилам базовых коэффициентов времени;
  • итоговая форма становится детерминированной и предсказуемой при сериализации и сравнении.