В библиотеке Luxon работа со временем строится вокруг строго определённой системы единиц, в которой базовыми сущностями выступают календарные и абсолютные интервалы. Поддерживаются как фиксированные единицы времени (миллисекунды, секунды, минуты, часы), так и календарные (дни, недели, месяцы, годы), поведение которых зависит от контекста календаря и временной зоны.
Luxon оперирует следующими основными единицами:
Эти единицы применяются в объектах типа Duration, а
также при арифметике дат через DateTime.
Ключевая особенность системы заключается в разделении:
Объект Duration представляет длительность, выраженную в
одной или нескольких единицах.
Создание через объектную форму:
import { Duration } from "luxon";
const d = Duration.fromObject({
hours: 2,
minutes: 30
});
Внутренне Luxon хранит каждую единицу отдельно, не сводя всё к одной шкале до момента явной конвертации.
При необходимости Luxon может привести разнородные единицы к согласованному виду:
const d = Duration.fromObject({
minutes: 120,
hours: 1
}).normalize();
Нормализация перераспределяет значения между единицами, сохраняя корректную иерархию (например, 120 минут превращаются в 2 часа).
Метод as выполняет пересчёт длительности в одну
выбранную единицу:
const d = Duration.fromObject({
hours: 2,
minutes: 30
});
d.as("minutes"); // 150
Важно учитывать, что результат зависит от типа единиц:
d.shiftTo("hours", "minutes").toObject();
shiftTo перераспределяет длительность в указанные
единицы, сохраняя общую величину.
Пример поведения:
исходно: 90 minutes
после shiftTo(“hours”, “minutes”):
Календарные единицы обладают переменной длиной:
Из-за этого Luxon не выполняет прямого преобразования:
Duration.fromObject({ months: 1 }).as("days");
Результат зависит от контекста, если он задан через дату, иначе используется усреднённая модель.
DateTime поддерживает арифметику с использованием
Duration.
import { DateTime, Duration } from "luxon";
const dt = DateTime.local();
const updated = dt.plus({ days: 3, hours: 5 });
Каждая единица интерпретируется согласно календарю конкретного момента времени.
const earlier = dt.minus({
weeks: 2,
minutes: 15
});
Календарные единицы учитывают особенности временной зоны и переходов (например, DST).
Объект Interval описывает промежуток между двумя точками
во времени.
import { Interval, DateTime } from "luxon";
const start = DateTime.local();
const end = start.plus({ hours: 4 });
const interval = Interval.fromDateTimes(start, end);
interval.length("hours"); // 4
Поддерживаются те же единицы, что и в Duration, но интервал всегда вычисляется между двумя моментами времени.
Luxon поддерживает ISO 8601 длительности:
const d = Duration.fromISO("PT2H30M");
Структура ISO:
Также поддерживается преобразование обратно:
d.toISO(); // "PT2H30M"
d.toObject();
Возвращает разложение по единицам:
{
hours: 2,
minutes: 30
}
d.toHuman();
Формирует строку на основе локали и единиц:
Luxon допускает дробные значения в длительностях:
Duration.fromObject({
hours: 1.5
});
Внутренне такие значения могут нормализоваться:
При конвертации дробные части перераспределяются в младшие единицы.
Для анализа длительностей используется приведение к общей шкале:
const a = Duration.fromObject({ hours: 2 });
const b = Duration.fromObject({ minutes: 90 });
a.equals(b); // false без нормализации
После нормализации:
a.normalize().equals(b.normalize()); // true
При использовании DateTime единицы интерпретируются в
контексте зоны:
Пример:
dt.setZone("Europe/Berlin").plus({ days: 1 });
Фактическая длительность в часах может отличаться от 24.
Календарные единицы обрабатываются через привязку к конкретной дате:
DateTime.local(2024, 1, 31).plus({ months: 1 });
Результат зависит от календарных правил:
Luxon разделяет единицы на два класса:
Fixed units
Calendar units
Такое разделение определяет стратегию вычислений:
DateTime.При смешивании единиц возможны потери точности:
Duration.fromObject({
months: 1,
days: 15
}).as("days");
Результат не является фиксированным значением, так как зависит от длины месяца.
Luxon может приводить длительность к каноническому виду:
Duration.fromObject({
minutes: 120
}).toObject();
После нормализации:
Канонизация обеспечивает минимальное число активных единиц.