Класс Period из библиотеки js-joda предназначен для
представления календарного периода в терминах:
Period используется для работы именно с календарными
величинами, а не с точным временем. В отличие от Duration,
который измеряет количество секунд и наносекунд, Period
оперирует календарными единицами, зависящими от структуры календаря.
Примеры:
const { Period } = require('@js-joda/core')
ofБазовый способ создания периода — метод
Period.of(years, months, days).
const period = Period.of(1, 6, 15)
console.log(period.toString())
Результат:
P1Y6M15D
Формат соответствует стандарту ISO-8601:
| Обозначение | Значение |
|---|---|
P |
начало периода |
Y |
годы |
M |
месяцы |
D |
дни |
ofYearsconst period = Period.ofYears(3)
console.log(period.toString())
Результат:
P3Y
ofMonthsconst period = Period.ofMonths(8)
console.log(period.toString())
Результат:
P8M
ofDaysconst period = Period.ofDays(21)
console.log(period.toString())
Результат:
P21D
ZEROКонстанта Period.ZERO представляет пустой период.
const period = Period.ZERO
console.log(period.toString())
Результат:
P0D
Проверка:
console.log(period.isZero())
Результат:
true
parsePeriod.parse() преобразует ISO-строку в объект
периода.
const period = Period.parse('P2Y5M10D')
console.log(period.years())
console.log(period.months())
console.log(period.days())
Результат:
2
5
10
const period = Period.of(4, 7, 12)
console.log(period.years())
console.log(period.months())
console.log(period.days())
Period чаще всего используется вместе с
LocalDate.
const { LocalDate, Period } = require('@js-joda/core')
const date = LocalDate.parse('2025-01-10')
const period = Period.of(1, 2, 15)
const result = date.plus(period)
console.log(result.toString())
Результат:
2026-03-25
Происходит последовательное добавление:
const date = LocalDate.parse('2025-08-20')
const period = Period.ofMonths(3)
const result = date.minus(period)
console.log(result.toString())
Результат:
2025-05-20
betweenМетод Period.between(start, end) вычисляет календарную
разницу между датами.
const start = LocalDate.parse('2020-01-15')
const end = LocalDate.parse('2023-04-20')
const period = Period.between(start, end)
console.log(period.toString())
Результат:
P3Y3M5D
Period.between() использует календарную арифметику.
const start = LocalDate.parse('2025-01-31')
const end = LocalDate.parse('2025-02-28')
const period = Period.between(start, end)
console.log(period.toString())
Результат:
P28D
Причина заключается в том, что февраль не содержит 31 числа.
Period может содержать отрицательные значения.
const period = Period.of(-1, -2, -10)
console.log(period.toString())
Результат:
P-1Y-2M-10D
isNegativeconst period = Period.ofDays(-5)
console.log(period.isNegative())
Результат:
true
isZeroconst period = Period.of(0, 0, 0)
console.log(period.isZero())
Объекты Period неизменяемы.
Каждая операция создаёт новый объект.
plusYearsconst period = Period.ofMonths(5)
const result = period.plusYears(2)
console.log(result.toString())
Результат:
P2Y5M
plusMonthsconst period = Period.ofYears(1)
const result = period.plusMonths(9)
console.log(result.toString())
Результат:
P1Y9M
plusDaysconst period = Period.ofYears(1)
const result = period.plusDays(20)
console.log(result.toString())
Результат:
P1Y20D
minusYearsconst period = Period.ofYears(5)
const result = period.minusYears(2)
console.log(result.toString())
Результат:
P3Y
minusMonthsconst period = Period.ofMonths(10)
const result = period.minusMonths(4)
console.log(result.toString())
Результат:
P6M
minusDaysconst period = Period.ofDays(30)
const result = period.minusDays(12)
console.log(result.toString())
Результат:
P18D
negatedconst period = Period.of(1, 2, 3)
const result = period.negated()
console.log(result.toString())
Результат:
P-1Y-2M-3D
absconst period = Period.of(-1, -3, -15)
const result = period.abs()
console.log(result.toString())
Результат:
P1Y3M15D
multipliedByconst period = Period.of(1, 2, 10)
const result = period.multipliedBy(3)
console.log(result.toString())
Результат:
P3Y6M30D
normalizedМетод преобразует месяцы в годы, если количество месяцев превышает 12.
const period = Period.of(1, 15, 10)
const result = period.normalized()
console.log(result.toString())
Результат:
P2Y3M10D
normalizedНормализация касается только месяцев и лет.
Дни не преобразуются в месяцы.
const period = Period.of(0, 0, 90)
console.log(period.normalized().toString())
Результат:
P90D
Причина связана с тем, что длина месяца различается.
У Period отсутствует прямое сравнение через:
isBefore;isAfter.Причина заключается в неоднозначности календарных величин.
Например:
equalsconst p1 = Period.of(1, 2, 3)
const p2 = Period.of(1, 2, 3)
console.log(p1.equals(p2))
Результат:
true
toStringconst period = Period.of(2, 5, 7)
console.log(period.toString())
Результат:
P2Y5M7D
Допустимы смешанные значения.
const period = Period.of(1, -2, 15)
console.log(period.toString())
Результат:
P1Y-2M15D
Подобные конструкции встречаются редко, но библиотека их поддерживает.
LocalDateconst { LocalDate, Period } = require('@js-joda/core')
const dates = [
LocalDate.parse('2025-01-01'),
LocalDate.parse('2025-02-01'),
LocalDate.parse('2025-03-01')
]
const period = Period.ofMonths(1)
const updated = dates.map(date => date.plus(period))
updated.forEach(date => {
console.log(date.toString())
})
const start = LocalDate.parse('2025-01-15')
const paymentPeriod = Period.ofMonths(1)
for (let i = 0; i < 6; i++) {
const paymentDate = start.plus(paymentPeriod.multipliedBy(i))
console.log(paymentDate.toString())
}
Результат:
2025-01-15
2025-02-15
2025-03-15
2025-04-15
2025-05-15
2025-06-15
const birthDate = LocalDate.parse('1995-06-10')
const currentDate = LocalDate.parse('2026-05-01')
const age = Period.between(birthDate, currentDate)
console.log(age.years())
Period и DurationPeriod |
Duration |
|---|---|
| Календарные единицы | Точное время |
| Годы, месяцы, дни | Секунды, наносекунды |
| Зависит от календаря | Независим от календаря |
| Используется с датами | Используется со временем |
PeriodPeriod подходит для:
Period
использовать нельзяPeriod не подходит для:
Для таких задач применяется Duration.
Строка:
P2Y4M6D
Расшифровывается так:
| Компонент | Значение |
|---|---|
P |
period |
2Y |
2 года |
4M |
4 месяца |
6D |
6 дней |
Допустимо указывать только отдельные компоненты.
Period.parse('P5D')
Period.parse('P2M')
Period.parse('P1Y')
const start = LocalDate.parse('2024-02-29')
const result = start.plus(Period.ofYears(1))
console.log(result.toString())
Результат:
2025-02-28
При отсутствии 29 февраля дата корректируется автоматически.
const date = LocalDate.parse('2025-01-31')
const result = date.plusMonths(1)
console.log(result.toString())
Результат:
2025-02-28
Period и методы календарной арифметики учитывают
реальные границы месяцев.
Все объекты Period являются immutable-объектами.
Операции:
Пример:
const original = Period.ofMonths(3)
const changed = original.plusDays(5)
console.log(original.toString())
console.log(changed.toString())
Результат:
P3M
P3M5D
const subscriptionStart = LocalDate.parse('2025-01-10')
const subscriptionPeriod = Period.ofMonths(12)
const expirationDate = subscriptionStart.plus(subscriptionPeriod)
console.log(expirationDate.toString())
const employmentDate = LocalDate.parse('2025-03-01')
const probation = Period.ofMonths(3)
const probationEnd = employmentDate.plus(probation)
console.log(probationEnd.toString())
const vacationStart = LocalDate.parse('2025-07-01')
const vacationLength = Period.ofDays(14)
const vacationEnd = vacationStart.plus(vacationLength)
console.log(vacationEnd.toString())