254 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			254 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict';
 | 
						|
 | 
						|
Object.defineProperty(exports, '__esModule', { value: true });
 | 
						|
 | 
						|
var base = require('./base.cjs');
 | 
						|
var julian = require('./julian.cjs');
 | 
						|
 | 
						|
/**
 | 
						|
 * @copyright 2013 Sonia Keys
 | 
						|
 * @copyright 2016 commenthol
 | 
						|
 * @license MIT
 | 
						|
 * @module jm
 | 
						|
 */
 | 
						|
 | 
						|
const int = Math.trunc;
 | 
						|
 | 
						|
/**
 | 
						|
 * JewishCalendar returns interesting dates and facts about a given year.
 | 
						|
 *
 | 
						|
 * Input is a Julian or Gregorian year.
 | 
						|
 *
 | 
						|
 * Outputs:
 | 
						|
 *  A:      (int) Year number in the Jewish Calendar
 | 
						|
 *  mP:     (int) Month number of Pesach.
 | 
						|
 *  dP:     (int) Day number of Pesach.
 | 
						|
 *  mNY:    (int) Month number of the Jewish new year.
 | 
						|
 *  dNY:    (int) Day number of the Jewish new year.
 | 
						|
 *  months: (int) Number of months in this year.
 | 
						|
 *  days:   (int) Number of days in this year.
 | 
						|
 */
 | 
						|
function JewishCalendar (y) {
 | 
						|
  const A = y + 3760;
 | 
						|
  const D = bigD(y);
 | 
						|
  let mP = 3;
 | 
						|
  let dP = D;
 | 
						|
  if (dP > 31) {
 | 
						|
    mP++;
 | 
						|
    dP -= 31;
 | 
						|
  }
 | 
						|
  // A simplification of Meeus's rule to add 163 days.  Months of Pesach
 | 
						|
  // are either March or April with D based off of March.  Months of New
 | 
						|
  // year are either September or August so D+163-(days from March to
 | 
						|
  // September == 184) = D-21 must be based off of September.
 | 
						|
  let mNY = 9;
 | 
						|
  let dNY = D - 21;
 | 
						|
  if (dNY > 30) {
 | 
						|
    mNY++;
 | 
						|
    dNY -= 30;
 | 
						|
  }
 | 
						|
  let months = 12;
 | 
						|
  switch (A % 19) {
 | 
						|
    case 0:
 | 
						|
    case 3:
 | 
						|
    case 6:
 | 
						|
    case 8:
 | 
						|
    case 11:
 | 
						|
    case 14:
 | 
						|
    case 17:
 | 
						|
      months++;
 | 
						|
      break
 | 
						|
  }
 | 
						|
  // Similarly, A simplification of Meeus's rule to take the difference
 | 
						|
  // in calendar days from NY of one year to NY of the next.  NY is based
 | 
						|
  // on D, so difference in D is difference in day numbers of year.  Result
 | 
						|
  // is sum of this number and the number of days in the Western calandar
 | 
						|
  // year.
 | 
						|
  const y1 = y + 1;
 | 
						|
  let lf = julian["default"].LeapYearGregorian;
 | 
						|
  if (y1 < 1583) {
 | 
						|
    lf = julian["default"].LeapYearJulian;
 | 
						|
  }
 | 
						|
  let days = 365;
 | 
						|
  if (lf(y1)) {
 | 
						|
    days++;
 | 
						|
  }
 | 
						|
  days += bigD(y1) - D;
 | 
						|
  return [A, mP, dP, mNY, dNY, months, days]
 | 
						|
}
 | 
						|
 | 
						|
