django-vue3-admin-web/node_modules/astronomia/lib/julian.cjs
2025-10-20 21:21:14 +08:00

678 lines
18 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var base = require('./base.cjs');
var sexagesimal = require('./sexagesimal.cjs');
var deltat = require('./deltat.cjs');
/**
* @copyright 2013 Sonia Keys
* @copyright 2016 commenthol
* @license MIT
* @module julian
*/
const int = Math.trunc;
/** 1582-10-05 Julian Date is 1st Gregorian Date (1582-10-15) */
const GREGORIAN0JD = 2299160.5;
const DAYS_OF_YEAR = [0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
const SECS_OF_DAY = 86400; // 24 * 60 * 60
/**
* Base class for CalendarJulian and CalendarGregorian
* Respects the start of the Gregorian Calendar at `GREGORIAN0JD`
*/
class Calendar {
/**
* @param {number|Date} [year] - If `Date` is given then year, month, day is taken from that. Shortcut to `new Calendar().fromDate(date)`
* @param {number} [month]
* @param {number} [day]
*/
constructor (year, month = 1, day = 1) {
if (year instanceof Date) {
this.fromDate(year);
} else {
this.year = year;
this.month = month;
this.day = day;
}
}
getDate () {
return {
year: this.year,
month: this.month,
day: Math.floor(this.day)
}
}
getTime () {
const t = new sexagesimal["default"].Time(this.day * SECS_OF_DAY);
const [neg, h, m, _s] = t.toHMS(); // eslint-disable-line no-unused-vars
let [s, ms] = base["default"].modf(_s);
ms = Math.trunc(ms * 1000);
return {
hour: h % 24,
minute: m,
second: s,
millisecond: ms
}
}
toISOString () {
const { year, month, day } = this.getDate();
const { hour, minute, second, millisecond } = this.getTime();
return `${pad(year, 4)}-${pad(month)}-${pad(day)}T` +
`${pad(hour)}:${pad(minute)}:${pad(second)}.${pad(millisecond, 3)}Z`
}
isGregorian () {
return isCalendarGregorian(this.year, this.month, this.day)
}
/**
* Note: Take care for dates < GREGORIAN0JD as `date` is always within the
* proleptic Gregorian Calender
* @param {Date} date - proleptic Gregorian date
*/
fromDate (date) {
this.year = date.getUTCFullYear();
this.month = date.getUTCMonth() + 1;
const day = date.getUTCDate();
const hour = date.getUTCHours();
const minute = date.getUTCMinutes();
const second = date.getUTCSeconds();
const ms = date.getMilliseconds();
this.day = day + (hour + ((minute + ((second + ms / 1000) / 60)) / 60)) / 24;
return this
}
/**
* Note: Take care for dates < GREGORIAN0JD as `date` is always within the
* proleptic Gregorian Calender
* @returns {Date} proleptic Gregorian date
*/
toDate () {
const [day, fhour] = base["default"].modf(this.day);
const [hour, fminute] = base["default"].modf(fhour * 24);
const [minute, fsecond] = base["default"].modf(fminute * 60);
const [second, fms] = base["default"].modf(fsecond * 60);
const date = new Date(Date.UTC(
this.year, this.month - 1, day, hour, minute, second, Math.round(fms * 1000)
));
date.setUTCFullYear(this.year);
return date
}
/**
* converts a calendar date to decimal year
* @returns {number} decimal year
*/
toYear () {
const [d, f] = base["default"].modf(this.day); // eslint-disable-line no-unused-vars
const n = this.dayOfYear() - 1 + f;
const days = this.isLeapYear() ? 366 : 365;
const decYear = this.year + (n / days);
return decYear
}
/**
* converts a decimal year to a calendar date
* @param {number} year - decimal year
*/
fromYear (year) {
const [y, f] = base["default"].modf(year);
this.year = y;
const days = this.isLeapYear() ? 366 : 365;
const dayOfYear = base["default"].round(f * days, 5);
let m = 12;
while (m > 0 && DAYS_OF_YEAR[m] > dayOfYear) {
m--;
}
this.month = m;
this.day = 1 + dayOfYear - DAYS_OF_YEAR[this.month];
return this
}
isLeapYear () {
if (this.isGregorian()) {
return LeapYearGregorian(this.year)
} else {
return LeapYearJulian(this.year)
}
}
toJD () {
return CalendarToJD(this.year, this.month, this.day, !this.isGregorian())
}
fromJD (jd) {
const isJulian = !isJDCalendarGregorian(jd);
const { year, month, day } = JDToCalendar(jd, isJulian);
this.year = year;
this.month = month;
this.day = day;
return this
}
fromJDE (jde) {
this.fromJD(jde);
const dT = deltat["default"].deltaT(this.toYear()); // in seconds
this.day -= dT / 86400;
return this
}
toJDE () {
const dT = deltat["default"].deltaT(this.toYear()); // in seconds
this.day += dT / 86400;
return this.toJD()
}
/**
* set date to midnight UTC
*/
midnight () {
this.day = Math.floor(this.day);
return this
}
/**
* set date to noon UTC
*/
noon () {
this.day = Math.floor(this.day) + 0.5;
return this
}
/**
* @param {Boolean} td - if `true` calendar instance is in TD; date gets converted to UT
* true - `UT = TD - ΔT`
* false - `TD = UT + ΔT`
*/
deltaT (td) {
const dT = deltat["default"].deltaT(this.toYear()); // in seconds
if (td) {
this.day -= dT / 86400;
} else {
this.day += dT / 86400;
}
return this
}
dayOfWeek () {
return DayOfWeek(this.toJD())
}
dayOfYear () {
if (this.isGregorian()) {
return DayOfYearGregorian(this.year, this.month, this.day)
} else {
return DayOfYearJulian(this.year, this.month, this.day)
}
}
}
class CalendarJulian extends Calendar {
toJD () {
return CalendarJulianToJD(this.year, this.month, this.day)
}
fromJD (jd) {
const { year, month, day } = JDToCalendarJulian(jd);
this.year = year;
this.month = month;
this.day = day;
return this
}
isLeapYear () {
return LeapYearJulian(this.year)
}
dayOfYear () {
return DayOfYearJulian(this.year, this.month, this.day)
}
/**
* toGregorian converts a Julian calendar date to a year, month, and day
* in the Gregorian calendar.
* @returns {CalendarGregorian}
*/
toGregorian () {
const jd = this.toJD();
return new CalendarGregorian().fromJD(jd)
}
}
class CalendarGregorian extends Calendar {
toJD () {
return CalendarGregorianToJD(this.year, this.month, this.day)
}
fromJD (jd) {
const { year, month, day } = JDToCalendarGregorian(jd);
this.year = year;
this.month = month;
this.day = day;
return this
}
isLeapYear () {
return LeapYearGregorian(this.year)
}
dayOfYear () {
return DayOfYearGregorian(this.year, this.month, this.day)
}
/*
* toJulian converts a Gregorian calendar date to a year, month, and day
* in the Julian calendar.
* @returns {CalendarJulian}
*/
toJulian () {
const jd = this.toJD();
return new CalendarJulian().fromJD(jd)
}
}
// -----------------------------------------------------------------------------
/**
* base conversion from calendar date to julian day
*/
function CalendarToJD (y, m, d, isJulian) {
let b = 0;
if (m < 3) {
y--;
m += 12;
}
if (!isJulian) {
const a = base["default"].floorDiv(y, 100);
b = 2 - a + base["default"].floorDiv(a, 4);
}
// (7.1) p. 61
const jd = (base["default"].floorDiv(36525 * (int(y + 4716)), 100)) +
(base["default"].floorDiv(306 * (m + 1), 10) + b) + d - 1524.5;
return jd
}
/**
* CalendarGregorianToJD converts a Gregorian year, month, and day of month
* to Julian day.
*
* Negative years are valid, back to JD 0. The result is not valid for
* dates before JD 0.
* @param {number} y - year (int)
* @param {number} m - month (int)
* @param {number} d - day (float)
* @returns {number} jd - Julian day (float)
*/
function CalendarGregorianToJD (y, m, d) {
return CalendarToJD(y, m, d, false)
}
/**
* CalendarJulianToJD converts a Julian year, month, and day of month to Julian day.
*
* Negative years are valid, back to JD 0. The result is not valid for
* dates before JD 0.
* @param {number} y - year (int)
* @param {number} m - month (int)
* @param {number} d - day (float)
* @returns {number} jd - Julian day (float)
*/
function CalendarJulianToJD (y, m, d) {
return CalendarToJD(y, m, d, true)
}
/**
* LeapYearJulian returns true if year y in the Julian calendar is a leap year.
* @param {number} y - year (int)
* @returns {boolean} true if leap year in Julian Calendar
*/
function LeapYearJulian (y) {
return y % 4 === 0
}
/**
* LeapYearGregorian returns true if year y in the Gregorian calendar is a leap year.
* @param {number} y - year (int)
* @returns {boolean} true if leap year in Gregorian Calendar
*/
function LeapYearGregorian (y) {
return (y % 4 === 0 && y % 100 !== 0) || y % 400 === 0
}
/**
* JDToCalendar returns the calendar date for the given jd.
*
* Note that this function returns a date in either the Julian or Gregorian
* Calendar, as appropriate.
* @param {number} jd - Julian day (float)
* @param {boolean} isJulian - set true for Julian Calendar, otherwise Gregorian is used
* @returns {object} `{ (int) year, (int) month, (float) day }`
*/
function JDToCalendar (jd, isJulian) {
const [z, f] = base["default"].modf(jd + 0.5);
let a = z;
if (!isJulian) {
const α = base["default"].floorDiv(z * 100 - 186721625, 3652425);
a = z + 1 + α - base["default"].floorDiv(α, 4);
}
const b = a + 1524;
const c = base["default"].floorDiv(b * 100 - 12210, 36525);
const d = base["default"].floorDiv(36525 * c, 100);
const e = int(base["default"].floorDiv((b - d) * 1e4, 306001));
// compute return values
let year;
let month;
const day = (int(b - d) - base["default"].floorDiv(306001 * e, 1e4)) + f;
if (e === 14 || e === 15) {
month = e - 13;
} else {
month = e - 1;
}
if (month < 3) {
year = int(c) - 4715;
} else {
year = int(c) - 4716;
}
return { year, month, day }
}
/**
* JDToCalendarGregorian returns the calendar date for the given jd in the Gregorian Calendar.
*
* @param {number} jd - Julian day (float)
* @returns {object} `{ (int) year, (int) month, (float) day }`
*/
function JDToCalendarGregorian (jd) {
return JDToCalendar(jd, false)
}
/**
* JDToCalendarJulian returns the calendar date for the given jd in the Julian Calendar.
*
* @param {number} jd - Julian day (float)
* @returns {object} { (int) year, (int) month, (float) day }
*/
function JDToCalendarJulian (jd) {
return JDToCalendar(jd, true)
}
/**
* isJDCalendarGregorian tests if Julian day `jd` falls into the Gregorian calendar
* @param {number} jd - Julian day (float)
* @returns {boolean} true for Gregorian, false for Julian calendar
*/
function isJDCalendarGregorian (jd) {
return (jd >= GREGORIAN0JD)
}
/**
* isCalendarGregorian tests if date falls into the Gregorian calendar
* @param {number} year - julian/gregorian year
* @param {number} [month] - month of julian/gregorian year
* @param {number} [day] - day of julian/gregorian year
* @returns {boolean} true for Gregorian, false for Julian calendar
*/
function isCalendarGregorian (year, month = 1, day = 1) {
return (year > 1582 ||
(year === 1582 && month > 10) ||
(year === 1582 && month === 10 && day >= 15)
)
}
/**
* JDToDate converts a Julian day `jd` to a Date Object (Gregorian Calendar)
*
* Note: Javascript uses the the ISO-8601 calendar, which is a proleptic Gregorian
* calendar, i.e. it acts as if this calendar was always in effect, even before
* its year of introduction in 1582. Therefore dates between 1582-10-05 and
* 1582-10-14 exists.
*
* @param {number} jd - Julian day (float)
* @returns {Date}
*/
function JDToDate (jd) {
return new CalendarGregorian().fromJD(jd).toDate()
}
/**
* DateToJD converts a proleptic Gregorian Date into a Julian day `jd`
* @param {Date} date
* @returns {number} jd - Julian day (float)
*/
function DateToJD (date) {
return new CalendarGregorian().fromDate(date).toJD()
}
/**
* JDEToDate converts a Julian ephemeris day `jde` to a Date Object (Gregorian Calendar)
* To obtain "Universal Time" (UT) from "Dynamical Time" (TD) the correction ΔT (in seconds) gets applied
* ```
* UT = TD - ΔT
* ```
* If your use case does not require such accuracy converting `jde` using `JDToDate` is fine.
*
* Note: Javascript uses the the ISO-8601 calendar, which is a proleptic Gregorian
* calendar, i.e. it acts as if this calendar was always in effect, even before
* its year of introduction in 1582. Therefore dates between 1582-10-05 and
* 1582-10-14 exists.
*
* @param {number} jde - Julian ephemeris day
* @returns {Date} Javascript Date Object
*/
function JDEToDate (jde) {
return new CalendarGregorian().fromJDE(jde).toDate()
}
/**
* DateToJDE converts a Date Object (Gregorian Calendar) to a Julian ephemeris day `jde`
* To obtain "Dynamical Time" (TD) from "Universal Time" (UT) the correction ΔT (in seconds) gets applied
* ```
* TD = UT + ΔT
* ```
* If your use case does not require such accuracy converting `Date` using `DateToJD` is fine.
*
* @param {Date} date - Javascript Date Object
* @returns {number} jde - Julian ephemeris day (float)
*/
function DateToJDE (date) {
return new CalendarGregorian().fromDate(date).toJDE()
}
/**
* converts Modified Julian Day `mjd` to Julian Day `jd`
* @param {Number} mjd - Modified Julian Day
* @returns {Number} jd - Julian Day
*/
function MJDToJD (mjd) {
return mjd + base["default"].JMod
}
/**
* converts Julian Day `jd` to Modified Julian Day `mjd`
* The MJD sometimes appear when mentioning orbital elements of artificial satellites.
* Contrary to JD the MJD begins at Greenwich mean midnight.
* @param {Number} jd - Julian Day
* @returns {Number} mjd - Modified Julian Day MJD
*/
function JDToMJD (jd) {
return jd - base["default"].JMod
}
/**
* DayOfWeek determines the day of the week for a given JD.
*
* The value returned is an integer in the range 0 to 6, where 0 represents
* Sunday. This is the same convention followed in the time package of the
* Javascript standard library.
* @param {number} jd - Julian day (float)
* @returns {number} (int) 0 == sunday; ...; 6 == saturday
*/
function DayOfWeek (jd) {
return int(jd + 1.5) % 7
}
/**
* DayOfYearGregorian computes the day number within the year of the Gregorian
* calendar.
* @param {number} y - year (int)
* @param {number} m - month (int)
* @param {number} d - day (float)
* @returns {number} day of year
*/
function DayOfYearGregorian (y, m, d) {
return DayOfYear(y, m, int(d), LeapYearGregorian(y))
}
/**
* DayOfYearJulian computes the day number within the year of the Julian
* calendar.
* @param {number} y - year (int)
* @param {number} m - month (int)
* @param {number} d - day (float)
* @returns {number} day of year
*/
function DayOfYearJulian (y, m, d) {
return DayOfYear(y, m, int(d), LeapYearJulian(y))
}
/**
* DayOfYear computes the day number within the year.
*
* This form of the function is not specific to the Julian or Gregorian
* calendar, but you must tell it whether the year is a leap year.
* @param {number} y - year (int)
* @param {number} m - month (int)
* @param {number} d - day (float)
* @param {boolean} leap - set `true` if `y` is leap year
* @returns {number} day of year
*/
function DayOfYear (y, m, d, leap) {
let k = 0;
if (leap && m > 1) {
k = 1;
}
return k + DAYS_OF_YEAR[m] + int(d)
}
/**
* DayOfYearToCalendar returns the calendar month and day for a given
* day of year and leap year status.
* @param {number} n - day of year (int)
* @param {boolean} leap - set `true` if `y` is leap year
* @returns {object} `{ (int) month, (float) day }`
*/
function DayOfYearToCalendar (n, leap) {
let month;
let k = 0;
if (leap) {
k = 1;
}
for (month = 1; month <= 12; month++) {
if (k + DAYS_OF_YEAR[month] > n) {
month = month - 1;
break
}
}
const day = n - k - DAYS_OF_YEAR[month];
return { month, day }
}
/**
* DayOfYearToCalendarGregorian returns the calendar month and day for a given
* day of year.
* @param {number} year
* @param {number} n - day of year (int)
* @returns {CalendarGregorian} { (int) year, (int) month, (float) day }
*/
function DayOfYearToCalendarGregorian (year, n) {
const { month, day } = DayOfYearToCalendar(n, LeapYearGregorian(year));
return new CalendarGregorian(year, month, day)
}
/**
* DayOfYearToCalendarJulian returns the calendar month and day for a given
* day of year.
* @param {number} year
* @param {number} n - day of year (int)
* @returns {CalendarJulian} { (int) year, (int) month, (float) day }
*/
function DayOfYearToCalendarJulian (year, n) {
const { month, day } = DayOfYearToCalendar(n, LeapYearJulian(year));
return new CalendarJulian(year, month, day)
}
function pad (num, len) {
len = len || 2;
const neg = num < 0 ? '-' : '';
num = Math.abs(num);
const padded = ('0000' + num);
return neg + padded.substr(padded.length - len, len)
}
var julian = {
GREGORIAN0JD,
Calendar,
CalendarJulian,
CalendarGregorian,
CalendarToJD,
CalendarGregorianToJD,
CalendarJulianToJD,
LeapYearJulian,
LeapYearGregorian,
JDToCalendar,
JDToCalendarGregorian,
JDToCalendarJulian,
isJDCalendarGregorian,
isCalendarGregorian,
JDToDate,
DateToJD,
JDEToDate,
DateToJDE,
MJDToJD,
JDToMJD,
DayOfWeek,
DayOfYearGregorian,
DayOfYearJulian,
DayOfYear,
DayOfYearToCalendar,
DayOfYearToCalendarGregorian,
DayOfYearToCalendarJulian
};
exports.Calendar = Calendar;
exports.CalendarGregorian = CalendarGregorian;
exports.CalendarGregorianToJD = CalendarGregorianToJD;
exports.CalendarJulian = CalendarJulian;
exports.CalendarJulianToJD = CalendarJulianToJD;
exports.CalendarToJD = CalendarToJD;
exports.DateToJD = DateToJD;
exports.DateToJDE = DateToJDE;
exports.DayOfWeek = DayOfWeek;
exports.DayOfYear = DayOfYear;
exports.DayOfYearGregorian = DayOfYearGregorian;
exports.DayOfYearJulian = DayOfYearJulian;
exports.DayOfYearToCalendar = DayOfYearToCalendar;
exports.DayOfYearToCalendarGregorian = DayOfYearToCalendarGregorian;
exports.DayOfYearToCalendarJulian = DayOfYearToCalendarJulian;
exports.GREGORIAN0JD = GREGORIAN0JD;
exports.JDEToDate = JDEToDate;
exports.JDToCalendar = JDToCalendar;
exports.JDToCalendarGregorian = JDToCalendarGregorian;
exports.JDToCalendarJulian = JDToCalendarJulian;
exports.JDToDate = JDToDate;
exports.JDToMJD = JDToMJD;
exports.LeapYearGregorian = LeapYearGregorian;
exports.LeapYearJulian = LeapYearJulian;
exports.MJDToJD = MJDToJD;
exports["default"] = julian;
exports.isCalendarGregorian = isCalendarGregorian;
exports.isJDCalendarGregorian = isJDCalendarGregorian;