Panchang Core — Advanced Vedic Astrology Engine for PHP
Introduction
Authentic Vedic Panchanga calculation engine with Swiss Ephemeris precision.
Overview
Panchang Core is a comprehensive PHP package for calculating Vedic Panchanga elements, Muhūrtas, and Hindu festivals with maximum astronomical precision. Built on Swiss Ephemeris FFI, it provides zero-tolerance calculations for authentic Vedic astrology applications.
Complete Panchanga
Tithi, Vara, Nakṣatra, Yoga, Karaṇa with precise fractions
162 Hindu Festivals
Comprehensive library covering major and minor festivals for all regions and traditions.
Muhūrta
Abhijit, Brahma Muhūrta, Rahu Kāla, Gulika, Yamaganda
Regional Support
Smarta, Vaishnava, North, South, Bengal, Maharashtra, Tamil traditions
Classical Sources
| Text | Implementation |
|---|---|
| Sūrya Siddhānta (Sage-Attributed) | |
| Sūrya Siddhānta 1.29 | Tithi calculation |
| Sūrya Siddhānta 8.1 | Nakṣatra calculation |
| Sūrya Siddhānta | Yoga, Karana |
| Sūrya Siddhānta 1.10 | Muhūrta |
| Sūrya Siddhānta 1.11 | Ghaṭikā, Pala |
| Bṛhat Parāśara Horā Śāstra (BPHS) | |
| BPHS | Vimśottarī Daśā System, Nakṣatra lords, Daśā years |
| BPHS | Horā |
| Bṛhat Saṃhitā (Varāhamihira) | |
| Bṛhat Saṃhitā 8 | Samvatsara |
| Bṛhat Saṃhitā | Ritu |
| Muhūrta & Kāla Nirṇaya | |
| Muhūrta Chintāmaṇi | Aruṇodaya, Pradoṣa, Bhadra |
| Ashtānga Hṛdaya | Brahma Muhūrta |
| Charaka Saṃhitā | Muhūrta |
| Kāla Nirṇaya | Choghadiya |
| Festival Resolution | |
| Nirṇaya Sindhu | Bhadra rules, Festival timing |
| Dharma Sindhu | Holikā Dahan, Vṛddhi/Kṣaya |
| Hari Bhakti Vilāsa | Ekādaśī |
| Modern Astronomy | |
| Swiss Ephemeris | Vara (weekday), Ayanāṃśa, Graha Sphuṭa |
Installation
composer require jayeshmepani/panchang-core
Requirements
- PHP 8.3+— uses typed constants, readonly classes, enums
- Swiss Ephemeris FFI— jayeshmepani/swiss-ephemeris-ffi
- Carbon— nesbot/carbon
- FFI Extension— required for Swiss Ephemeris
Quick Start
<?php
require 'vendor/autoload.php';
use JayeshMepani\PanchangCore\Panchanga\PanchangService;
use JayeshMepani\PanchangCore\Astronomy\AstronomyService;
use JayeshMepani\PanchangCore\Astronomy\SunService;
use JayeshMepani\PanchangCore\Panchanga\PanchangaEngine;
use JayeshMepani\PanchangCore\Panchanga\MuhurtaService;
use JayeshMepani\PanchangCore\Festivals\FestivalService;
use JayeshMepani\PanchangCore\Festivals\FestivalRuleEngine;
use JayeshMepani\PanchangCore\Festivals\FestivalFamilyOrchestrator;
use JayeshMepani\PanchangCore\Festivals\Utils\BhadraEngine;
use SwissEph\FFI\SwissEphFFI;
use Carbon\CarbonImmutable;
// Initialize services
$sweph = new SwissEphFFI();
$ruleEngine = new FestivalRuleEngine();
$orchestrator = new FestivalFamilyOrchestrator();
$panchang = new PanchangService(
$sweph,
new SunService($sweph),
new AstronomyService($sweph),
new PanchangaEngine(),
new MuhurtaService(),
new FestivalService($ruleEngine, $orchestrator),
new BhadraEngine()
);
// Calculate panchanga
$date = CarbonImmutable::parse('2026-03-24');
$details = $panchang->getDayDetails(
date: $date,
lat: 23.2472446,
lon: 69.668339,
tz: 'Asia/Kolkata'
);
echo "Tithi: " . $details['Tithi']['name'] . "\n";
echo "Nakshatra: " . $details['Nakshatra']['name'] . "\n";
Configuration
Global settings and formatting preferences available in config/panchang.php.
Overview
When running inside Laravel, you can publish the configuration file to config/panchang.php.
These settings control the default formatting across the entire package output, allowing you to globally
enforce timezone notations, unit systems, and double precision decimals.
Default Calculation Options
The defaultsarray configures formatting representations.
| Setting | Description | Acceptable Values |
|---|---|---|
measurement_system |
Unit system for generic dimensions and lengths. | indian_metric: Metric (meters, km)western: Imperial (feet, miles)
|
date_time_format |
String formatting of generic date-time outputs. | indian_12h: "24/03/2026 06:14:00 AM"indian_24h: "24/03/2026
06:14:00"iso8601: "2026-03-24T06:14:00+05:30" |
time_notation |
Global time output behavior (sunrise, sunset, muhurtas). | 12h: "06:14:00 AM"24h: "06:14:00" |
coordinate_format |
Format for geographical coordinates. | decimal: 23.2472446, 69.668339dms: "23°14'50.1\"N, 69°40'06.0\"E"
|
angle_unit |
Format for astronomical degrees (planet longitudes, Ascendant, Ayanamsa). | degree: 350.5234°dms: "350°31'24\"" |
duration_format |
How lengths of time are formatted. | mixed: "1h 30m 0s"minutes: 90.0seconds:
5400.0hours: 1.5 |
number_precision |
Decimal points for all floating-point and angular outputs. Maximum accuracy guaranteed via IEEE 754. | Integer (Default: 16) |
Festival Calculation Settings
The festivalsarray provides defaults for region and tradition if not explicitly supplied.
| Setting | Description | Acceptable Values |
|---|---|---|
default_tradition |
Default sect or tradition used to resolve conflicting festival rules. | Smarta, Vaishnava |
default_region |
Default geographical region for festival rule variations. | North, South, Bengal, Maharashtra,
Tamil
|
Timing Semantics
- Time-only fields include date-qualified companion keys as
*_isowhere applicable. - Panchang day is evaluated from sunrise to next sunrise; times earlier than sunrise belong to next civil date.
Varjyamsupports multiple windows viawindow_countandwindows[].Pradosha_Kaalin day output includes base night window and Trayodashi-overlap effective window.
Nakshatra
Enum: JayeshMepani\PanchangCore\Core\Enums\Nakshatra
Represents the 27 lunar mansions in Vedic astrology. Each nakṣatra spans 13°20' of the zodiac.
Quick Usage
use JayeshMepani\PanchangCore\Core\Enums\Nakshatra;
// Get nakshatra from moon longitude
$nakshatra = Nakshatra::fromLongitude(125.3); // Magha
echo $nakshatra->getName(); // "Magha"
echo $nakshatra->getDeity(); // "Pitṛs"
echo $nakshatra->getRulingPlanet(); // "Sun"
echo $nakshatra->getSymbol(); // "Royal Throne"
// Get pada (quarter)
$pada = Nakshatra::getPada(125.3); // 2
echo "Pada: $pada\n"; // Pada: 2
// Get longitude range
$range = Nakshatra::Ashwini->getLongitudeRange();
echo $range['start'] . "° - " . $range['end'] . "°\n"; // 0° - 13.333°
Cases
AshwiniBharaniKrittikaRohiniMrigashiraArdraPunarvasuPushyaAshleshaMaghaPurvaPhalguniUttaraPhalguniHastaChitraSwatiVishakhaAnuradhaJyeshthaMulaPurvaAshadhaUttaraAshadhaShravanaDhanishtaShatabhishaPurvaBhadrapadaUttaraBhadrapadaRevatiMethods
getName()
Get Sanskrit name
public function getName(): stringstring— Sanskrit namegetDeity()
Get deity of the nakṣatra
public function getDeity(): stringstring— Deity namegetRulingPlanet()
Get ruling planet
public function getRulingPlanet(): stringstring— Planet namegetSymbol()
Get Vedic symbol
public function getSymbol(): stringstring— Symbol descriptiongetLongitudeRange()
Get Vedic longitude range
public function getLongitudeRange(): array{start: float, end: float}
array— Longitude range in degrees fromLongitude()
Get nakṣatra from longitude
public static function fromLongitude(float $longitude): self
$longitude(float) — Longitude in degrees (0–360)
self— Nakṣatra instancegetPada()
Get pada (quarter) from longitude
public static function getPada(float $longitude): int$longitude(float) — Longitude in degrees
int— Pada number (1–4)Tithi
Enum: JayeshMepani\PanchangCore\Core\Enums\Tithi
Represents the 30 lunar days in a Hindu lunar month. Each tithi is completed when the Moon gains 12° on the Sun.
Quick Usage
use JayeshMepani\PanchangCore\Core\Enums\Tithi;
// Get tithi by index (1-30)
$tithi = Tithi::from(12); // Shukla Dwadashi
echo $tithi->getName(); // "Dwadashi"
echo $tithi->getPaksha()->name; // "Shukla"
// Check paksha
if ($tithi->getPaksha() === Paksha::Shukla) {
echo "Waxing moon phase\n";
}
// Get normalized index (1-15 for both pakshas)
echo $tithi->getNormalizedIndex(); // 12
Cases
ShuklaPratipadaShuklaDwitiyaShuklaTritiyaShuklaChaturthiShuklaPanchamiShuklaShashthiShuklaSaptamiShuklaAshtamiShuklaNavamiShuklaDashamiShuklaEkadashiShuklaDwadashiShuklaTrayodashiShuklaChaturdashiPurnimaKrishnaPratipadaKrishnaDwitiyaKrishnaTritiyaKrishnaChaturthiKrishnaPanchamiKrishnaShashthiKrishnaSaptamiKrishnaAshtamiKrishnaNavamiKrishnaDashamiKrishnaEkadashiKrishnaDwadashiKrishnaTrayodashiKrishnaChaturdashiAmavasyaMethods
getName()
Get Sanskrit name
public function getName(): stringstring— Name (e.g., 'Pratipada',
'Purnima')getPaksha()
Get pakṣa (fortnight)
public function getPaksha(): PakshaPaksha— Shukla or KrishnagetNormalizedIndex()
Get normalized index (1–15)
public function getNormalizedIndex(): intint— Index within pakṣaisEkadashi()
Check if this is Ekadashi
public function isEkadashi(): boolboolisPurnimaOrAmavasya()
Check if Purnima or Amavasya
public function isPurnimaOrAmavasya(): boolboolfromLongitudes()
Get tithi from Sun-Moon longitudes
public static function fromLongitudes(float $sunLon, float $moonLon): self
$sunLon(float) — Sun longitude in degrees$moonLon(float) — Moon longitude in degrees
selfgetFractionRemaining()
Get fraction remaining in tithi
public static function getFractionRemaining(float $sunLon, float $moonLon): float
float— Fraction (0.0–1.0)Paksha
Enum: JayeshMepani\PanchangCore\Core\Enums\Paksha
Represents the two fortnights in a lunar month.
Cases
ShuklaKrishnaMethods
getName()
Get Sanskrit name
public function getName(): stringgetDescription()
Get description
public function getDescription(): stringgetTithiRange()
Get tithi range
public function getTithiRange(): array{start: int, end: int}
containsTithi()
Check if tithi belongs to this pakṣa
public function containsTithi(int $tithiIndex): boolnormalizeTithi()
Normalize tithi to 1–15 range
public function normalizeTithi(int $tithiIndex): intYoga
Enum: JayeshMepani\PanchangCore\Core\Enums\Yoga
Represents the 27 yogas. Each yoga is completed when the Sun-Moon longitude sum advances by 13°20'.
Cases
VishkambhaPritiAyushmanSaubhagyaShobhanaAtigandaSukarmaDhritiShulaGandaVriddhiDhruvaVyaghataHarshanaVajraSiddhiVyatipataVariyanaParighaShivaSiddhaSadhyaShubhaShuklaBrahmaAindraVaidhritiMethods
getName()
Get Sanskrit name
public function getName(): stringfromLongitudes()
Get yoga from Sun-Moon longitudes
public static function fromLongitudes(float $sunLon, float $moonLon): self
Karana
Enum: JayeshMepani\PanchangCore\Core\Enums\Karana
Represents the 11 karanas (half lunar days). Each tithi is divided into two karanas.
Cases
BavaBalavaKaulavaTaitilaGaraVanijaVishtiShakuniChatushpadaNagaKimstughnaMethods
getName()
Get Sanskrit name
public function getName(): stringgetType()
Get type (Chara/Sthira)
public function getType(): stringisVishti()
Check if this is Vishti (Bhadra)
public function isVishti(): boolfromTithi()
Get karana from tithi
public static function fromTithi(int $tithiIndex, float $fraction): self
Vara
Enum: JayeshMepani\PanchangCore\Core\Enums\Vara
Represents the 7 weekdays, each ruled by a planet.
Cases
SundayMondayTuesdayWednesdayThursdayFridaySaturdayMethods
getName()
Get Sanskrit name
public function getName(): stringgetEnglishName()
Get English name
public function getEnglishName(): stringgetRulingPlanet()
Get ruling planet
public function getRulingPlanet(): stringfromJulianDay()
Get weekday from Julian Day
public static function fromJulianDay(float $jd): selfCore Enums
Basic enumeration types used throughout the package.
Ritu (Seasons)
Represents the 6 Hindu seasons. Each ṛtu spans 2 lunar months.
Vasanta(Spring)Grishma(Summer)Varsha(Monsoon)Sharad(Autumn)Hemanta(Pre-Winter)Shishira(Winter)PanchangaEngine::getRitu($sunLon)returns
season from Sun longitudeMasa (Lunar Months)
Represents the 12 lunar months in the Hindu calendar.
ChaitraVaishakhaJyeshthaAshadhaShravanaBhadrapadaAshvinaKartikaMargashirshaPaushaMaghaPhalgunaPanchangaEngine::getHinduMonth($sunLon, $moonLon)
Samvatsara (60-Year Cycle)
Represents the 60 years in the Jupiter cycle.
PrabhavaVibhavaShuklaPramodaPrajapati… (60 total)PanchangaEngine::getSamvatsara($vikramSamvat)
Rasi (Zodiac Signs)
Represents the 12 zodiac signs in Vedic astrology.
Mesha(Aries)Vrishabha(Taurus)Mithuna(Gemini)Karka(Cancer)Simha(Leo)Kanya(Virgo)Tula(Libra)Vrischika(Scorpio)Dhanu(Sagittarius)Makara(Capricorn)Kumbha(Aquarius)Meena(Pisces)Vimshottari Dasha
Planetary periods in Vedic astrology, summing to 120 years.
Ketu(7 yr)Venus(20 yr)Sun(6 yr)Moon(10 yr)Mars(7 yr)Rahu(18 yr)Jupiter(16 yr)Saturn(19 yr)Mercury(17 yr)Muhurta
Represents the 30 divisions of a day (approx 48 minutes each).
RudraAhiMitraPitriVasuVarahaVishvedevaVidhi… (30 total)MuhurtaService::calculateMuhurtaTable($sunrise, $sunset, $nextSunrise)
Choghadiya
8 day and night time divisions primarily used in North & West India.
Udveg(Inauspicious)Chal(Neutral)Labh(Auspicious)Amrita(Very Auspicious)Kala(Inauspicious)Shubh(Auspicious)Rog(Inauspicious)MuhurtaService::calculateChoghadiyaTable()
Hora
24 hourly planetary divisions of a day.
SunVenusMercuryMoonSaturnJupiterMarsMuhurtaService::calculateHoraTable()— Each
hora spans ~1 hourPanchangService
Service: JayeshMepani\PanchangCore\Panchanga\PanchangService
Facade-like service that orchestrates all underlying components to provide complete daily details.
Methods
getDayDetails()
Returns complete Panchanga details for a given date and location. Includes Tithi, Nakshatra, Yoga, Karana, Muhurta, Choghadiya, Hora, and festival data.
public function getDayDetails(CarbonImmutable $date, float $lat, float $lon, string $tz, float $elevation=0.0, ?CarbonImmutable $ayanamsaAt=null, array $options=[]): array
$date(CarbonImmutable) — Date to calculate$lat(float) — Latitude in degrees$lon(float) — Longitude in degrees$tz(string) — Timezone (e.g., 'Asia/Kolkata')$elevation(float, optional) — Elevation in meters (default: 0.0)$ayanamsaAt(CarbonImmutable, optional) — Custom ayanamsa calculation time$options(array, optional) — Additional options
array — Complete panchanga data with keys: Tithi, Nakshatra, Yoga, Karana, Vara, Muhurta, Choghadiya, Hora, Festivals, etc.getFestivalSnapshot()
Lightweight daily snapshot for festival resolution. Faster than getDayDetails when you only need festival data.
public function getFestivalSnapshot(CarbonImmutable $date, float $lat, float $lon, string $tz, float $elevation=0.0): array
$date(CarbonImmutable) — Date to calculate$lat(float) — Latitude$lon(float) — Longitude$tz(string) — Timezone$elevation(float, optional) — Elevation in meters
array — Festival data and minimal panchanga elements.configure()
Global configuration for the service (typically used in standalone mode).
public static function configure(string $ephePath, string $ayanamsa='LAHIRI'): void
$ephePath(string) — Absolute path to ephemeris files$ayanamsa(string) — 'LAHIRI', 'RAMAN', or 'KRISHNAMURTI'
AstronomyService
Service: JayeshMepani\PanchangCore\Astronomy\AstronomyService
Calculates planetary longitudes and Julian Days using Swiss Ephemeris.
Methods
toJulianDayUtc()
Convert birth data array to high-precision Julian Day (UTC).
public function toJulianDayUtc(array $birth): float
$birth(array) — Associative array: [year, month, day, hour, minute, second, timezone]
float — Julian Day number (UT1)getPlanets()
Returns all planetary longitudes for a given birth details.
public function getPlanets(array $birth): array
$birth(array) — Birth details with location and time.
array — Map of planet names to longitudinal degrees.getAscendant()
Calculate the Ascendant (Lagna) longitude for a specific time and location.
public function getAscendant(array $birth): float
$birth(array) — Birth details.
float — Ascendant longitude in degrees.getAyanamsa()
Get the ayanamsa (sidereal difference) value for a given Julian Day.
public function getAyanamsa(float $jd): float
$jd(float) — Julian Day (UTC).
float — Ayanamsa in decimal degrees.SunService
Service: JayeshMepani\PanchangCore\Astronomy\SunService
Calculates sunrise, sunset, and solar events using precision algorithms.
Methods
getSunriseSunset()
Calculate exact sunrise and sunset times for a location.
public function getSunriseSunset(array $birth): array
$birth(array) — Birth details with lat/lon and date.
array — [CarbonImmutable sunrise, CarbonImmutable sunset]getMoonriseMoonset()
Calculate moonrise and moonset times (geocentric).
public function getMoonriseMoonset(array $birth): array
$birth(array) — Birth details.
array — [CarbonImmutable moonrise, CarbonImmutable moonset]getTwilightTimes()
Calculate civil, nautical, and astronomical twilight boundaries.
public function getTwilightTimes(array $birth): array
$birth(array) — Birth details.
array — Map of twilight phases.isDayBirth()
Check if a specific time occurs between sunrise and sunset.
public function isDayBirth(array $birth): bool
$birth(array) — Birth details.
bool — True if daylight birth.PanchangaEngine
Service: JayeshMepani\PanchangCore\Panchanga\PanchangaEngine
Core panchanga calculation engine for tithi, yoga, karana, and seasonal logic (no ephemeris dependencies).
Methods
calculateTithi()
Calculate Tithi from Sun and Moon longitudes.
public function calculateTithi(float $sunLon, float $moonLon): array
$sunLon(float) — Sun longitude in degrees.$moonLon(float) — Moon longitude in degrees.
array — {index, name, paksha, fraction_left}
$tithi = $engine->calculateTithi(350.5, 125.3);
echo $tithi['name']; // "Dwadashi"
getNakshatraInfo()
Determine Nakshatra and Pada from a specific longitude.
public function getNakshatraInfo(float $longitude): array
$longitude(float) — Celestial longitude in degrees.
array — [name, pada, lord]calculateYoga()
Calculate Yoga from the sum of Sun and Moon longitudes.
public function calculateYoga(float $sunLon, float $moonLon): array
$sunLon(float) — Sun longitude.$moonLon(float) — Moon longitude.
array — {index, name}getKarana()
Get the Karana (half-tithi) from celestial longitudes.
public function getKarana(float $sunLon, float $moonLon): array
$sunLon(float) — Sun longitude.$moonLon(float) — Moon longitude.
array — [name, number]calculateVara()
Calculate weekday (Vara) relative to local sunrise.
public function calculateVara(array $birth, SunService $sunService): array
$birth(array) — Birth details.$sunService(SunService) — Helper for sunrise timing.
array — {index, name, lord}getRitu()
Identify the Vedic season (Ritu) based on solar longitude.
public function getRitu(float $sunLon): string
$sunLon(float) — Sun longitude.
string — Sanskrit name of the season (e.g., "Sharad").getAyana()
Identify the solar hemisphere (Uttarayana or Dakshinayana).
public function getAyana(float $sunLon): string
$sunLon(float) — Sun longitude.
string — "Uttarayana" or "Dakshinayana".getSamvat()
Calculate Vikram Samvat and Saka Samvat years.
public function getSamvat(int $year, int $month): array
$year(int) — Gregorian year.$month(int) — Gregorian month (1-12).
array — {Vikram_Samvat, Saka_Samvat}getSamvatsara()
Identify the Samvatsara name in the 60-year Jupiter cycle.
public function getSamvatsara(int $vikramSamvat): string
$vikramSamvat(int) — Vikram Samvat year.
string — Samvatsara name.getHinduMonth()
Identify the Hindu lunar month for a given moment.
public function getHinduMonth(float $sunLon, float $moonLon, string $paksha='Shukla'): array
$sunLon(float) — Sun longitude.$moonLon(float) — Moon longitude.$paksha(string) — Current lunar phase.
array — {Amanta, Purnimanta, Amanta_Index, Purnimanta_Index}getSamvatsaraNorth()
Calculate North Indian Samvatsara name (variant cycle).
public function getSamvatsaraNorth(int $vikramSamvat): string
$vikramSamvat(int) — Vikram Samvat year.
string — North Samvatsara name.getKaliSamvat()
Calculate the year in the Kali Yuga era.
public function getKaliSamvat(int $vikramSamvat): int
$vikramSamvat(int) — Vikram Samvat year.
int — Kali Samvat year.getGujaratiSamvat()
Calculate the year in the Gujarati (Kartikadi) Samvat era.
public function getGujaratiSamvat(int $vikramSamvat, int $monthIdx): int
$vikramSamvat(int) — Vikram Samvat year.$monthIdx(int) — Month index (0-11).
int — Gujarati Samvat year.calculatePanchakaRahita()
Calculate Panchaka Rahita status for Muhurta selection (classical residual logic).
public function calculatePanchakaRahita(int $tithi, int $vara, int $nak, int $lagna): array
$tithi(int) — Tithi index.$vara(int) — Weekday index.$nak(int) — Nakshatra index.$lagna(int) — Lagna index.
array — {status, classification}calculateKundaLagna()
Calculate Kunda Lagna (Ascendant * 81) used for birth time rectification.
public function calculateKundaLagna(float $ascendantLongitude): array
$ascendantLongitude(float) — Longitude of the Ascendant.
array — {degrees, rasi}isVishtiKarana()
Determine if the current moment falls under the inauspicious Vishti Karana (Bhadra).
public function isVishtiKarana(float $sunLon, float $moonLon): bool
$sunLon(float) — Sun longitude.$moonLon(float) — Moon longitude.
bool — True if Bhadra is active.MuhurtaService
Service: JayeshMepani\PanchangCore\Panchanga\MuhurtaService
Advanced engine for time-based divisions, auspicious periods, and negative time clusters.
Methods
calculateMuhurtaTable()
Calculate all 30 named Muhurtas for a full 24-hour cycle.
public function calculateMuhurtaTable(CarbonImmutable $sunrise, CarbonImmutable $sunset, CarbonImmutable $nextSunrise): array
$sunrise(CarbonImmutable) — Current day sunrise.$sunset(CarbonImmutable) — Current day sunset.$nextSunrise(CarbonImmutable) — Next day sunrise.
array — 30 muhurta objects with {name, start, end}.calculateChoghadiyaTable()
Calculate 8 day and 8 night Choghadiya periods.
public function calculateChoghadiyaTable(CarbonImmutable $sunrise, CarbonImmutable $sunset, CarbonImmutable $nextSunrise, int $varaIdx): array
$sunrise(CarbonImmutable) — Sunrise time.$sunset(CarbonImmutable) — Sunset time.$nextSunrise(CarbonImmutable) — Next sunrise time.$varaIdx(int) — Weekday index (0-6).
array — Detailed list of 16 Choghadiya divisions.calculateHoraTable()
Identify the 24 planetary Hora rulers for the day.
public function calculateHoraTable(CarbonImmutable $sunrise, CarbonImmutable $sunset, CarbonImmutable $nextSunrise, int $varaIdx): array
$sunrise(CarbonImmutable) — Sunrise time.$sunset(CarbonImmutable) — Sunset time.$nextSunrise(CarbonImmutable) — Next sunrise time.$varaIdx(int) — Weekday index (0-6).
array — 24 Hora objects with {planet, start, end}.calculateAbhijitMuhurta()
Determine the most auspicious midday period (Abhijit).
public function calculateAbhijitMuhurta(CarbonImmutable $sunrise, CarbonImmutable $sunset): array
$sunrise(CarbonImmutable) — Sunrise time.$sunset(CarbonImmutable) — Sunset time.
array — {start, end, duration}.calculateBrahmaMuhurta()
Identify the pre-dawn auspicious period (Brahma Muhurta).
public function calculateBrahmaMuhurta(CarbonImmutable $sunrise): array
$sunrise(CarbonImmutable) — Sunrise time.
array — {start, end, name}calculateLagnaTable()
Calculate full 12/13 Lagna (Ascendant) intervals for the day with exact sign entry times.
public function calculateLagnaTable(CarbonImmutable $sunrise, CarbonImmutable $sunset, CarbonImmutable $nextSunrise, float $sunriseSunLon, float $ayanamsa, float $lat, float $lon, SwissEphFFI $sweph): array
$sunrise, $sunset, $nextSunrise(CarbonImmutable) — Boundary timestamps.$sunriseSunLon(float) — Sun longitude at sunrise.$ayanamsa(float) — Calculation offset.$lat, $lon(float) — Coordinates.
array — List of sign durations with start/end times.calculatePrahara()
Calculate 8 Prahara (4 day + 4 night) as per Srimad Bhagavata Purana.
public function calculatePrahara(CarbonImmutable $sunrise, CarbonImmutable $sunset, CarbonImmutable $nextSunrise): array
$sunrise, $sunset, $nextSunrise(CarbonImmutable) — Boundary timestamps.
array — 8 canonical Prahara periods.calculateDurMuhurta()
Identify specific inauspicious Muhurtas from the daily 30-period table.
public function calculateDurMuhurta(CarbonImmutable $sunrise, CarbonImmutable $sunset, CarbonImmutable $nextSunrise): array
$sunrise, $sunset, $nextSunrise(CarbonImmutable) — Boundary timestamps.
array — List of Dur-Muhurta periods.calculateVarjyam()
Calculate one Varjyam (Tyajyam) window for a specific Nakshatra span.
public function calculateVarjyam(CarbonImmutable $sunrise, CarbonImmutable $sunset, CarbonImmutable $nextSunrise, int $nakIdx, float $nakStartJd, float $nakEndJd): array
$sunrise, $sunset, $nextSunrise(CarbonImmutable) — Boundary timestamps.$nakIdx(int) — Nakshatra index.$nakStartJd, $nakEndJd(float) — Nakshatra span boundaries.
array — Varjyam window payload for that Nakshatra. Day-level aggregation is done in PanchangService.calculateAmritaKaal()
Calculate Amrita Kaal (auspicious period — opposite of Varjyam).
public function calculateAmritaKaal(CarbonImmutable $sunrise, array $varjyam): array
$sunrise(CarbonImmutable) — Sunrise time.$varjyam(array) — Calculated Varjyam results.
array — {amrita_kaal_start, amrita_kaal_end, duration_minutes}calculatePradoshaKaal()
Legacy helper around sunset. Full Trayodashi-overlap Pradosha logic in day output is computed by PanchangService.
public function calculatePradoshaKaal(CarbonImmutable $sunset, int $tithiNum): array
$sunset(CarbonImmutable) — Sunset time.$tithiNum(int) — Absolute Tithi index.
array — Pradosha timings.calculateBadTimes()
Calculate Rahu Kala, Gulika, and Yamaganda for a given day.
public function calculateBadTimes(CarbonImmutable $sunrise, CarbonImmutable $sunset, int $varaIdx): array
$sunrise, $sunset(CarbonImmutable) — Sunrise/Sunset.$varaIdx(int) — Weekday index.
array — Set of bad time intervals.EclipseService
Service: JayeshMepani\PanchangCore\Astronomy\EclipseService
Predict solar and lunar eclipses with sub-second precision, including contact times, magnitudes, and visibility assessment.
Methods
getEclipsesForYear()
Find all eclipses occurring in a specific calendar year globally or for a location.
public function getEclipsesForYear(int $year, float $lat, float $lon, string $tz): array
$year(int) — Gregorian year.$lat, $lon(float) — Coordinates.$tz(string) — Timezone.
array — List of eclipse events with times, type, and visibility.BhadraEngine
Service: JayeshMepani\PanchangCore\Festivals\Utils\BhadraEngine
Advanced Bhadra (Vishti Karana) analysis according to Muhūrta Chintāmaṇi and Nirṇaya Sindhu.
Methods
calculateBhadra()
Calculate Bhadra subdivisions (Mukha, Madhya, Puchha) and location (Bhadravāsa/Lok).
public function calculateBhadra(float $sunriseJd, float $vishtiStartJd, float $vishtiEndJd, int $moonRasi, int $tithi, string $paksha): array
$sunriseJd(float) — Julian Day of sunrise.$vishtiStartJd(float) — Julian Day of Vishti Karana start.$vishtiEndJd(float) — Julian Day of Vishti Karana end.$moonRasi(int) — Moon's Rasi (sign) index.$tithi(int) — Tithi index.$paksha(string) — 'Shukla' or 'Krishna'.
array— {mukha, madhya, puchha, lok, status}
AstroCore
Utility: JayeshMepani\PanchangCore\Core\AstroCore
Core astronomical utility class for normalization, coordinate conversion, and high-precision formatting.
Static Methods
normalize()
Normalize any angle to [0, 360) range.
public static function normalize(float $angle): float
$angle(float) — Angle in decimal degrees.
float — Normalized angle.formatAngle()
Format decimal degrees to DMS (Deg° Min' Sec") string.
formatTime()
Format time based on library configuration (12h/24h).
public static function formatTime(CarbonImmutable $dt): string
$dt(CarbonImmutable) — Date/Time object.
string — Formatted time string.formatDuration()
Format minutes to Hh Mm string.
public static function formatDuration(float $minutes): string
$minutes(float) — Duration in minutes.
string — Formatted duration.r9()
Round value to high precision (9 decimal places) for consistency.
public static function r9(float $value): float
$value(float) — Decimal value.
float — Rounded value.Configuration
Complete reference for config/panchang.php.
| Key | Type | Default | Description |
|---|---|---|---|
ephe_path |
string | __DIR__ . '/../ephe' |
Path to Swiss Ephemeris .se1 files. |
ayanamsa |
string | 'LAHIRI' |
Default calculation system (LAHIRI, RAMAN, etc.). |
defaults.measurement_system |
string | 'indian_metric' |
Unit system for generic measurements. |
defaults.date_time_format |
string | 'indian_12h' |
Date-time output format. |
defaults.time_notation |
string | '12h' |
Time output notation. |
festivals.default_tradition |
string | 'Smarta' |
Default tradition used for festival resolution. |
festivals.default_region |
string | 'North' |
Default region used for festival resolution. |
Constants & Enums
Available options for calculation parameters.
Ayanamsa Systems
LAHIRI— Chitra Paksha (Standard)RAMAN— BV RamanKRISHNAMURTI— KP SystemSAYANA— Tropical (Zero offset)JNRBHASIN— JN Bhasin
Traditions
Smarta— Standard Dharmasindhu rulesVaishnava— ISKCON/Gaudiya rules
Regions
North— Purnimanta calendar (UP, Delhi, Rajasthan)South— Amanta calendar (Karnataka, Andhra, TN)Maharashtra,Gujarat— Regional variationsBengal— Solar calendar variations
FestivalService
Service: JayeshMepani\PanchangCore\Festivals\FestivalService
Calculate Hindu festivals based on Tithi, Nakshatra, and complex regional traditions/priorities.
Methods
resolveFestivalsForDate()
Resolve all festivals for a date using today's and tomorrow's snapshot context.
public function resolveFestivalsForDate(CarbonImmutable $date, array $todayDetails, array $tomorrowDetails): array
$date(CarbonImmutable) — Target date.$todayDetails(array) — Festival snapshot for date.$tomorrowDetails(array) — Festival snapshot for next date.
array — List of festival objects with names, types, and metadata.$today = $panchang->getFestivalSnapshot(
CarbonImmutable::parse('2026-03-24'),
23.247,
69.668,
'Asia/Kolkata'
);
$tomorrow = $panchang->getFestivalSnapshot(
CarbonImmutable::parse('2026-03-25'),
23.247,
69.668,
'Asia/Kolkata'
);
$festivals = $festivalService->resolveFestivalsForDate(
CarbonImmutable::parse('2026-03-24'),
$today,
$tomorrow
);
foreach ($festivals as $festival) {
echo $festival['name'] . "\n";
}
Laravel Integration
Complete guide for using Panchang Core in Laravel applications.
Installation
composer require jayeshmepani/panchang-core
Configuration
Publish the configuration file:
php artisan vendor:publish --provider="JayeshMepani\PanchangCore\PanchangServiceProvider" --tag="panchang-config"
This creates config/panchang.php:
return [
'ephe_path' => env('PANCHANG_EPHE_PATH', ''),
'ayanamsa' => env('PANCHANG_AYANAMSA', 'LAHIRI'),
'defaults' => [
'tradition' => 'Smarta',
'region' => 'North',
],
];
Using the Facade
use JayeshMepani\PanchangCore\Facades\Panchang;
use Carbon\CarbonImmutable;
// Get complete panchanga
$details = Panchang::getDayDetails(
date: CarbonImmutable::parse('2026-03-24'),
lat: 23.2472,
lon: 69.6683,
tz: 'Asia/Kolkata'
);
echo $details['Tithi']['name']; // "Dwadashi"
echo $details['Nakshatra']['name']; // "Magha"
Service Container
Or inject via constructor:
use JayeshMepani\PanchangCore\Panchanga\PanchangService;
class PanchangController extends Controller
{
public function __construct(
private PanchangService $panchang
) {}
public function show()
{
$details = $this->panchang->getDayDetails(
date: CarbonImmutable::now(),
lat: 28.6139,
lon: 77.2090,
tz: 'Asia/Kolkata'
);
return view('panchang', compact('details'));
}
}
Return Value Structures
Complete data structures returned by main methods.
getDayDetails() Return Structure
[
'Tithi'=>[ 'index'=>12, 'name'=>'Dwadashi', 'paksha'=>'Shukla', 'fraction_left'=>0.7666, ],
'Nakshatra'=>[ 'index'=>10, 'name'=>'Magha', 'pada'=>2, 'lord'=>'Sun', ],
'Yoga'=>['index'=>9, 'name'=>'Shula'],
'Karana'=>['index'=>23, 'name'=>'Bava'],
'Vara'=>['index'=>2, 'name'=>'Tuesday', 'lord'=>'Mars'],
'Muhurta_Full_Day'=>[
['name'=>'Rudra', 'start'=>'06:14', 'end'=>'07:02'], // ... 30 periods
],
'Chogadiya_Full_Day'=>[
['name'=>'Amrit', 'mode'=>'Day', 'start'=>'06:14', 'end'=>'07:46'], // ... 16 divisions
],
'Hora_Full_Day'=>[
['planet'=>'Sun', 'start'=>'06:14', 'end'=>'07:14'], // ... 24 horas
],
'Prahara_Full_Day'=>[
['name'=>'Pratah Prahara', 'start'=>'06:14', 'end'=>'09:18'], // ... 8 objects
],
'Lagna_Full_Day'=>[
['sign_name'=>'Mesha', 'start'=>'06:14', 'end'=>'08:22'], // ... 12/13 signs
],
'Dur_Muhurta_Full_Day'=>[
['name'=>'Rudra', 'start'=>'06:14', 'end'=>'07:02'], // Inauspicious Muhurtas only
],
'Festivals'=>[['name'=>'Pradosh Vrat', 'type'=>'vrat']],
'Sunrise'=>'06:14:00',
'Sunset'=>'18:32:00',
'Moonrise'=>'15:45:00',
'Moonset'=>'04:20:00',
]
getFestivalSnapshot() Return Structure
[
'Festivals' => [
['name' => 'Holika Dahan', 'type' => 'festival', 'priority' => 1],
],
'Tithi' => [...],
'Nakshatra' => [...],
]
Real-World Examples
Complete working examples for common use cases.
1. Daily Panchang Display
// Show today's panchang
$today = Panchang::getDayDetails(
date: CarbonImmutable::now(),
lat: $userLat,
lon: $userLon,
tz: $userTz
);
echo "Tithi: " . $today['Tithi']['name'];
echo "Nakshatra: " . $today['Nakshatra']['name'];
2. Festival Calendar
// Get festivals for entire month
$monthFestivals = [];
for ($day = 1; $day <= 31; $day++) {
$date = CarbonImmutable::create(2026, 10, $day);
$fest = Panchang::getFestivalSnapshot($date, $lat, $lon, $tz);
if (!empty($fest['Festivals'])) {
$monthFestivals[$day] = $fest['Festivals'];
}
}
3. Tradition-Specific Resolution
// Smarta-style date resolution (date-scoped festivals)
$smarta = Panchang::getDayDetails(
CarbonImmutable::parse('2026-09-06'),
28.61, 77.20, 'Asia/Kolkata'
)['Festivals'];
// Next-day festival context (for comparison)
$vaishnava = Panchang::getDayDetails(
CarbonImmutable::parse('2026-09-07'),
28.61, 77.20, 'Asia/Kolkata'
)['Festivals'];
4. Birth Chart Basics
// Get planetary positions for a birth date
$birthData = [
'year' => 1990, 'month' => 5, 'day' => 15,
'hour' => 14, 'minute' => 30, 'second' => 0,
'tz' => 'Asia/Kolkata', 'lat' => 28.61, 'lon' => 77.20
];
$planets = $astronomy->getPlanets($birthData);
$ascendant = $astronomy->getAscendant($birthData);
echo "Sun: " . $planets['Sun'] . "°\n";
echo "Ascendant: " . $ascendant . "°";
5. Comprehensive Full-Day Data
// Get all advanced time divisions for a date
$details = Panchang::getDayDetails($date, $lat, $lon, $tz);
$lagnas = $details['Lagna_Full_Day']; // Exact Sign entry times
$horas = $details['Hora_Full_Day']; // 24 planetary rulers
$praharas = $details['Prahara_Full_Day']; // 8 canonical periods
$muhurtas = $details['Muhurta_Full_Day']; // 30 named Muhurtas
$durs = $details['Dur_Muhurta_Full_Day']; // Inauspicious Muhurtas
Accuracy & Date Range
Technical specifications of the Swiss Ephemeris astronomical engine.
Precision Modes
| Mode | Date Range | Precision |
|---|---|---|
| High Precision | 13,201 BCE to 17,191 CE | 0.001 arcsec |
| Standard | 3,000 BCE to 3,000 CE | 0.1 arcsec |
*High Precision requires .se1 data files from Astro.com.
Ephemeris File Structure
Files are split into 600-year periods:
sepl_*.se1/semo_*.se1— Common Era (AD) Datesseplm*.se1/semom*.se1— Before Common Era (BC)se00*.se1— Asteroids (Range: 5401 BCE to 5399 CE)
Calculation Precision
- IEEE 754 — Double precision (53-bit significand)
- Lossless — No intermediate rounding in formulas
- High Convergence — 80 iterations for 1e-24 JD precision
Error Handling
Understanding and handling errors.
Common Exceptions
| Exception | When It Occurs | How to Handle |
|---|---|---|
RuntimeException |
Swiss Ephemeris file not found | Set correct ephe_path in config |
InvalidArgumentException |
Invalid latitude/longitude | Validate coordinates before calling |
RuntimeException |
Timezone not found | Use valid PHP timezone identifiers |
Best Practices
try {
$details = Panchang::getDayDetails(
date: $date,
lat: $lat, // Validate: -90 to 90
lon: $lon, // Validate: -180 to 180
tz: $tz // Validate: timezone_exists($tz)
);
} catch (RuntimeException $e) {
Log::error('Panchang calculation failed', [
'error' => $e->getMessage(),
'location' => compact('lat', 'lon', 'tz')
]);
return response()->json([
'error' => 'Unable to calculate panchang for this location'
], 500);
}
FAQ & Troubleshooting
Common questions and solutions.
Why are my calculations different from other panchang apps?
- Answer
-
- Ayanamsa: We use Lahiri by default. Change via config if needed.
- Location: Ensure exact latitude/longitude.
- Tradition: Smarta vs Vaishnava have different rules.
- Precision Mode: Ensure you have
.se1ephemeris files installed for 0.001" accuracy. Without them, the engine falls back to the Moshier model (0.1" precision).
How do I change the ayanamsa?
- Answer
-
Set in config or pass to
getDayDetails():// In config/panchang.php 'ayanamsa' => 'RAMAN', // Options: LAHIRI, RAMAN, KRISHNAMURTI // Or per-call $details = Panchang::getDayDetails( date: $date, lat: $lat, lon: $lon, tz: $tz, ayanamsaAt: CarbonImmutable::now() );
Why is Janmashtami on different dates?
- Answer
-
This is normal. Smarta tradition celebrates on one day (ashtami at sunrise), Vaishnava on another (ashtami + Rohini nakshatra at midnight). Use the
traditionparameter for the correct date.
How accurate are the calculations?
- Answer
-
We use Swiss Ephemeris which provides accuracy to within 1 arcsecond for planetary positions. All calculations use IEEE 754 double precision with no intermediate rounding.
Can I use this for historical dates?
- Answer
-
Yes! Swiss Ephemeris supports dates from 3000 BCE to 3000 CE. Just pass any valid CarbonImmutable date.
License
AGPL-3.0 License
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).
The core engine utilize the Swiss Ephemeris for precision calculations, which follows a dual-licensing model:
- Open Source: Licensed under GNU AGPLv3. If you use this package in a free/open-source project, your project must also be licensed under AGPLv3.
- Commercial: If you wish to use this package in a closed-source or commercial application, you MUST purchase a commercial license from Astrodienst AG.
For more details, see the full license text.
Quick Reference
What to Use When
| I want to… | Use this method |
|---|---|
| Get complete panchanga for a day | PanchangService::getDayDetails() |
| Get only festivals | PanchangService::getFestivalSnapshot() |
| Get planetary positions | AstronomyService::getPlanets() |
| Get sunrise/sunset | SunService::getSunriseSunset() |
| Calculate Tithi manually | PanchangaEngine::calculateTithi() |
| Get Nakshatra from Moon position | PanchangaEngine::getNakshatraInfo() |
| Get Muhurta times | MuhurtaService::calculateMuhurtaTable() |
| Get auspicious times | MuhurtaService::calculateAbhijitMuhurta() |
| Get Brahma Muhurta | MuhurtaService::calculateBrahmaMuhurta() |
| Get Rahu Kala, Gulika | MuhurtaService::calculateBadTimes() |
| Get resolved festivals for a date | PanchangService::getDayDetails() / FestivalService::resolveFestivalsForDate() |
| Get season (Ritu) | PanchangaEngine::getRitu() |
| Get Samvatsara | PanchangaEngine::getSamvatsara() |
Classical Text References
All calculations are based on authentic Sanskrit texts:
- Sūrya Siddhānta 1.29→ Tithi
- Sūrya Siddhānta 8.1→ Nakṣatra
- Sūrya Siddhānta→ Yoga, Karana
- BPHS→ Vimśottarī Daśā, Horā
- Bṛhat Saṃhitā 8→ Samvatsara, Ritu
- Muhūrta Chintāmaṇi→ Muhūrta
- Kāla Nirṇaya→ Choghadiya
- Ashtānga Hṛdaya→ Brahma Muhūrta