Стандартный объект Date в JavaScript хранит время в
миллисекундах. Это фундаментальное ограничение платформы, влияющее на
любые операции с датой и временем. Библиотека js-joda наследует часть
этих ограничений при взаимодействии с системным временем, однако внутри
собственной модели предоставляет существенно более строгую и
предсказуемую работу.
Основная проблема Date заключается в том, что:
js-joda устраняет большинство этих проблем за счёт:
Одной из ключевых особенностей js-joda является
поддержка наносекунд (nanoseconds).
В отличие от стандартного Date, библиотека позволяет
хранить:
const { LocalTime } = require('@js-joda/core');
const time = LocalTime.of(12, 30, 15, 123456789);
console.log(time.toString());
// 12:30:15.123456789
Последний аргумент — количество наносекунд.
Несмотря на поддержку наносекунд, важно понимать различие между:
js-joda способен хранить значения до наносекунды:
const time = LocalTime.parse('10:15:30.999999999');
При использовании:
Instant.now()
точность зависит от платформы JavaScript.
В большинстве сред:
Следовательно, объект может хранить наносекунды, но источник времени не всегда способен их предоставить.
Каждый временной тип в js-joda имеет строгие
границы.
LocalDate.MIN
LocalDate.MAX
Поддерживаемый диапазон:
-999999999-01-01
до
+999999999-12-31
Это значительно больше диапазона стандартного Date.
Время суток ограничено:
00:00:00.000000000
—
23:59:59.999999999
Попытка создать невалидное время вызывает исключение.
LocalTime.of(25, 0);
Результат:
DateTimeException
Библиотека строго валидирует значения.
LocalDate.of(2025, 13, 1);
LocalDate.of(2025, 2, 30);
LocalTime.of(10, 0, 0, 1000000000);
Во всех случаях будет выброшено исключение.
При выходе за допустимый диапазон библиотека генерирует ошибку.
LocalDate.MAX.plusDays(1);
Результат:
DateTimeException
Это предотвращает скрытые ошибки вычислений.
Тип Instant представляет точку времени относительно
UTC.
const { Instant } = require('@js-joda/core');
const instant = Instant.now();
Диапазон также ограничен:
Instant.MIN
Instant.MAX
Попытка выйти за пределы вызывает исключение.
Особое внимание требуется при конвертации между:
Instant;Date;const date = new Date();
При преобразовании:
Instant.ofEpochMilli(date.getTime());
наносекундная часть теряется.
const instant = Instant.parse(
'2025-01-01T10:15:30.123456789Z'
);
console.log(instant.toEpochMilli());
Результат:
1735726530123
Сохраняются только миллисекунды.
Формат JSON не содержит встроенного типа даты.
Обычно используется ISO-строка:
{
"createdAt": "2025-01-01T10:15:30.123456789Z"
}
Однако:
JavaScript использует тип Number, основанный на IEEE
754.
Из-за этого возможны ограничения при работе с большими timestamp.
Number.MAX_SAFE_INTEGER
Безопасный диапазон целых чисел ограничен:
9007199254740991
Это влияет на:
Хранение времени в наносекундах как одного числа небезопасно:
const nanos =
1735726530123456789;
Такое значение может потерять точность.
Поэтому js-joda использует:
Это повторяет архитектуру Java Time API.
Для полноценной работы с временными зонами требуется:
@js-joda/timezone
Без этого доступны только:
Не каждая строка является корректной зоной.
ZoneId.of('Mars/Base1');
Результат:
DateTimeException
Переходы летнего времени создают сложные ситуации.
2025-03-30 02:30
В некоторых зонах такого времени не существует.
Осенью один и тот же локальный момент может встречаться дважды.
const zoned =
ZonedDateTime.parse(
'2025-10-26T02:30+02:00[Europe/Berlin]'
);
Необходимо учитывать:
База временных зон IANA периодически обновляется.
Следствия:
Высокая точность имеет цену.
Операции js-joda обычно:
Date;Каждая операция создаёт новый объект.
const next =
date.plusDays(1);
Исходный объект не изменяется.
Преимущества:
Недостатки:
Некоторые типы нельзя напрямую сериализовать.
JSON.stringify({
date: LocalDate.now()
});
Результат зависит от реализации объекта.
Чаще используется явное преобразование:
date.toString()
Формат даты должен строго соответствовать шаблону.
LocalDate.parse('01-12-2025');
Результат:
DateTimeParseException
По умолчанию библиотека ориентирована на ISO-8601.
Корректный формат:
2025-12-01
Некорректный:
01/12/2025
Для сложного форматирования требуется пакет:
@js-joda/locale
Без него возможности форматирования ограничены.
При длительных вычислениях возможно накопление ошибок, если используется внешний источник времени.
setInterval(() => {
// дрейф таймера
}, 1000);
js-joda не устраняет ограничения JavaScript timers:
Системное время может:
Для измерения интервалов предпочтительнее:
performance.now();Instant.now() отражает именно системное время.
Библиотека не поддерживает високосные секунды как отдельные значения.
23:59:60
Такое значение считается некорректным.
js-joda использует:
Не поддерживаются:
Некоторые сторонние библиотеки ожидают объект Date.
Поэтому может потребоваться конвертация:
const jsDate =
new Date(
instant.toEpochMilli()
);
При этом теряются:
Поддержка зависит от:
В старых окружениях возможны:
Разные версии Node.js содержат:
Из-за этого один и тот же код может выдавать различные результаты на разных серверах.
const millis =
instant.toEpochMilli();
Значение:
2025-01-01T10:15:30.123999999Z
после преобразования станет:
2025-01-01T10:15:30.123Z
Точность необратимо теряется.
Для высокоточных систем обычно используются:
2025-01-01T10:15:30.123456789Z
{
epochSecond: 1735726530,
nano: 123456789
}
Все значения сохраняются в UTC, а локальная зона применяется только на уровне отображения.
Объекты нельзя сравнивать оператором ===.
date1 === date2
date1.equals(date2)
или:
date1.compareTo(date2)
Некоторые операции невозможны без явного указания единицы времени.
date.plus(1);
Некорректно.
Необходимо:
date.plusDays(1);
или:
date.plus(1, ChronoUnit.DAYS);
Тип Duration хранит:
Тип Period хранит:
Эти типы нельзя смешивать без понимания календарной природы времени.
Period.ofMonths(1)
не эквивалентен:
Duration.ofDays(30)
Поскольку месяцы имеют разную длину.
Duration обеспечивает высокую точность интервалов.
1 =1,000,000,000
Пример:
const duration =
Duration.ofNanos(1);
Однако фактическая точность исполнения зависит от платформы выполнения JavaScript.
Многие СУБД ограничивают точность:
| СУБД | Точность |
|---|---|
| PostgreSQL | микросекунды |
| MySQL | миллисекунды/микросекунды |
| SQLite | часто строки |
| MongoDB | миллисекунды |
При сохранении объектов js-joda часть данных может
теряться.
LocalDateTime.now()
и:
Instant.now()
представляют разные концепции.
new Date().getTime()
не подходит для наносекундных операций.
Добавление суток:
plusDays(1)
не всегда означает:
24 часа
из-за переходов времени.
Большие значения могут терять точность.
Безопаснее: