JulianDate

В системе координат времени, используемой в CesiumJS, ключевую роль играет представление даты и времени через класс JulianDate. Он служит фундаментальным типом для всех временных вычислений, связанных с орбитальной механикой, визуализацией движения объектов, интерполяцией анимаций и синхронизацией сцен в глобальном пространстве.

Юлианская дата основана на непрерывном счёте дней, начиная с фиксированной исторической точки отсчёта — юлианской эпохи. В отличие от стандартных календарных форматов (годы, месяцы, дни), такая система позволяет выражать время как одно число с дробной частью, где целая часть соответствует дням, а дробная — доле суток.

В контексте CesiumJS это критично по нескольким причинам:

  • отсутствие неоднозначности календарных переходов;
  • удобство арифметики времени;
  • высокая точность при интерполяции движения;
  • независимость от локальных календарей и часовых поясов.

Представление времени в CesiumJS

JulianDate в CesiumJS реализует двойную структуру хранения времени:

  • целая часть (dayNumber) — количество дней с начала юлианского периода;
  • дробная часть (secondsOfDay) — количество секунд внутри суток с высокой точностью.

Такой подход минимизирует ошибки округления, возникающие при использовании стандартных чисел с плавающей точкой.

Основная концепция заключается в разделении глобального времени на дискретные сутки и высокоточное внутрисуточное смещение.

Конструктор JulianDate

Базовая инициализация объекта JulianDate осуществляется через указание дней и секунд:

const date = new JulianDate(2451545, 0.0);

Здесь:

  • 2451545 — юлианский день (соответствует эпохе J2000.0);
  • 0.0 — секунды внутри суток.

Также допускается создание через стандартные JavaScript-даты, которые конвертируются во внутреннее представление:

const date = JulianDate.fromDate(new Date());

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

Эпоха J2000.0 и базовые константы

CesiumJS использует эпоху J2000.0 как стандартную точку отсчёта для астрономических вычислений. Это соответствует:

  • 1 января 2000 года
  • 12:00:00 UTC

Юлианское представление позволяет удобно выражать смещения относительно этой точки:

const t = JulianDate.fromIso8601("2020-01-01T00:00:00Z");

При этом все временные операции внутри движка выполняются относительно J2000, что упрощает вычисления орбит и вращений небесных тел.

Арифметика времени

JulianDate поддерживает операции сложения и вычитания временных интервалов через секунды:

const start = JulianDate.now();
const end = JulianDate.addSeconds(start, 3600, new JulianDate());

Такой подход позволяет:

  • избегать преобразований в миллисекунды JavaScript;
  • сохранять точность при длительных интервалах;
  • работать с астрономическими масштабами времени.

Разница между двумя моментами вычисляется через:

const diff = JulianDate.secondsDifference(end, start);

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

Сравнение дат

JulianDate предоставляет строгие методы сравнения, основанные на числовом представлении:

JulianDate.lessThan(a, b);
JulianDate.greaterThan(a, b);
JulianDate.equals(a, b);

Сравнение выполняется без приведения к стандартным объектам Date, что исключает потери точности и влияние локальных настроек системы.

Работа с UTC и TAI

Внутреннее время CesiumJS опирается на различие между:

  • UTC (Coordinated Universal Time)
  • TAI (International Atomic Time)

JulianDate учитывает наличие leap seconds (високосных секунд), что особенно важно для точных симуляций.

Преобразования:

const utc = JulianDate.toDate(julianDate);
const jd = JulianDate.fromIso8601("2023-10-01T12:00:00Z");

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

Интерполяция времени

JulianDate активно используется в ключевой механике интерполяции движений объектов. При анимации камеры или спутников вычисляются промежуточные значения времени:

const t = JulianDate.lerp(start, end, 0.5, new JulianDate());

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

Клонирование и неизменяемость

JulianDate часто используется как иммутабельный объект. Для операций модификации создаются новые экземпляры:

const copy = JulianDate.clone(original);

Такой подход предотвращает побочные эффекты при использовании времени в разных подсистемах: рендеринге, физике, симуляции и таймлайне.

Преобразование из и в стандартные форматы

JulianDate поддерживает конвертацию в различные форматы:

ISO 8601

JulianDate.toIso8601(julianDate);

JavaScript Date

JulianDate.toDate(julianDate);

Юлианское число

JulianDate.toJulianDate(julianDate);

Каждое представление используется в разных слоях системы: от пользовательского интерфейса до низкоуровневых вычислений.

Точность и численные ограничения

Использование двойной структуры (день + секунды) минимизирует ошибки округления IEEE-754. Однако при длительных интервалах времени возможны накопления погрешностей.

Для компенсации применяются:

  • нормализация секунд внутри суток;
  • перенос переполнений в целую часть;
  • использование фиксированных алгоритмов сложения.

Использование в системе симуляции времени

JulianDate является основой для Clock и Timeline в CesiumJS. Все временные шкалы, анимации и обновления сцены зависят от текущего JulianDate.

В симуляционном цикле:

  • текущий момент времени хранится как JulianDate;
  • шаг симуляции выражается в секундах;
  • обновление сцены происходит через вычисление нового JulianDate.

Такой подход обеспечивает детерминированность и синхронность визуализации.

Взаимодействие с потоками данных

При обработке потоковых данных (например, телеметрии спутников) JulianDate используется как ключ синхронизации. Каждое измерение привязывается к конкретному моменту времени:

{
  time: JulianDate.fromIso8601("2024-06-01T00:00:00Z"),
  position: { x: 1, y: 2, z: 3 }
}

Это позволяет строить непрерывные траектории и выполнять интерполяцию между измерениями.

Внутренняя оптимизация представления

JulianDate оптимизирован для:

  • минимального количества аллокаций;
  • быстрого сравнения через числовые поля;
  • компактного хранения в памяти;
  • предсказуемого поведения в реальном времени.

Такая структура делает его предпочтительным типом времени во всех подсистемах CesiumJS, где требуется высокая точность и стабильность вычислений.