Функции для Юлианского календаря на 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
, а то лента при загрузке главной страницы будет "перескакивать" поближе к форме выбора даты.
09.06.2019, 15:50 [1989 просмотров]