Астрономические вычисления

Астрономические задачи почти всегда связаны с высокой точностью времени. Ошибка даже в несколько секунд способна привести к неправильному расчёту положения небесного объекта, момента восхода или фазы Луны. Библиотека Luxon предоставляет удобные инструменты для работы с UTC, часовыми поясами, юлианскими датами и интервалами времени.

В астрономии критически важны:

  • хранение времени в UTC;
  • работа с миллисекундной точностью;
  • корректный учёт временных зон;
  • преобразование между календарными системами;
  • вычисление временных интервалов;
  • обработка ISO-форматов.

Использование UTC как базовой системы времени

Астрономические вычисления почти никогда не выполняются в локальном времени. Основной стандарт — UTC.

import { DateTime } from "luxon";

const now = DateTime.utc();

console.log(now.toISO());

Пример результата:

2026-05-24T14:32:11.421Z

Метод utc() создаёт объект времени без привязки к локальному часовому поясу.


Создание точного момента времени

Для расчётов часто требуется фиксированная дата наблюдения.

const eclipse = DateTime.fromObject({
  year: 2026,
  month: 8,
  day: 12,
  hour: 18,
  minute: 45,
  second: 0
}, {
  zone: "utc"
});

console.log(eclipse.toISO());

Юлианская дата

В астрономии широко используется юлианская дата (Julian Date, JD). Luxon не содержит встроенной поддержки JD, однако предоставляет удобную основу для вычислений.

Формула перевода Unix Time в Julian Date

JD = + 2440587.5

Реализация:

function toJulianDate(dateTime) {
  return dateTime.toMillis() / 86400000 + 2440587.5;
}

const dt = DateTime.utc();

console.log(toJulianDate(dt));

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

function fromJulianDate(jd) {
  const millis = (jd - 2440587.5) * 86400000;

  return DateTime.fromMillis(millis, {
    zone: "utc"
  });
}

const date = fromJulianDate(2461185.125);

console.log(date.toISO());

Модифицированная юлианская дата

Для уменьшения размеров чисел используется MJD (Modified Julian Date).

Формула MJD

MJD = JD - 2400000.5

Реализация:

function toMJD(dateTime) {
  return toJulianDate(dateTime) - 2400000.5;
}

Звёздное время

Звёздное время применяется для определения положения небесных объектов относительно меридиана наблюдателя.

Приближённая формула GMST

GMST = 18.697374558 + 24.06570982441908 D

где:

  • D — количество суток с эпохи J2000.0.

Реализация вычисления GMST

function gmst(dateTime) {
  const jd = toJulianDate(dateTime);

  const d = jd - 2451545.0;

  let gmst = 18.697374558 + 24.06570982441908 * d;

  gmst = gmst % 24;

  if (gmst < 0) {
    gmst += 24;
  }

  return gmst;
}

const now = DateTime.utc();

console.log(gmst(now));

Эпоха J2000.0

Многие астрономические алгоритмы используют эпоху J2000.0 как базовую точку отсчёта.

Дата эпохи:

2000-01-01 12:00:00 UTC

Создание в Luxon:

const J2000 = DateTime.fromISO(
  "2000-01-01T12:00:00Z"
);

console.log(J2000.toISO());

Количество суток между астрономическими событиями

const start = DateTime.utc(2026, 1, 1);
const end = DateTime.utc(2026, 12, 31);

const diff = end.diff(start, "days");

console.log(diff.days);

Вычисление времени до следующего затмения

const now = DateTime.utc();

const nextEclipse = DateTime.fromISO(
  "2026-08-12T18:45:00Z"
);

const interval = nextEclipse.diff(now, [
  "days",
  "hours",
  "minutes"
]);

console.log(interval.toObject());

Работа с астрономическими интервалами

Luxon предоставляет объект Interval.

import { Interval } from "luxon";

const meteorShower = Interval.fromDateTimes(
  DateTime.fromISO("2026-08-11T00:00:00Z"),
  DateTime.fromISO("2026-08-13T00:00:00Z")
);

console.log(meteorShower.length("hours"));

Проверка попадания времени в интервал наблюдения

const observationWindow = Interval.fromDateTimes(
  DateTime.utc(2026, 5, 1, 20),
  DateTime.utc(2026, 5, 2, 4)
);

const observationTime = DateTime.utc(
  2026,
  5,
  1,
  23,
  30
);

console.log(
  observationWindow.contains(observationTime)
);

Солнечные сутки и звёздные сутки

Средние солнечные сутки:

24 часа

Звёздные сутки:

23 часа 56 минут 4 секунды

Создание звёздных суток:

const siderealDay = Duration.fromObject({
  hours: 23,
  minutes: 56,
  seconds: 4
});

console.log(siderealDay.as("seconds"));

Работа с Duration

import { Duration } from "luxon";

const orbitalPeriod = Duration.fromObject({
  days: 365,
  hours: 6,
  minutes: 9
});

console.log(
  orbitalPeriod.as("hours")
);

Добавление орбитального периода

