678 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			678 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'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;
 |