/*
* 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;
}
}