/* * kollavarsham * http://kollavarsham.org * * Copyright (c) 2014-2023 The Kollavarsham Team * Licensed under the MIT license. */ /** * @module calculations */ import { Calendar } from './calendar'; import { Celestial } from './celestial/index'; import { JulianDate } from './dates/julianDate'; import { KollavarshamDate } from './dates/kollavarshamDate'; import { MathHelper } from './mathHelper'; import { SakaDate } from './dates/sakaDate'; const Ujjain = { system: '', latitude: 23.2, longitude: 75.8 }; /** * * **INTERNAL/PRIVATE** * * @class Calculations */ export class Calculations { constructor(settings) { this.longitude = settings.longitude; this.latitude = settings.latitude; this.celestial = new Celestial(settings.system); this.calendar = new Calendar(this.celestial); } static getPaksa(tithi) { return tithi >= 15 ? 'Krsnapaksa' : 'Suklapaksa'; } fromGregorianToSaka(gregorianDate) { const year = gregorianDate.getFullYear(); const julianDay = Calendar.gregorianDateToJulianDay(gregorianDate); const ahargana = Calendar.julianDayToAhargana(julianDay); // Calculate the SakaDate at 6 AM const timeAsFractionalDayAt6AM = 0.25; // time at 6 o'clock const sakaDate = this.celestialCalculations(ahargana, year, julianDay, timeAsFractionalDayAt6AM); // Calculate the SakaDate at the given time // (this is done only for the resulting the naksatra, which now has better precision) const timeFromGregorianDate = Calendar.timeIntoFractionalDay(gregorianDate); const sakaDateAtGivenTime = this.celestialCalculations(ahargana, year, julianDay, timeFromGregorianDate); sakaDate.naksatra = sakaDateAtGivenTime.naksatra; sakaDate.gregorianDate = gregorianDate; // set the input gregorian date return sakaDate; } celestialCalculations(ahargana, year, julianDay, timeAsFractionalDay) { ahargana += timeAsFractionalDay; // Definition of desantara // http://books.google.com/books?id=kt9DIY1g9HYC&pg=PA683&lpg=PA683&dq=desantara&source=bl&ots=NLd1wFKFfN&sig=jCfG95R-6eiSff3L73DCodijo1I&hl=en&sa=X&ei=uKgHU__uKOr7yAGm0YGoBQ&ved=0CF8Q6AEwCDgK#v=onepage&q=desantara&f=false const desantara = (this.longitude - Ujjain.longitude) / 360; // desantara ahargana -= desantara; // time of sunrise at local latitude const equationOfTime = this.celestial.getDaylightEquation(year, this.latitude, ahargana); ahargana -= equationOfTime; const { sunriseHour, sunriseMinute } = Celestial.getSunriseTime(timeAsFractionalDay, equationOfTime); const { trueSolarLongitude, trueLunarLongitude } = this.celestial.setPlanetaryPositions(ahargana); // finding tithi and longitude of conjunction const tithi = Celestial.getTithi(trueSolarLongitude, trueLunarLongitude); // last conjunction & next conjunction const lastConjunctionLongitude = this.celestial.getLastConjunctionLongitude(ahargana, tithi); const nextConjunctionLongitude = this.celestial.getNextConjunctionLongitude(ahargana, tithi); const masaNum = Calendar.getMasaNum(trueSolarLongitude, lastConjunctionLongitude); // kali and Saka era const kaliYear = this.calendar.aharganaToKali(ahargana + (4 - masaNum) * 30); const sakaYear = Calendar.kaliToSaka(kaliYear); let tithiDay = MathHelper.truncate(tithi) + 1; const paksa = Calculations.getPaksa(tithiDay); tithiDay = tithiDay >= 15 ? tithiDay -= 15 : tithiDay; const { sauraMasa, sauraDivasa } = this.calendar.getSauraMasaAndSauraDivasa(ahargana, desantara); const sakaDate = new SakaDate(sakaYear, masaNum, tithiDay, paksa); sakaDate.julianDay = MathHelper.truncate(julianDay + 0.5); sakaDate.ahargana = MathHelper.truncate(ahargana + 0.5); // Remove the decimals sakaDate.originalAhargana = ahargana; sakaDate.sauraMasa = sauraMasa; sakaDate.sauraDivasa = sauraDivasa; sakaDate.naksatra = Calendar.getNaksatra(trueLunarLongitude); sakaDate.kaliYear = kaliYear; sakaDate.adhimasa = Calendar.getAdhimasa(lastConjunctionLongitude, nextConjunctionLongitude); sakaDate.fractionalTithi = MathHelper.fractional(tithi); sakaDate.sunriseHour = sunriseHour; sakaDate.sunriseMinute = sunriseMinute; return sakaDate; } fromGregorian(gregorianDate) { const sakaDate = this.fromGregorianToSaka(gregorianDate); return sakaDate.generateKollavarshamDate(); } toGregorian(kollavarshamDate) { // TODO: Implement this to convert a Kollavarsham date to Gregorian console.log('kollavarshamDate: ' + JSON.stringify(kollavarshamDate)); // eslint-disable-line no-console throw new Error('Not implemented'); } toGregorianFromSaka(sakaDate) { // TODO: Remove this method?? // This is implemented specifically for the pancanga-nodejs cli (https://github.com/kollavarsham/pancanga-nodejs) // Could be removed when toGregorian has been implemented based on this const sakaYear = sakaDate.year; const masaNum = sakaDate.month; let tithiDay = sakaDate.tithi; const paksa = sakaDate.paksa; if (paksa === 'Krsnapaksa') { tithiDay += 15; } const kaliYear = Calendar.sakaToKali(sakaYear); const ahargana = this.calendar.kaliToAhargana(kaliYear, masaNum, tithiDay); let julianDay = Calendar.aharganaToJulianDay(ahargana); julianDay += 0.5; const modernDate = Calendar.julianDayToModernDate(julianDay); if (JulianDate.prototype.isPrototypeOf(modernDate)) { // eslint-disable-line no-prototype-builtins console.log('\nkollavarsham::toGregorianDate: *** Returning an instance of JulianDate class ***'); // eslint-disable-line no-console } // TODO: Not happy that the empty constructor will make this with MalayalamYear => 1, MalayalamMonth => 1, and MalayalamDate => 1 // TODO: Think this through before implementing toGregorian above const kollavarshamDate = new KollavarshamDate(); kollavarshamDate.gregorianDate = modernDate; kollavarshamDate.julianDay = julianDay; kollavarshamDate.ahargana = ahargana; kollavarshamDate.sakaDate = sakaDate; return kollavarshamDate; } }