const perihelion = DateTime.fromISO(
  "2025-01-04T13:28:00Z"
);

const nextPerihelion = perihelion.plus({
  days: 365,
  hours: 6
});

console.log(nextPerihelion.toISO());

Работа с високосными годами

Астрономические расчёты требуют учёта високосных лет.

const year = DateTime.utc(2028);

console.log(year.isInLeapYear);

День года

Во многих алгоритмах используется номер дня в году.

const dt = DateTime.utc(2026, 3, 15);

console.log(dt.ordinal);

Дробные сутки

Часто требуется представить время как долю суток.

Формула дробных суток

Fraction = + +

Пример:

function fractionalDay(dateTime) {
  return (
    dateTime.hour / 24 +
    dateTime.minute / 1440 +
    dateTime.second / 86400
  );
}

console.log(
  fractionalDay(DateTime.utc())
);

Парсинг астрономических временных меток

ISO 8601 — стандартный формат хранения времени.

const observation = DateTime.fromISO(
  "2026-05-24T22:15:45.123Z"
);

console.log(observation.toUTC().toISO());

Работа с миллисекундами

Для высокоточных вычислений:

const precise = DateTime.utc();

console.log(precise.millisecond);

Конвертация временных зон

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

const local = DateTime.local();

const utc = local.toUTC();

console.log(local.toString());
console.log(utc.toString());

Локальное время обсерватории

const observatory = DateTime.utc().setZone(
  "America/Santiago"
);

console.log(observatory.toString());

Вычисление времени прохождения объекта

Пример расчёта момента через фиксированный интервал:

const start = DateTime.utc();

const transit = start.plus({
  hours: 5,
  minutes: 17,
  seconds: 42
});

console.log(transit.toISO());

Работа с массивом наблюдений

const observations = [
  "2026-05-01T20:15:00Z",
  "2026-05-01T21:10:00Z",
  "2026-05-01T22:45:00Z"
];

const parsed = observations.map(date =>
  DateTime.fromISO(date)
);

parsed.forEach(item => {
  console.log(item.toUTC().toISO());
});

Среднее время наблюдений

function averageDate(dates) {
  const total = dates.reduce((sum, dt) => {
    return sum + dt.toMillis();
  }, 0);

  return DateTime.fromMillis(
    total / dates.length,
    { zone: "utc" }
  );
}

Расчёт времени экспозиции

const exposure = Duration.fromObject({
  seconds: 180
});

console.log(exposure.as("minutes"));

Проверка равенства временных отметок

const a = DateTime.fromISO(
  "2026-05-24T10:00:00Z"
);

const b = DateTime.fromISO(
  "2026-05-24T10:00:00Z"
);

console.log(a.equals(b));

Нормализация данных времени

const dt = DateTime.fromObject({
  year: 2026,
  month: 15,
  day: 40
});

console.log(dt.toISO());

Luxon автоматически корректирует переполнение:

2027-04-09T00:00:00.000+00:00

Unix Timestamp в астрономии

Unix timestamp часто используется в телеметрии и системах управления телескопами.

const timestamp = Date.now();

const dt = DateTime.fromMillis(timestamp);

console.log(dt.toUTC().toISO());

Сериализация астрономических данных

const observation = {
  object: "Mars",
  observedAt: DateTime.utc().toISO()
};

console.log(JSON.stringify(observation));

Интерполяция времени наблюдений

function interpolate(start, end, factor) {
  const diff = end.toMillis() - start.toMillis();

  return DateTime.fromMillis(
    start.toMillis() + diff * factor,
    { zone: "utc" }
  );
}

Вычисление времени между импульсами

const pulse1 = DateTime.utc();
const pulse2 = pulse1.plus({
  milliseconds: 125
});

const diff = pulse2.diff(
  pulse1,
  "milliseconds"
);

console.log(diff.milliseconds);

Работа с большими временными диапазонами

const ancient = DateTime.utc(-500, 1, 1);

console.log(ancient.toISO());

Luxon поддерживает даты до нашей эры, что полезно для исторической астрономии и анализа древних затмений.


Форматирование астрономического времени

const dt = DateTime.utc();

console.log(
  dt.toFormat("yyyy-MM-dd HH:mm:ss 'UTC'")
);

Обработка недопустимых дат

const invalid = DateTime.fromISO(
  "2026-02-30"
);

console.log(invalid.isValid);
console.log(invalid.invalidReason);

Использование цепочек преобразований

const result = DateTime.utc()
  .plus({ days: 5 })
  .minus({ hours: 3 })
  .startOf("hour");

console.log(result.toISO());

Практическая модель астрономического наблюдения

import { DateTime, Interval } from "luxon";

const start = DateTime.fromISO(
  "2026-06-10T20:00:00Z"
);

const end = DateTime.fromISO(
  "2026-06-11T03:00:00Z"
);

const session = Interval.fromDateTimes(
  start,
  end
);

const duration = session.toDuration([
  "hours",
  "minutes"
]);

console.log(duration.toObject());