Period в js-joda представляет календарную
длительность, выраженную в годах, месяцах и днях. Такой тип
интервала зависит от календарной системы и не фиксирован в абсолютных
секундах: один месяц может содержать разное число дней, один год — 365
или 366 дней.
Основной набор фабричных методов:
Period.of(years, months, days)Period.ofYears(years)Period.ofMonths(months)Period.ofWeeks(weeks)Period.ofDays(days)Примеры:
Period.of(1, 2, 10) // 1 год, 2 месяца, 10 дней
Period.ofYears(3) // 3 года
Period.ofMonths(6) // 6 месяцев
Period.ofWeeks(2) // 14 дней (нормализуется в дни)
Period.ofDays(5) // 5 дней
Неделя в Period всегда преобразуется в дни, поскольку
модель не хранит отдельного поля для недель.
Метод Period.parse() разбирает ISO-8601 строку:
Period.parse("P1Y2M3D")
Period.parse("P10D")
Period.parse("P2W") // 14 дней
Формат строго соответствует ISO:
P — префикс периодаY — годыM — месяцыW — неделиD — дниМетоды чтения внутренних значений:
getYears()getMonths()getDays()const p = Period.of(2, 5, 12);
p.getYears(); // 2
p.getMonths(); // 5
p.getDays(); // 12
Важно учитывать, что Period не нормализует месяцы в годы
автоматически, кроме случаев явного вызова
normalized().
Метод normalized() приводит месяцы к диапазону 0–11,
перераспределяя их в годы:
Period.of(1, 15, 0).normalized()
// 2 года, 3 месяца, 0 дней
Логика основана на том, что 12 месяцев = 1 год.
Поддерживаются операции:
plus(otherPeriod)minus(otherPeriod)multipliedBy(scalar)negated()const p1 = Period.of(1, 2, 10);
const p2 = Period.of(0, 3, 5);
p1.plus(p2); // 1Y 5M 15D
p1.minus(p2); // 1Y -1M 5D
p1.multipliedBy(2); // 2Y 4M 20D
p1.negated(); // -1Y -2M -10D
isZero() — период равен нулюisNegative() — хотя бы один компонент
отрицательныйPeriod.of(0, 0, 0).isZero(); // true
Period.of(0, -1, 0).isNegative(); // true
Period применяется к LocalDate:
plus(period)minus(period)plusYears, plusMonths,
plusDays как эквиваленты через Perioddate.plus(Period.ofMonths(2))
date.minus(Period.ofDays(10))
Поведение зависит от календарной логики: добавление месяцев может менять день месяца.
Duration представляет точный временной
интервал, основанный на фиксированных единицах времени: секунды
и наносекунды. В отличие от Period, он не зависит от
календаря.
Основные фабричные методы:
Duration.ofDays(days)Duration.ofHours(hours)Duration.ofMinutes(minutes)Duration.ofSeconds(seconds)Duration.ofMillis(millis)Duration.ofNanos(nanos)Duration.ofHours(5)
Duration.ofMinutes(90)
Duration.ofSeconds(30)
Duration.ofMillis(1500)
Все методы преобразуются в секунды и наносекунды внутри.
Duration.parse("PT20S")
Duration.parse("PT15M")
Duration.parse("PT1H")
Duration.parse("PT2H30M")
Формат:
P — префикс периодаT — начало временной частиH, M, S — часы, минуты,
секундыgetSeconds()getNano()const d = Duration.ofSeconds(5, 500000000);
d.getSeconds(); // 5
d.getNano(); // 500000000
Важно: Duration хранит нормализованное значение, где
наносекунды всегда в диапазоне 0–999,999,999.
Поддерживаются операции:
plus(duration)minus(duration)multipliedBy(scalar)dividedBy(divisor)negated()abs()const d1 = Duration.ofMinutes(10);
const d2 = Duration.ofSeconds(30);
d1.plus(d2); // PT10M30S
d1.minus(d2); // PT9M30S
d1.multipliedBy(2); // PT20M
d1.dividedBy(2); // PT5M
d1.negated(); // отрицательная длительность
d1.abs(); // абсолютное значение
isZero() — нулевая длительностьisNegative() — отрицательная длительностьDuration.ofSeconds(0).isZero(); // true
Duration.ofSeconds(-5).isNegative(); // true
toMillis()toSeconds()toMinutes()toHours()Duration.ofSeconds(90).toMinutes(); // 1 (с округлением вниз)
Duration.ofMillis(1500).toSeconds(); // 1
Преобразования выполняются с усечением дробной части.
Duration часто применяется к Instant:
plus(duration)minus(duration)plusSeconds, plusMillis и т.д. через
Durationinstant.plus(Duration.ofHours(1))
instant.minus(Duration.ofMinutes(15))
Также используется в вычислении разницы:
Duration.between(start, end)Duration.between(instant1, instant2)
Результат может быть отрицательным, если второй момент раньше первого.
Period — календарные значения (годы, месяцы, дни)Duration — абсолютное время (секунды, наносекунды)Period зависит от календарной структурыDuration независим от календаряPeriod:
Duration:
InstantДобавление Period к дате:
LocalDate.of(2024, 1, 31).plus(Period.ofMonths(1))
// может дать 2024-02-29 или 2024-02-28
Добавление Duration к времени:
Instant.now().plus(Duration.ofSeconds(30))
Результат всегда детерминирован и не зависит от календаря.
normalized()date
.plus(Period.ofMonths(2))
.plus(Period.ofDays(10))
.minus(Period.ofYears(1))
Каждая операция изменяет календарную позицию, сохраняя относительную структуру.
instant
.plus(Duration.ofSeconds(30))
.plus(Duration.ofMinutes(5))
.minus(Duration.ofMillis(500))
Все операции эквивалентны суммированию фиксированных временных единиц.
Отрицательность может быть неоднородной:
Period.of(1, -2, 3)
Каждое поле интерпретируется отдельно.
Отрицательность глобальна:
Duration.ofSeconds(-10)
Нельзя иметь «частично отрицательную» длительность — знак распространяется на всё значение.
Period и Duration разделяют модель времени
на два слоя:
LocalDate, Period)Instant, Duration)Такое разделение устраняет неоднозначности, характерные для традиционных Date API в JavaScript, где месяцы, дни и часы смешаны в одной модели без строгой семантики.