Вычисление юлианской даты с помощью javascript

Я пытаюсь рассчитать дату по юлианскому календарю из строки даты календаря, используя javascript. Я нашел этот сайт, где объясняется, как его рассчитать.

Я сделал этот код javascript: https://jsfiddle.net/kzgn8vs1/1/

var time = moment("2018-04-07 23:45:16 -0300", "YYYY-MM-DD HH:mm:ss Z").utc(); 
var Y = time.year();
var M = time.month() + 1;
var D = time.date() + moment.duration(time.format('HH:mm:ss')).asDays();

if( M == 1 || M == 2 ) {
    Y = Y - 1;
    M = M + 12;
}

var A = Y / 100;
var B = 2 - A + (A / 4);
var C = ( Y > 0 ) ? (365.25 * Y) : ((365.25 * Y) - 0.75);
var E = 30.6001 * (M + 1);

var JD = B+C+D+E+1720994.5;

console.log(JD);

Что возвращает 2458216.9802685184 для даты 2018-04-07 23:45:16 -0300. Но когда я пробую некоторые онлайн-конвертеры, такие как http://www.onlineconversion.com/julian_date.htm и https://www.aavso.org/jd-calculator

Ввод даты 2018-04-08 2:45:16 (моя дата преобразована в UTC), оба возвращают 2458216.61477. Разница в 0,36 с моим результатом.

Где ошибка? В моем коде или в методе расчета?


person Mark    schedule 07.04.2018    source источник
comment
Вы можете найти подробное объяснение этого вопроса stackoverflow.com/ вопросы/11759992/   -  person Lasitha Petthawadu    schedule 07.04.2018
comment
Пример кода по этому вопросу также дает мне другой результат, чем все онлайн-калькуляторы, которые я пробовал, с разницей +-30 или 40, мой код намного ближе к результату онлайн-калькуляторов.   -  person Mark    schedule 07.04.2018
comment
Проверьте ответ, который я опубликовал, я смог пересмотреть ваш код, чтобы получить ответ онлайн-калькуляторов, и подробно описал, как я к нему пришел.   -  person Lasitha Petthawadu    schedule 07.04.2018


Ответы (2)


Основываясь на вопросе StackOverflow здесь, я изменил ваш JsFiddle

Я изменил вашу реализацию на основе

2440587,5 дней + ВРЕМЯ UNIX в днях === Юлианский день

(UNIX TIME/86400000) + 2440587,5) === Юлианский день;

и обновил ваш код, чтобы он отображался как var JD = time/86400000 + 2440587.5; Чтобы получить тот же результат, что и онлайн-калькулятор, мне пришлось использовать время UTC, которое вы использовали в онлайн-примерах.

person Lasitha Petthawadu    schedule 07.04.2018
comment
Спасибо, в конце концов, я заставил свою реализацию кода работать, мне пришлось использовать некоторые значения как целые вместо двойных, например, этот var JD = parseInt(B)+parseInt(C)+(D)+parseInt(E)+1720994.5; - person Mark; 07.04.2018
comment
Это не отвечает на вопрос Где ошибка. - person RobG; 07.04.2018
comment
@Mark - это ваш фактический ответ, страница, на которую вы ссылаетесь, имеет A = INT (Y/100), поэтому вы должны сделать что-то вроде var A = Y / 100 | 0 или использовать Math.floor или parseInt для усечения десятичной части везде, где используется INT(…). То же самое относится к B, C и E. - person RobG; 07.04.2018

Как вы говорите в своем комментарии к ответу Ласиты Ишан Петтаваду, вам нужно установить минимальные значения A, B, C и E. Версия, которая является довольно буквальной реализацией алгоритма ссылка из OP без использования библиотеки:

function toJulianDate(date) {
  var floor = Math.floor;
  var y = date.getUTCFullYear();
  var m = date.getUTCMonth() + 1;
  var d = date.getUTCDate() + (date % 8.64e7) / 8.64e7;
  
  if (m < 3) {
    y -= 1;
    m += 12;
  }
  
  var a = floor(y/100);
  var b = date < new Date(Date.UTC(1582,9,15))? 0 : 2 - a + floor(a/4);
  var c = floor(y < 0? 365.25 * y - 0.75 : 365.25 * y);
  var e = floor(30.6001 * (m + 1));
  
  return b + c + d + e + 1720994.5;
}

console.log(toJulianDate(new Date('2018-04-07T23:45:16-03:00'))); // 2458216.6147685186

console.log(toJulianDate(new Date('2018-04-08T02:45:16Z'))); // 2458216.6147685186

При создании дат я использовал строгий расширенный формат ISO 8601. Все остальное не должно использовать встроенный парсер.

person RobG    schedule 07.04.2018
comment
Судя по моим экспериментам, функция даты Javascript не распознает юлианский календарь и обрабатывает все даты как григорианские, даже те, которые были до 15 октября 1582 года. ecma-international.org/ecma-262/5.1/#sec-15.9.1.15 указывает, что YYYY — это десятичные цифры года от 0000 до 9999. по григорианскому календарю. - person Gerard Ashton; 15.04.2018
comment
@GerardAshton - я не понимаю причины вашего комментария. Это реализация алгоритма, предоставленного OP для генерации строки даты по юлианскому календарю из объекта даты ECMAScript. Нет никаких утверждений или выводов о том, что встроенный синтаксический анализатор понимает даты по юлианскому календарю, как раз наоборот. - person RobG; 15.04.2018
comment
Я не расшифровал все магические числа в алгоритме. Но я не понимаю, почему алгоритм RobG заботится о том, является ли дата до или после даты принятия григорианского календаря в Риме. - person Gerard Ashton; 17.04.2018
comment
@GerardAshton — как я постоянно говорю, это не мой алгоритм, это тот, < i>связано с OP. Мне кажется, что это 1 год и 1 день, но это может быть просто потому, что ECMAScript имеет год 0000, который обычно не распознается. Проблемы с алгоритмом или даты до 15 октября 1582 года следует обсуждать с ОП или автором связанного алгоритма. - person RobG; 17.04.2018