UNPKG

@marchingy/lunar

Version:

Chinese calendar with the 24 solar terms.

123 lines (122 loc) 5.88 kB
(function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "ephemeris", "./tool", "./intl", "./lunar-calendar"], factory); } })(function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getTermsOnYear = exports.countSolarTerms = exports.getTermOnDay = exports.calcDiffOfSunAndMoon = exports.calcSunEclipticLongitude = exports.calcMoonEclipticLongitude = exports.create24SolarTerms = exports.SolarTerm = void 0; const ephemeris_1 = require("ephemeris"); const tool_1 = require("./tool"); const intl_1 = require("./intl"); const lunar_calendar_1 = require("./lunar-calendar"); /** * @description GB/T 33661-2017 农历的编算和颁行 * @link http://c.gb688.cn/bzgk/gb/showGb?type=online&hcno=E107EA4DE9725EDF819F33C60A44B296 */ class SolarTerm { constructor(order, label) { this.label = label; this.toString = () => { var _a; return `${this.label}` + (this.date ? ` ${(_a = this.date) === null || _a === void 0 ? void 0 : _a.toChineseString()}` : ``); }; if (order < 1 || order > 24 || order % 1 !== 0) { throw new Error(`Illegal parameter "order": ${order}, this must be an integer from 1 to 24.`); } this.order = order; this.longitude = (order - 1) * 15; } isMidTerm() { return this.longitude % 30 === 0; } static create(index, lang = intl_1.SOLAR_TERMS_ZH) { return new SolarTerm((0, tool_1.coerceInteger)(index), lang[index - 1]); } } exports.SolarTerm = SolarTerm; function create24SolarTerms(lang = intl_1.SOLAR_TERMS_ZH) { const terms = new Map(); for (let i = 1; i <= 24; i++) { terms.set(i, SolarTerm.create(i, lang)); } return terms; } exports.create24SolarTerms = create24SolarTerms; function calcMoonEclipticLongitude(targetDate, coordinate = intl_1.CH_STANDARD_POSITION) { return (0, ephemeris_1.getPlanet)('moon', targetDate, coordinate[0], coordinate[1], 0).observed.moon.apparentLongitudeDd; } exports.calcMoonEclipticLongitude = calcMoonEclipticLongitude; ; function calcSunEclipticLongitude(targetDate, coordinate = intl_1.CH_STANDARD_POSITION) { return (0, ephemeris_1.getPlanet)('sun', targetDate, coordinate[0], coordinate[1], 0).observed.sun.apparentLongitudeDd; } exports.calcSunEclipticLongitude = calcSunEclipticLongitude; ; function calcDiffOfSunAndMoon(time, coordinate = intl_1.CH_STANDARD_POSITION) { const sunResult = calcSunEclipticLongitude(time, coordinate); const moonResult = calcMoonEclipticLongitude(time, coordinate); return Math.min(Math.abs(sunResult - moonResult), Math.abs(sunResult - (moonResult - 360)), Math.abs((sunResult - 360) - moonResult), Math.abs((sunResult - 360) - (moonResult - 360))); } exports.calcDiffOfSunAndMoon = calcDiffOfSunAndMoon; function getTermOnDay(date, coordinate = intl_1.CH_STANDARD_POSITION) { const dateS = new Date(date.getFullYear(), date.getMonth(), date.getDate()); const dateE = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59); let eclipticLngS = (0, tool_1.toPrecision)(calcSunEclipticLongitude(dateS, coordinate), 3); const eclipticLngE = (0, tool_1.toPrecision)(calcSunEclipticLongitude(dateE, coordinate), 3); let result = null; let x = Math.floor(eclipticLngE); // An integer; if (eclipticLngS > eclipticLngE) { eclipticLngS = eclipticLngS - 360; } do { if (x % 15 === 0 && eclipticLngS <= x && eclipticLngE >= x) { const index = x / 15 + 1; if (index >= 1 && index <= 24) { result = SolarTerm.create(index); result.date = new lunar_calendar_1.ChineseDate(date); break; } } x--; } while (x > eclipticLngS); return result; } exports.getTermOnDay = getTermOnDay; function countSolarTerms(fromDate, toDate, coordinate = intl_1.CH_STANDARD_POSITION) { const terms = []; let startDate; let endDate; let target; if (fromDate.getTime() <= toDate.getTime()) { startDate = new Date(fromDate.getFullYear(), fromDate.getMonth(), fromDate.getDate()); endDate = new Date(toDate.getFullYear(), toDate.getMonth(), toDate.getDate()); } else { startDate = new Date(toDate.getFullYear(), toDate.getMonth(), toDate.getDate()); endDate = new Date(fromDate.getFullYear(), fromDate.getMonth(), fromDate.getDate()); } do { target = getTermOnDay(startDate, coordinate); if (target) { terms.push(target); startDate.setDate(startDate.getDate() + 13); continue; } startDate.setDate(startDate.getDate() + 1); } while (startDate.getTime() <= endDate.getTime()); return terms; } exports.countSolarTerms = countSolarTerms; /** * This method will countSolarTerms with params that are the first date and the latest date of the year. */ function getTermsOnYear(year, coordinate = intl_1.CH_STANDARD_POSITION) { return countSolarTerms(new Date(year, 0, 1, 0, 0, 0, 0), new Date(year, 11, 31, 23, 59, 59, 999), coordinate); } exports.getTermsOnYear = getTermsOnYear; });