UNPKG

mm-cal-js

Version:
188 lines (174 loc) 5.65 kB
import { LUNAR_MONTH, MYANMAR_ERA_START, SOLAR_YEAR } from "./constants"; import { getMyanmarConstants } from "./myanmar-year-constants"; /** * Julian day number to Myanmar date * @param julianDay : julian day number * @returns myanmarYearType = year type [0=common, 1=little watat, 2=big watat] * @returns month = [ * Tagu=1, Kason=2, Nayon=3, 1st Waso=0, 2nd Waso=4, * Wagaung=5, Tawthalin=6, Thadingyut=7, Tazaungmon=8, * Nadaw=9, Pyatho=10, Tabodwe=11, Tabaung=12, * Late Tagu=13, Late Kason=14] * @returns monthType = [0=Hnaung, 1=Oo] * @returns monthLength = [29 or 30 days] * @returns monthDay = [1 to 30] * @returns fortnightDay = [1 to 15] * @returns moonPhase = [0=waxing, 1=full moon, 2=waning, 3=new moon] * @returns weekDay = [0=sat, 1=sun, 2=mon, 3=tue, 4=wed, 5=thu, 6=fri] */ export const julianToMyanmarDate = (julianDay: number) => { // convert jd to jdn // jdn let julianDayNumber = Math.round(julianDay); // myear let myanmarYear = Math.floor( (julianDayNumber - 0.5 - MYANMAR_ERA_START) / SOLAR_YEAR ); // check year let yo = checkMyanmarYear(myanmarYear); // dd let dayCount = julianDayNumber - yo.tagu1 + 1; let b =Math.floor( yo.myanmarYearType / 2); // big wa and common year let c = Math.floor(1 / (yo.myanmarYearType + 1)); // year length let yearLength = 354 + (1 - c) * 30 + b; // month type: Hnaung = 1 or Oo = 0 | late = 1 or early = 0 let monthType = Math.floor((dayCount -1)/yearLength); dayCount -= monthType * yearLength; // adjust day count and threshold let a = Math.floor((dayCount + 423) / 512); // month let month = Math.floor((dayCount - b * a + c * a * 30 + 29.26) / 29.544); let e =Math.floor( (month + 12) / 16); let f = Math.floor((month + 11) / 16); // day of month let monthDay = dayCount - Math.floor(29.544 * month - 29.26) - b * e + c * f * 30; // adjust month numbers for late months month += f * 3 - e * 4 + 12 * monthType; let monthLength = 30 - (month % 2); if (month === 3) { // adjust if Nayon in big watat monthLength += yo.myanmarYearType / 2; } // moon phase from day of the month, month, and year type // [0=waxing, 1=full moon, 2=waning, 3=new moon] let moonPhase = (monthDay + 1) / 16 + monthDay / 16 + monthDay / monthLength; // fortnight day from month day // waxing or waning day let fortnightDay = monthDay - 15 * (monthDay / 16); // week day let weekDay = (julianDayNumber + 2) % 7; return { myanmarYear, myanmarYearType: yo.myanmarYearType, yearLength, month, monthType, monthLength, monthDay, // moonPhase, // fortnightDay, weekDay, julianDay, }; }; /** * Check watat (intercalary month) (chk_watat) * @param myanmarYear Myanmar year * @returns watat = intercalary month [1=watat, 0=common] * @returns fm = full moon day of 2nd Waso in jdn_mm (jdn+6.5 for MMT) [only valid when watat=1] */ export const checkWatat = (myanmarYear: number) => { // get constants for the corresponding calendar era let myanmarConstants = getMyanmarConstants(myanmarYear); // threshold to adjust let threshold = (SOLAR_YEAR / 12 - LUNAR_MONTH) * (12 - myanmarConstants.NUMBER_OF_MONTHS); // excess day let excessDays = (SOLAR_YEAR * (myanmarYear + 3739)) % LUNAR_MONTH; if (excessDays < threshold) { // adjust excess days excessDays += LUNAR_MONTH; } // full moon day of 2nd Waso let fullMoon = Math.round( SOLAR_YEAR * myanmarYear + MYANMAR_ERA_START - excessDays + 4.5 * LUNAR_MONTH + myanmarConstants.WATAT_OFFSET ); let watat = 0; // find watat if (myanmarConstants.ERA_ID >= 2) { // if 2nd era or later, find watat based on excess days let tw = LUNAR_MONTH - (SOLAR_YEAR / 12 - LUNAR_MONTH) * myanmarConstants.NUMBER_OF_MONTHS; if (excessDays >= tw) { watat = 1; } } else { // if 1st era, find watat by 19 years metonic cycle // Myanmar year is divided by 19 and there is an intercalary month // if the remainder is 2, 5, 7, 10, 13, 15, 18 // https://github.com/kanasimi/CeJS/blob/master/data/date/calendar.js#L2330 watat = (myanmarYear * 7 + 2) % 19; if (watat < 0) { watat += 19; } watat = Math.floor(watat / 12.0); } // correct watat exceptions watat ^= myanmarConstants.EXCEPTION_IN_WATAT_YEAR; return { fullMoon, // fm watat, // watat }; }; /** * Check Myanamr year (chk_my) * depenency: chk_watat(my) * @param myanmarYear Myanmar year * @returns map * myanmarYearType = year type [0=common, 1=little watat, 2=big watat] (myt) * tagu1 = the 1st day of Tagu as Julian Day Number (Julian Day Number for MMT) tg1 * fullMoon = full moon day of [2nd] Waso as Julian Day Number (fm) * watatError = [0=ok, 1=error] (werr) */ export const checkMyanmarYear = (myanmarYear: number) => { let y2 = checkWatat(myanmarYear); let myanmarYearType = y2!.watat; let yd = 0; let y1: | { fullMoon: number; watat: number; } | undefined = undefined; do { yd++; y1 = checkWatat(myanmarYear - yd); } while (y1!.watat === 0 && yd < 3); let fullMoon: number = 0; let watatError = 0; if (myanmarYearType) { let nd = (y2!.fullMoon - y1!.fullMoon) % 354; myanmarYearType = Math.floor(nd / 31) + 1; fullMoon = y2!.fullMoon; if (nd != 30 && nd != 31) { watatError = 1; } } else { fullMoon = y1!.fullMoon + 354 * yd; } let tagu1 = y1!.fullMoon + 354 * yd - 102; return { myanmarYearType, // myt tagu1, // tg1 fullMoon: fullMoon, // fm watatError, // werr }; };