const bigD = function (y) { // (y int)  int
 | 
						|
  const C = base["default"].floorDiv(y, 100);
 | 
						|
  // const S int
 | 
						|
  let S = 0;
 | 
						|
  if (y >= 1583) {
 | 
						|
    S = int(base["default"].floorDiv(3 * C - 5, 4));
 | 
						|
  }
 | 
						|
  const a = (12 * y + 12) % 19;
 | 
						|
  const b = y % 4;
 | 
						|
  const Q = -1.904412361576 + 1.554241796621 * (a) + 0.25 * (b) -
 | 
						|
    0.003177794022 * (y) + (S);
 | 
						|
  const fq = Math.floor(Q);
 | 
						|
  const iq = int(fq);
 | 
						|
  const j = (iq + 3 * y + 5 * b + 2 - S) % 7;
 | 
						|
  const r = Q - fq;
 | 
						|
  // const D int
 | 
						|
  let D;
 | 
						|
  if (j === 2 || j === 4 || j === 6) {
 | 
						|
    D = iq + 23;
 | 
						|
  } else if (j === 1 && a > 6 && r >= 0.63287037) {
 | 
						|
    D = iq + 24;
 | 
						|
  } else if (j === 0 && a > 11 && r >= 0.897723765) {
 | 
						|
    D = iq + 23;
 | 
						|
  } else {
 | 
						|
    D = iq + 22;
 | 
						|
  }
 | 
						|
  return int(D)
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * MoslemToJD converts a Moslem calendar date to a Julian Day.
 | 
						|
 * @param {Number} y - year in moslem calendar
 | 
						|
 * @param {Number} m - month
 | 
						|
 * @param {Number} d - day
 | 
						|
 * @returns {Number} jd - Julian day
 | 
						|
 */
 | 
						|
function MoslemToJD (y, m, d) { // (y, m, d int)  (jY, jDN int)
 | 
						|
  const N = d + base["default"].floorDiv(295001 * (m - 1) + 9900, 10000);
 | 
						|
  const Q = base["default"].floorDiv(y, 30);
 | 
						|
  const R = y % 30;
 | 
						|
  const A = base["default"].floorDiv(11 * R + 3, 30);
 | 
						|
  const W = 404 * Q + 354 * R + 208 + A;
 | 
						|
  const Q1 = base["default"].floorDiv(W, 1461);
 | 
						|
  const Q2 = W % 1461;
 | 
						|
  const G = 621 + 28 * Q + 4 * Q1;
 | 
						|
  const K = base["default"].floorDiv(Q2 * 10000, 3652422);
 | 
						|
  const E = base["default"].floorDiv(3652422 * K, 10000);
 | 
						|
  let J = Q2 - E + N - 1;
 | 
						|
  let X = G + K;
 | 
						|
  if (J > 366 && X % 4 === 0) {
 | 
						|
    J -= 366;
 | 
						|
    X++;
 | 
						|
  } else if (J > 365 && X % 4 > 0) {
 | 
						|
    J -= 365;
 | 
						|
    X++;
 | 
						|
  }
 | 
						|
  const jd = base["default"].floorDiv(36525 * (X - 1), 100) + 1721423 + J;
 | 
						|
  return jd
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * MoslemLeapYear returns true if year y of the Moslem calendar is a leap year.
 | 
						|
 * @param {Number} year
 | 
						|
 * @returns {Boolean} true if leap year
 | 
						|
 */
 | 
						|
function MoslemLeapYear (year) { // (y int)  bool
 | 
						|
  const R = year % 30;
 | 
						|
  return (11 * R + 3) % 30 > 18
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @typedef {object} DateObj
 | 
						|
 * @property {number} year
 | 
						|
 * @property {number} month
 | 
						|
 * @property {number} day
 | 
						|
 */
 | 
						|
 | 
						|
/**
 | 
						|
 * JulianToMoslem takes a year, month, and day of the Julian calendar and returns the equivalent year, month, and day of the Moslem calendar.
 | 
						|
 *
 | 
						|
 * @param {Number} y - julian year
 | 
						|
 * @param {Number} m - julian month
 | 
						|
 * @param {Number} d - julian day
 | 
						|
 * @returns {DateObj}
 | 
						|
 */
 | 
						|
function JulianToMoslem (y, m, d) { // (y, m, d int)  (my, mm, md int)
 | 
						|
  let W = 2;
 | 
						|
  if (y % 4 === 0) {
 | 
						|
    W = 1;
 | 
						|
  }
 | 
						|
  const N = base["default"].floorDiv(275 * m, 9) - W * base["default"].floorDiv(m + 9, 12) + d - 30;
 | 
						|
  const A = int(y - 623);
 | 
						|
  const B = base["default"].floorDiv(A, 4);
 | 
						|
  const C2 = (function (A) {
 | 
						|
    const C = A % 4;
 | 
						|
    const C1 = 365.25001 * (C);
 | 
						|
    const C2 = Math.floor(C1);
 | 
						|
    if (C1 - C2 > 0.5) {
 | 
						|
      return int(C2) + 1
 | 
						|
    }
 | 
						|
    return int(C2)
 | 
						|
  })(A);
 | 
						|
  const Dp = 1461 * B + 170 + C2;
 | 
						|
  const Q = base["default"].floorDiv(Dp, 10631);
 | 
						|
  const R = Dp % 10631;
 | 
						|
  const J = base["default"].floorDiv(R, 354);
 | 
						|
  const K = R % 354;
 | 
						|
  const O = base["default"].floorDiv(11 * J + 14, 30);
 | 
						|
  let my = 30 * Q + J + 1;
 | 
						|
  let JJ = K - O + N - 1;
 | 
						|
  let days = 354;
 | 
						|
  if (MoslemLeapYear(y)) {
 | 
						|
    days++;
 | 
						|
  }
 | 
						|
  if (JJ > days) {
 | 
						|
    JJ -= days;
 | 
						|
    my++;
 | 
						|
  }
 | 
						|
  let mm;
 | 
						|
  let md;
 | 
						|
  if (JJ === 355) {
 | 
						|
    mm = 12;
 | 
						|
    md = 30;
 | 
						|
  } else {
 | 
						|
    const S = base["default"].floorDiv((JJ - 1) * 10, 295);
 | 
						|
    mm = 1 + S;
 | 
						|
    md = base["default"].floorDiv(10 * JJ - 295 * S, 10);
 | 
						|
  }
 | 
						|
  return { year: my, month: mm, day: md }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * An MMonth specifies a month of the Moslum Calendar (Muharram = 1, ...).
 | 
						|
 *
 | 
						|
 * Upgraded to Unicode from the spellings given by Meeus.
 | 
						|
 * Source: http://en.wikipedia.org/wiki/Islamic_calendar.
 | 
						|
 */
 | 
						|
const mmonths = [
 | 
						|
  '',
 | 
						|
  'Muḥarram',
 | 
						|
  'Ṣafar',
 | 
						|
  'Rabīʿ I',
 | 
						|
  'Rabīʿ II',
 | 
						|
  'Jumādā I',
 | 
						|
  'Jumādā II',
 | 
						|
  'Rajab',
 | 
						|
  'Shaʿbān',
 | 
						|
  'Ramaḍān',
 | 
						|
  'Shawwāl',
 | 
						|
  'Dhū al-Qaʿda',
 | 
						|
  'Dhū al-Ḥijja'
 | 
						|
];
 | 
						|
 | 
						|
/**
 | 
						|
 * String returns the Romanization of the month ("Muḥarram", "Ṣafar", ...).
 | 
						|
 */
 | 
						|
function moslemMonth (m) {
 | 
						|
  return mmonths[m]
 | 
						|
}
 | 
						|
 | 
						|
var jm = {
 | 
						|
  JewishCalendar,
 | 
						|
  MoslemToJD,
 | 
						|
  MoslemLeapYear,
 | 
						|
  JulianToMoslem,
 | 
						|
  moslemMonth
 | 
						|
};
 | 
						|
 | 
						|
exports.JewishCalendar = JewishCalendar;
 | 
						|
exports.JulianToMoslem = JulianToMoslem;
 | 
						|
exports.MoslemLeapYear = MoslemLeapYear;
 | 
						|
exports.MoslemToJD = MoslemToJD;
 | 
						|
exports["default"] = jm;
 | 
						|
exports.moslemMonth = moslemMonth;
 |