БлогNot. Функции для Юлианского календаря на Javascript

Функции для Юлианского календаря на Javascript

Между прочим, Юлианский календарь не только до сих пор применяется в астрономии, но и считается многими, особенно православными людьми, точнее григорианского, что бы там ни болтали в школе :)

Да и чисто из практики - ну не начинается у нас весна 1 марта, а осень - 1 сентября. Всё как раз на 13-14 дней позже календарных сезонов начинается.

Для перевода "бесовских" дат в "настоящие", наверное, существуют и решения, и онлайн-сервисы, но навскидку они кажутся или слишком сложными или прямо ошибочными (проверял на сегодняшней дате, впрочем, ошибки, может, и нет, а просто по часовому поясу ещё "вчера" было).

Так как в PHP есть готовые функции gregoriantojd, jdtogregorian и jdtojulian для нашей цели, этой системе именования и последуем.

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

Контроля корректности дат здесь нету, всё равно функции Javascript скажут "NaN" (не число) сами. Помните также, что "нулевого" года не существовало, Христос родился в Году Первом, а до этого был "первый до нашей эры".

Вот скриптик в работе и далее исходники (без HTML-обрамления).

Дата папская:

 <form name="formJulian">
  <p>Дата папская: 
   <input type="date" name="grigorianDate" id="grigorianDate" autofocus />
   <input type="button" value="Дата истинная" onclick="runMe()" />
  </p>
  <p id="julianDate"></p>
 </form>

 <script>
  function gregorianToJd (d) { //Григорианская дата в JDN
   var x = Math.floor((14 - d.getMonth())/12);
   var y = d.getFullYear() + 4800 - x;
   var z = d.getMonth() - 3 + 12 * x;
   var n = d.getDate() + Math.floor(((153 * z) + 2)/5) + (365 * y) + 
           Math.floor(y/4) + Math.floor(y/400) - Math.floor(y/100) - 32045;
   return n;
  }   

  function jdToJulian (JD) { //JDN в юлианскую дату (месяцы нумеруются с единицы!)
   var alpha, c, d, e, day, month, year, z, a, b;
   JD += 0.5;
   z = Math.floor(JD);
   a = z;
   b = a + 1524;
   c = Math.floor((b - 122.1) / 365.25);
   d = Math.floor(365.25 * c);
   e = Math.floor((b - d) / 30.6001);
   month = Math.floor((e < 14) ? (e - 1) : (e - 13));
   year = Math.floor((month > 2) ? (c - 4716) : (c - 4715));
   day = b - d - Math.floor(30.6001 * e);
   if (year < 1) year--;
   return [day,month,year];
  };

  function jdToGregorian (jd) { //JDN в григорианскую дату (месяцы нумеруются с нуля!)
   function Date_setJD (jd) {
    this.setTime(Math.round((jd - 2440587.5) * 86400000));
    return this;
   }
   function Date_getJD() {
    return this.getTime() / 86400000 + 2440587.5;
   }
   var obj = new Date();
   obj.getJD = Date_getJD;
   obj.setJD = Date_setJD;
   if (arguments.length) obj.setJD(jd);
   obj.valueOf = Date_getJD;
   return obj;
  }

  function runMe() {
   var dt = document.getElementById('grigorianDate').value;
   var y = parseInt(''+dt.slice(0,4));
   var m = parseInt(''+dt.slice(5,7));
   var d = parseInt(''+dt.slice(8));
   var d0 = new Date(y,m,d);
   var n = gregorianToJd (d0);
   var dj = jdToJulian(n), d0 = parseInt(dj[0]), m0 = parseInt(dj[1]), y0 = parseInt(dj[2]);
   var dd = jdToGregorian(n);
   d = dd.getDate(); m = dd.getMonth() + 1; y = dd.getFullYear();
   document.getElementById('julianDate').innerHTML = 'Юлианский номер дня (JDN): ' + n + 
    '<br>Юлианская дата: ' + (d0<10 ? '0' : '') + d0 + '.' + (m0<10 ? '0' : '') + m0 + '.' + y0 +
    '<br>Обратно преобразованная дата: ' + (d<10 ? '0' : '') + d + '.' + (m<10 ? '0' : '') + m + '.' + y;
  }

  window.addEventListener('load', function (e) { //По загрузке поставить в компоненту сегодня
   var today = new Date();
   var d = today.getFullYear() + '-' + ('0' + (today.getMonth() + 1)).slice(-2) + '-' + 
           ('0' + today.getDate()).slice(-2);
   document.getElementById('grigorianDate').value = d;
  }, false); 
 </script>
 <noscript><p>Включите Javascript для работы приложения!</p></noscript>

Простейший аналогичный код на PHP может выглядеть для сегодняшней даты так:

<?php
 $d = cal_to_jd (  CAL_GREGORIAN , 6 , 9 , 2019 );
 echo 'JDN:'.$d;
 echo '<br>Gregorian date:'. jdtogregorian ( $d );
 echo '<br>Julian date:'. jdtojulian ( $d );
?>

P.S. В онлайн-версии убрал у поля ввода даты атрибут autofocus, а то лента при загрузке главной страницы будет "перескакивать" поближе к форме выбора даты.


теги: javascript php дата православие

09.06.2019, 15:50; рейтинг: 42