В библиотеке Luxon работа с длительностями основана на объекте
Duration, который хранит временной интервал в
структурированном виде: дни, часы, минуты, секунды, миллисекунды и
другие единицы. Однако внутренняя структура не всегда удобна для
вычислений или сравнения. Для преобразования длительности в числовое
значение в конкретной единице используется метод as.
Метод позволяет получить эквивалент длительности в выбранной шкале времени без изменения исходного объекта.
duration.as(unit)
unit — строка, обозначающая единицу измерения
времениМетод as работает с набором стандартных временных единиц
Luxon:
"milliseconds""seconds""minutes""hours""days""weeks""months""years"Каждая единица пересчитывается на основе внутренних правил Luxon, учитывающих календарную сложность (например, месяцы и годы зависят от контекста).
Объект Duration хранит данные в нормализованной форме,
но as всегда возвращает итоговое значение в одной выбранной
единице, агрегируя все составляющие.
Пример:
import { Duration } from "luxon";
const duration = Duration.fromObject({
hours: 2,
minutes: 30
});
console.log(duration.as("hours"));
// 2.5
Здесь минуты преобразуются в долю часа.
Один и тот же объект может быть выражен в различных масштабах.
const duration = Duration.fromObject({
minutes: 90
});
console.log(duration.as("hours"));
// 1.5
console.log(duration.as("minutes"));
// 90
console.log(duration.as("seconds"));
// 5400
Метод не изменяет объект, а только интерпретирует его в другой единице измерения.
При наличии нескольких компонентов Luxon автоматически суммирует их с учетом коэффициентов.
const duration = Duration.fromObject({
days: 1,
hours: 12
});
console.log(duration.as("hours"));
// 36
Здесь:
Некоторые единицы имеют переменную длину:
Их преобразование зависит от контекста календаря и может быть приблизительным.
const duration = Duration.fromObject({
months: 1
});
console.log(duration.as("days"));
// приблизительно 30 или 31 или 28/29 (в зависимости от контекста)
Luxon опирается на стандартную календарную модель, но точность зависит от того, как интерпретируется месяц.
Если длительность создана с выходом за пределы единицы, Luxon может
нормализовать значения, но as всегда возвращает итоговую
сумму.
const duration = Duration.fromObject({
hours: 25
});
console.log(duration.as("days"));
// 1.041666...
Несмотря на то что 25 часов формально не нормализованы в объекте, пересчёт выполняется корректно.
Duration может содержать отрицательные значения, и метод
as сохраняет знак результата.
const duration = Duration.fromObject({
minutes: -90
});
console.log(duration.as("hours"));
// -1.5
Отрицательная длительность обрабатывается симметрично положительной.
Luxon допускает дробные компоненты длительности, и as
учитывает их без округления.
const duration = Duration.fromObject({
seconds: 90.5
});
console.log(duration.as("minutes"));
// 1.508333...
Точность сохраняется на уровне IEEE 754 floating point.
toObject и
toISOМетод as принципиально отличается от методов
сериализации:
toObject() возвращает структуруtoISO() возвращает строкуas() возвращает числовую интерпретациюПример:
const duration = Duration.fromObject({
hours: 2,
minutes: 30
});
console.log(duration.toObject());
// { hours: 2, minutes: 30 }
console.log(duration.toISO());
// "PT2H30M"
console.log(duration.as("hours"));
// 2.5
Метод as часто применяется для арифметических операций,
где требуется единая шкала.
const work = Duration.fromObject({ hours: 8 });
const breakTime = Duration.fromObject({ minutes: 30 });
const total = work.plus(breakTime);
console.log(total.as("hours"));
// 8.5
Здесь итоговая длительность легко переводится в числовое значение для расчётов.
Поскольку as возвращает число, его удобно использовать
для сравнения.
const a = Duration.fromObject({ minutes: 90 });
const b = Duration.fromObject({ hours: 1 });
console.log(a.as("minutes") > b.as("minutes"));
// true
Такой подход устраняет необходимость ручной нормализации.
При работе с большими значениями и дробными коэффициентами возможны незначительные погрешности, характерные для чисел с плавающей точкой.
const duration = Duration.fromObject({
years: 1
});
console.log(duration.as("milliseconds"));
// 31557600000 (примерное значение)
Эта особенность связана не с Luxon, а с моделью представления времени в JavaScript.
Метод as сам по себе не зависит от временной зоны.
Однако исходная длительность может быть получена из вычислений, где зона
влияет на результат (например, разница дат).
import { DateTime, Duration } from "luxon";
const start = DateTime.fromISO("2024-01-01T00:00:00");
const end = DateTime.fromISO("2024-01-02T06:00:00");
const diff = end.diff(start);
console.log(diff.as("hours"));
// 30
Метод можно использовать внутри цепочек преобразований, комбинируя с
plus, minus, mapUnits.
const duration = Duration.fromObject({ hours: 10 })
.plus({ minutes: 15 })
.minus({ seconds: 30 });
console.log(duration.as("hours"));
// 10.241666...
Если передана неподдерживаемая единица, результат становится
некорректным или NaN.
const duration = Duration.fromObject({ hours: 1 });
console.log(duration.as("lightyears"));
// NaN
Luxon не выполняет автоматическое приведение произвольных единиц.
as в
архитектуре DurationМетод выполняет роль универсального “редуктора” структуры длительности к числу. Он устраняет необходимость вручную преобразовывать компоненты и обеспечивает единый механизм интерпретации времени.
Основные свойства поведения:
Метод применяется в задачах:
Типичный пример:
function averageDuration(durations) {
const total = durations.reduce((acc, d) => acc + d.as("seconds"), 0);
return total / durations.length;
}
const duration = Duration.fromObject({});
console.log(duration.as("seconds"));
// 0
Пустой объект интерпретируется как нулевая длительность.
При последовательных преобразованиях может возникать накопление погрешности:
let d = Duration.fromObject({ seconds: 1 });
for (let i = 0; i < 1000; i++) {
d = d.plus({ milliseconds: 1 });
}
console.log(d.as("seconds"));
Результат может содержать незначительные отклонения от ожидаемого значения из-за бинарной арифметики.