Создание Instant из различных источников

Instant в js-joda представляет момент времени на временной шкале в формате UTC, измеряемый в наносекундах от эпохи Unix (1970-01-01T00:00:00Z). Ключевая особенность этого типа — полная независимость от часовых поясов и календарных систем: он фиксирует только абсолютную точку во времени.

Любое создание Instant сводится к преобразованию различных источников данных в универсальное представление времени относительно эпохи.


Текущее системное время

Наиболее прямой способ получить Instant — использование текущего времени системных часов.

import { Instant } from "@js-joda/core";

const now = Instant.now();

Метод Instant.now() обращается к системному источнику времени и формирует объект, содержащий текущее UTC-время. Важно учитывать, что результат зависит от системных часов окружения, а не от логики js-joda.

В средах с поддержкой альтернативных источников времени (например, тестирование) возможно использование кастомных clock-реализаций через Clock, однако базовый вариант всегда опирается на системное время.


Создание из эпохи Unix в миллисекундах

Одним из наиболее распространённых источников времени в JavaScript является количество миллисекунд с начала Unix-эпохи. Для преобразования этого значения используется метод:

const instant = Instant.ofEpochMilli(1710000000000);

Данный метод принимает целое число миллисекунд и преобразует его в Instant. Он особенно полезен при работе с:

  • Date.now()
  • timestamp из API
  • логами и событиями систем

Пример интеграции с нативным Jav * aScript:

const timestamp = Date.now();
const instant = Instant.ofEpochMilli(timestamp);

Создание из секунд эпохи Unix

Для более низкоуровневого представления времени используется метод, оперирующий секундами и наносекундами:

const instant = Instant.ofEpochSecond(1710000000);

Метод также поддерживает дополнительную точность в виде наносекундной поправки:

const instant = Instant.ofEpochSecond(1710000000, 500000000);

Здесь:

  • первый аргумент — секунды с начала эпохи
  • второй — дополнительная наносекундная часть (0–999_999_999)

Этот способ часто применяется в системах, где время хранится в формате Unix timestamp с высокой точностью.


Парсинг строкового представления

Instant поддерживает создание из строк, соответствующих формату ISO-8601 UTC.

const instant = Instant.parse("2024-01-01T10:15:30Z");

Строка должна включать:

  • дату
  • время
  • обязательный указатель зоны Z (UTC)

Допустимы также форматы с дробной частью секунд:

const instant = Instant.parse("2024-01-01T10:15:30.123Z");

Парсинг строго соответствует спецификации ISO-8601, любые отклонения от формата приводят к ошибке разбора.


Преобразование из временных объектов через TemporalAccessor

Instant может быть создан из любого объекта, реализующего интерфейс TemporalAccessor. Это обеспечивает универсальность при работе с другими типами js-joda.

import { LocalDateTime, ZoneOffset, Instant } from "@js-joda/core";

const ldt = LocalDateTime.of(2024, 1, 1, 12, 0);
const instant = Instant.from(ldt.atZone(ZoneOffset.UTC));

Важный момент: LocalDateTime не содержит информации о зоне, поэтому преобразование требует явного указания ZoneOffset.

Аналогично можно работать с ZonedDateTime:

import { ZonedDateTime } from "@js-joda/core";

const zdt = ZonedDateTime.now();
const instant = Instant.from(zdt);

В этом случае временная зона уже встроена в объект, и преобразование происходит напрямую.


Преобразование через ZonedDateTime

ZonedDateTime является одним из наиболее естественных источников для Instant, поскольку уже содержит полное представление даты, времени и зоны.

const instant = zdt.toInstant();

Этот метод эквивалентен использованию Instant.from(zdt) и является более читаемым в контексте цепочек преобразований.


Конвертация из LocalDateTime с указанием зоны

LocalDateTime требует дополнительной информации о смещении относительно UTC.

import { LocalDateTime, ZoneOffset, Instant } from "@js-joda/core";

const ldt = LocalDateTime.of(2024, 5, 10, 18, 30);

const instant = ldt
  .atOffset(ZoneOffset.ofHours(3))
  .toInstant();

Здесь процесс включает два шага:

  • привязка локального времени к смещению (OffsetDateTime)
  • преобразование в абсолютный момент времени

Работа с миллисекундами через Date

В экосистеме JavaScript часто требуется взаимодействие с нативным Date. Преобразование выполняется через epoch-milliseconds:

const date = new Date();
const instant = Instant.ofEpochMilli(date.getTime());

Обратное преобразование:

const millis = instant.toEpochMilli();
const date = new Date(millis);

Таким образом обеспечивается совместимость между js-joda и стандартным API JavaScript.


Разбор граничных значений эпохи

Instant поддерживает диапазон значений значительно шире, чем стандартный Date. При работе с epoch-значениями следует учитывать:

  • переполнение Number.MAX_SAFE_INTEGER
  • потерю точности при больших значениях миллисекунд
  • предпочтение секундному формату при системных вычислениях

Пример безопасного создания:

const seconds = BigInt("1710000000000");
const instant = Instant.ofEpochSecond(Number(seconds));

Создание через промежуточные временные типы

Часто Instant формируется как результат цепочки преобразований:

import { LocalDate, LocalTime, ZoneId } from "@js-joda/core";

const date = LocalDate.of(2024, 6, 1);
const time = LocalTime.of(14, 45);

const instant = date
  .atTime(time)
  .atZone(ZoneId.of("Europe/Moscow"))
  .toInstant();

Такая цепочка демонстрирует типичную модель:

  • локальные компоненты времени
  • привязка к зоне
  • финальная нормализация в UTC-момент

Особенности интерпретации входных данных

Разные источники данных при создании Instant имеют различную семантику:

  • epoch milliseconds — абсолютное время без контекста
  • ISO-строки — человекочитаемое представление UTC
  • LocalDateTime — контекстно-зависимое время
  • ZonedDateTime — полное временное представление

При преобразовании важно учитывать, что потеря или добавление информации о временной зоне напрямую влияет на итоговый Instant, поскольку он всегда нормализуется к UTC.


Согласование точности при конвертации

Instant хранит время с точностью до наносекунд, однако источники данных в JavaScript ограничены миллисекундами. Это приводит к следующим особенностям:

  • Date.now() — миллисекунды
  • ISO-строки — до наносекунд (в зависимости от источника)
  • Instant.ofEpochSecond — секунды + наносекунды

При преобразовании миллисекунды автоматически расширяются до наносекунд с заполнением нулями в младших разрядах.

const instant = Instant.ofEpochMilli(1000);
// эквивалентно 1 секунде и 0 наносекунд

Сравнение источников создания

Различные способы создания Instant ориентированы на разные сценарии:

  • системное время: Instant.now()
  • интеграция с API: ofEpochMilli
  • низкоуровневые системы: ofEpochSecond
  • обмен данными: parse
  • календарные вычисления: from(ZonedDateTime)

Каждый метод отражает определённый слой абстракции работы со временем, от аппаратного до прикладного уровня.