В js-joda операции округления времени строятся вокруг принципа усечения (truncation) до заданной временной единицы. Библиотека не делает «математического округления» по умолчанию (вверх/вниз/до ближайшего), а предоставляет строгую детерминированную операцию отсечения младших компонентов.
Основной смысл округления во временных типах — привести значение к более крупной единице измерения: секундам, минутам, часам, дням и т.д., убрав дробную часть времени.
Типичные сценарии:
Ключевой механизм округления в js-joda — метод
truncatedTo(unit).
Он доступен у:
InstantLocalTimeLocalDateTimeZonedDateTimeПринцип работы: все значения младше указанной единицы времени обнуляются.
import { Instant, ChronoUnit } from '@js-joda/core';
const now = Instant.now();
const truncated = now.truncatedTo(ChronoUnit.SECONDS);
Результат:
import { LocalDateTime, ChronoUnit } from '@js-joda/core';
const dt = LocalDateTime.parse('2026-05-25T14:37:52.987');
const result = dt.truncatedTo(ChronoUnit.MINUTES);
Результат:
2026-05-25T14:37
Все значения после минут (секунды и наносекунды) становятся нулевыми.
Операция усечения работает иерархически:
Пример:
dt.truncatedTo(ChronoUnit.HOURS);
2026-05-25T14:00
По сути truncatedTo — это всегда округление
вниз.
Пример:
LocalTime.parse('10:29:59').truncatedTo(ChronoUnit.HOURS);
Результат:
10:00
Никаких правил «0.5 и выше» не применяется. Поведение строго детерминировано: всё, что меньше единицы — отбрасывается.
В js-joda нет встроенного метода округления вверх, но его можно реализовать через комбинацию добавления единицы и усечения.
import { LocalTime, ChronoUnit } from '@js-joda/core';
const time = LocalTime.parse('10:29:10');
const ceil = time
.plusMinutes(1)
.truncatedTo(ChronoUnit.MINUTES);
Логика:
Результат:
10:30
Особенность: такой подход может приводить к переходу через границы
(например, 23:59 → 00:00 следующего дня при работе с
LocalTime через LocalDateTime или
ZonedDateTime).
Для округления «по математическим правилам» требуется вычислить середину единицы измерения.
import { LocalTime, ChronoUnit } from '@js-joda/core';
const time = LocalTime.parse('10:29:40');
const seconds = time.toSecondOfDay();
const rounded = (seconds % 60 >= 30)
? time.plusMinutes(1).truncatedTo(ChronoUnit.MINUTES)
: time.truncatedTo(ChronoUnit.MINUTES);
Результаты:
10:29:20 → 10:2910:29:40 → 10:30Instant представляет момент времени в UTC и особенно
часто используется для округления временных меток в системах логирования
и событий.
import { Instant, ChronoUnit } from '@js-joda/core';
const instant = Instant.parse('2026-05-25T14:37:52.987Z');
const truncated = instant.truncatedTo(ChronoUnit.MINUTES);
Результат:
2026-05-25T14:37:00Z
Все операции выполняются в UTC, независимо от локальной зоны.
ZonedDateTime добавляет слой временной зоны, но принцип
округления сохраняется.
import { ZonedDateTime, ChronoUnit, ZoneId } from '@js-joda/core';
const zdt = ZonedDateTime
.parse('2026-05-25T14:37:52+05:00[Asia/Almaty]');
const result = zdt.truncatedTo(ChronoUnit.HOURS);
Результат:
2026-05-25T14:00+05:00[Asia/Almaty]
Важно:
js-joda поддерживает наносекундную точность, что влияет на поведение округления.
const t = LocalTime.parse('12:15:30.123456789');
const truncated = t.truncatedTo(ChronoUnit.SECONDS);
Результат:
12:15:30
Любая точность ниже секунды полностью удаляется.
Часто округление используется вместе с операциями plus,
minus.
const normalized = dt
.minusMinutes(7)
.truncatedTo(ChronoUnit.HOURS);
Это позволяет «сдвинуть окно» и затем выровнять данные по часам.
truncatedTo не округляет, а отсекает. Ожидание поведения
типа 10:59 → 11:00 приводит к логическим ошибкам.
При переходе между LocalDateTime и
ZonedDateTime округление может давать разные результаты
из-за смещения зоны.
Последовательное усечение:
dt.truncatedTo(ChronoUnit.SECONDS)
.truncatedTo(ChronoUnit.MINUTES);
не эквивалентно одному усечению до минут только в логике анализа, но может влиять на читаемость и намерение кода.
Округление Instant всегда происходит в UTC, что может не
совпадать с локальной логикой приложения.
Округление временных значений применяется в архитектурных сценариях:
Пример ключа для кэша:
const key = dt.truncatedTo(ChronoUnit.MINUTES).toString();
| Метод | Поведение | Применение |
|---|---|---|
| truncatedTo | Округление вниз | логирование, группировка |
| plus + truncatedTo | Округление вверх | интервальные расчёты |
| условное сравнение | округление до ближайшего | аналитика, метрики |
Иногда округление применяется не к моментам времени, а к длительностям:
import { Duration, ChronoUnit } from '@js-joda/core';
const d = Duration.ofSeconds(125);
const normalized = d.truncatedTo(ChronoUnit.MINUTES);
Результат:
PT2M
Остаётся только целая часть минут, секунды отбрасываются.
Выбор единицы влияет на:
Слишком грубое округление приводит к потере детализации, слишком точное — к росту объёма данных.
Округление в js-joda обладает строгой детерминированностью:
Это делает truncatedTo удобным для распределённых
систем, где временные значения должны совпадать между узлами.