Panchang Core — Advanced Vedic Astrology Engine for PHP

Introduction

Authentic Vedic Panchanga calculation engine with JME native ephemeris precision.

Overview

Panchang Core is a comprehensive PHP package for calculating Vedic Panchanga elements, Muhūrtas, Karmakala windows, and Hindu festivals with high astronomical precision. Built on JME native ephemeris FFI, it provides a reusable calculation engine for authentic Vedic astrology applications.

Complete Panchanga

Tithi, Vara, Nakṣatra, Yoga, Karaṇa with precise fractions

🕉

324 Festivals + 122 Vrats

Comprehensive library of unique festival and vrat identities covering major and minor observances for all regions and traditions.

Muhūrta

Abhijit, Brahma Muhūrta, Rahu Kāla, Gulika, Yamaganda, Varjyam, Pradosha

Special Yogas

Sarvartha Siddhi, Amrit Siddhi, Ravi Yoga, Pushya variants, Dwipushkar, Tripushkar, Ganda Mula, Aadal, Vidaal, and Jwalamukhi.

Disha & Vaasa

Disha Shool, Nakshatra Shool, Rahu Vaasa, Chandra Vaasa, Shiva Vaasa, Agni Vaasa, and Yogini Vaasa for general panchang and electional screening.

Regional Support

Smarta, Vaishnava, North, South, Bengal, Maharashtra, Tamil traditions

Localization & Calendar Types

English, Hindi, and Gujarati localization with Amanta and Purnimanta month representation.

Classical Sources

Important: This is a source-integrity map, not a manuscript-critical proof. The codebase mixes direct conventions, package rule mappings, regional almanac conventions, modern references, and legacy helpers. For complete details, see docs/TRADITIONAL_TEXT_SOURCES.md. For the current canonical identity list, see docs/FESTIVAL_VRAT_IDENTITIES.md; for duplicate-name cleanup decisions, see docs/FESTIVAL_VRAT_DUPLICATE_AUDIT.md; for Muhurta source classification, see docs/MUHURTA_TEXT_SOURCES.md.

Tier 1: Direct or Standard Panchang Conventions

Standard Panchang conventions used for calculations
Source Implementation
Sūrya Siddhānta 1.29 Tithi calculation (30 lunar days, 12° each)
Sūrya Siddhānta 8.1 Nakṣatra calculation (27 lunar mansions, 13°20' each)
Sūrya Siddhānta 3.1-3 Yoga calculation (27 combinations, 13°20' Sun-Moon sum)
Muhūrta Chintāmaṇi Chapter 2 Karana calculation (11 half lunar days, 6° each)
Sūrya Siddhānta 1.10-1.11 Muhūrta, Ghaṭikā, Pala time units
Brahmagupta / Khaṇḍakhādyaka tradition Eclipse ritual magnitude thresholds used by Nirnay-rule handling
Śrīmad Bhāgavatam 3.11.10 / Āryabhaṭīya commentary tradition Yama and Prahar as day/night quarters for dynamic sutak and daily-period calculations
Classical astronomy and Panchanga calculation texts Generic source-family labels used in Panchanga calculation metadata

Tier 2: Package Rule Mappings

Package rule mappings attributed to traditional literature
Source Implementation
Muhūrta Chintāmaṇi Universal bad tithis, Vara-Tithi Yogas
Dharma Sindhu / Dharma_Sindhu Punya Kala, Sankranti, Ekadashi classification, Rama Navami, Dhanteras, Diwali, Mahashivaratri, and Narasimha Jayanti rule families
Kamakoti Dharma Sindhu translation / public digest Vaishnava/Smarta Ekadashi classification references and Dharma-Sindhu-style rule explanations
Bṛhat Saṃhitā Muhurta rules, Samvatsara, Ritu
Māyamata Vāstu muhurta guidance
Vaikhānasa Āgama Āgama-based muhurta guidance
Aśvalāyana Gṛhya Sūtra Gṛhya-sūtra muhurta guidance
Muhūrta Mārtaṇḍa Advanced muhurta calculations
Gargiya Jyotisha Rikta Tithi dosha
Classical Choghadiya / Yoga texts Source-family labels for encoded electional tables

Tier 3: Festival-Resolution Logic

Festival resolution sources
Source Implementation
Nirṇaya Sindhu Festival timing, Bhadra rules
Muhūrta Chintāmaṇi Aruṇodaya, Pradoṣa, Ekadashi handling
Hari Bhakti Vilāsa Vaishnava Ekadashi rules
Satsangi Jeevan / Swaminarayan tradition Vaishnava Ekadashi Dashami-vedha and parana nakshatra-pada restrictions
Shikshapatri and Vitthalnathji vrata-nirnaya tradition Vaishnava vrata compliance and sectarian Ekadashi decision-profile context
Vālmīki Rāmāyaṇa and Śrīmad Bhāgavatam Rama Navami, Vamana Jayanti, Govardhan Puja, and Annakuta source context
Śrīmad Bhāgavata Purāṇa, Agni Purāṇa, Gīta Govinda Festival-description sources for Vaishakha Purnima and Sugata Buddha/Kurma Jayanti notes
Yājñavalkya Smṛti and Saṃskāra-ratnamālā Samavedi Shravani / Upakarma Hasta-nakshatra rule family
Utsava-Nirnaya, Bhakti-Hamsa, Seva-Shlokah Shringar-Rasamandanam Pushtimarg / Vaishnava tithi-conflict, vrata, grahana, and seva-calendar source families

Tier 4: Published Panchang Conventions

Published Panchang conventions
Source Implementation
Tamil Gowri/Pambu Panchangam Gowri Panchangam (8-part day/night division)
Popular travel-muhurta and Nivas-Shool Panchang tables Disha Shool, Nakshatra Shool, Rahu Vaasa, Chandra Vaasa, Shiva Vaasa, Agni Vaasa, and Yogini Vaasa
Drik / modern Nivas-Shool Panchang style Source-family metadata for Vaasa-style published almanac rules
Published Ekadashi, Mahadvadashi, and festival timing pages Published almanac references for parana windows, Harivasara, symbolic water parana, and public festival timing comparisons
BAPS, Swaminarayan.org, and Satsangi Jivan public tradition references Phuldolotsava / Pushpadolotsav profile variants and Swaminarayan observance context
ISKCON public observance references Gaudiya/ISKCON Ekadashi, Narasimha Jayanti, Govardhan Puja, and Annakuta observance context
Indica Today and Samskaaram.com Upakarma summaries Samavedi Shravani / Sāma Veda Upākarmā procedure references used as modern public summaries
Sarāvalī Kala Vela rules (Rahu, Gulika, Yamaghantaka)
Published Panchang convention Dynamic night-muhurta Brahma Muhurta timing
Nārada Saṃhitā 9.1-5 and Kāśyapa / Vṛddha Vasiṣṭha Saṃhitā 30 named Muhurta devata sequence: 15 day muhurtas beginning Rudra, Ahi, Mitra and 15 night muhurtas beginning Isha, Ajapada, Ahirbudhnya. See docs/MUHURTA_TEXT_SOURCES.md for source classification and exact ślokas.
Aṣṭāṅga Hṛdaya Brahma Muhurta practice context
Charaka Saṃhitā Muhurta concepts
Manusmṛti Brahma Muhurta for Vedic study
Sandhyāvandanam Tradition Sandhya windows (living tradition)
Smarta, Vaishnava, ISKCON/Gaudiya, regional traditions Festival family variants and regional observance notes

Tier 5: Modern Systems

Modern systems used
Source Implementation
JME native ephemeris Planetary longitudes, Ayanāṃśa, Vara
KP System Varjyam (Visha Ghati) calculation
Ernst Wilhelm's Classical Muhurta Bhadra subdivisions
Puri Shankaracharya Swami Nischalananda Saraswati Living-authority citation in Vaishakha Purnima explanatory text

What This Does NOT Claim

  • ❌ Every package rule is 1:1 from a single primary text
  • ❌ All regional or sectarian variants are covered
  • ❌ Modern almanac conventions are identical across traditions
  • ❌ Independent verification against critical Sanskrit editions

System Setup

Configuring PHP FFI and JME native ephemeris data files.

FFI Requirement

Panchang Core uses the PHP FFI extension to achieve maximum astronomical precision. This must be installed and enabled on your server.

1. Enable FFI Extension

Linux (Ubuntu/Debian)

sudo apt install php8.3-ffi

Linux (RHEL/CentOS)

sudo dnf install php-ffi

macOS (Homebrew)

Included by default in brew install php.

Windows

Included with PHP 8.3+. Enable in php.ini as shown below.

2. Configure php.ini

Add or uncomment high-privilege FFI settings in your php.ini:

php.ini
extension=ffi
ffi.enable=1

3. Verify Setup

php -r "echo extension_loaded('ffi') ? 'FFI loaded' : 'FFI not loaded';"
php -r "echo ini_get('ffi.enable') ? 'FFI enabled' : 'FFI not enabled';"

📂 JPL Kernel Files

The default moshier mode works without external kernel files. For strict JPL mode, download a supported .bsp kernel from the native JME release page:

Download JPL Kernels

Use de440s.bsp, de440.bsp, or de441.bsp with PANCHANG_JME_MODE=jpl.

Download Kernels

Installation

Composer Install
composer require jayeshmepani/panchang-core

Requirements

  • PHP 8.3+— uses typed constants, readonly classes, enums
  • JME native ephemeris FFI— jayeshmepani/jpl-moshier-ephemeris-php
  • Carbon— nesbot/carbon
  • FFI Extension— required for JME native ephemeris

Quick Start

Standalone Usage
<?php

require 'vendor/autoload.php';

use JayeshMepani\PanchangCore\Traits\CliBootstrap;
use Carbon\CarbonImmutable;

// Initialize standalone environment (loads config & sets up DI)
CliBootstrap::init(__DIR__);

// Create fully wired PanchangService
$panchang = CliBootstrap::makePanchangService();

// Calculate panchanga
$date = CarbonImmutable::parse('2026-03-24');
$details = $panchang->getDayDetails(
    date: $date,
    lat: 23.2472446,
    lon: 69.668339,
    tz: 'Asia/Kolkata'
);

echo "Sunrise Tithi: " . $details['Tithi_At_Sunrise']['name'] . "\n";
echo "Current Tithi: " . $details['Current_Tithi_At_Input_Now']['name'] . "\n";
echo "Nakshatra: " . $details['Nakshatra']['name'] . "\n";

🪐 Ayanamsa Authority

The Ayanamsa defines the starting point of the sidereal zodiac. For Panchanga calculations, this is a fixed religious and legal anchor.

Locked Standard

Strict Lahiri (Chitra Paksha)

For any authentic Hindu Panchanga (Tithi, Vara, Nakshatra, Yoga, Karana), Lahiri is the absolute mandatory standard. Using any other Ayanamsa results in incorrect festival dates and Nakshatra transitions.

This package does not support and has intentionally removed all other Ayanamsa systems to maintain calculation integrity.

System Core Policy

Ayanamsa Standard Status
Lahiri (Chitra Paksha) National Standard of India Hardcoded Core

Engine Conventions

Current calculation settings used by the package for Panchanga, sunrise, moonrise, eclipses, and Nirnay rules.

Scope Note

These are implementation conventions, not a claim that every Hindu almanac school uses the same choices. The detailed source and rule map is maintained in docs/TRADITIONAL_TEXT_SOURCES.md.

Current engine convention matrix
Area Current Setting Meaning
Engine mode PANCHANG_JME_MODE=jpl by default JME native ephemeris through FFI; supported modes are auto, jpl, moshier, and vsop_elp_meeus.
Ayanamsa JME_SIDEREAL_LAHIRI Lahiri/Chitra Paksha is hardcoded for Panchanga calculations. Dynamic True Citra is not used for the five limbs.
Panchanga Moon Geocentric sidereal Moon Tithi, Nakshatra, Yoga, Karana, Moon sign, and transition searches use geocentric high-precision sidereal longitudes, without a topocentric flag.
Moonrise/moonset Topocentric visibility interval Rise/set is computed for the observer location. The month API reports moonset only when the visibility interval begins with a moonrise inside that civil date.
Sunrise/sunset Visible upper limb with standard refraction The engine does not pass disc-center, disc-bottom, no-refraction, or Hindu-rising flags for Panchanga sunrise/sunset.
Atmosphere 1013.25 hPa, 15 C Standard pressure and temperature are supplied to JME rise/transit calculations; refraction remains enabled.
Panchang day Sunrise to next sunrise Daily observances and sunrise-state limbs are resolved against the local Panchang day, not only midnight-to-midnight civil time.
Ekadashi Nirnay 55 ghaṭikā Dashami-vedha; Hari Vasara is first quarter of Dvadashi Parana windows exclude Anuradha P1, Shravana P2-3, and Revati P4, and may extend past civil midnight.
Ekadashi parana refinements Dwadashi-bound parana, preferred early-day windows, and symbolic-water emergency metadata Outputs distinguish valid and preferred parana spans where available, with Vaishnava/Nirnay restrictions preserved in localized display fields.
Festival karmakala Window overlap for Pradosha, Nishitha, Madhyahna, Aparahna, Sangava, Arunodaya, and Vijaya Kaal Festival resolution uses interval overlap and source-specific fallback/tie-break behavior rather than only testing a single clock instant.
Deepotsav and major festival rules Dhanteras in Pradosha Trayodashi; Diwali/Lakshmi Puja in Amavasya Pradosha/night Related rule families include Rama Navami Madhyahna, Mahashivaratri Nishitha, Vamana Abhijit/Shravana, Narasimha Pradosha, Samavedi Shravani Hasta, and Phuldolotsava profile variants.
Chandra Darshana First visible waxing crescent after Amavasya, after local sunset and before moonset The tithi context is Shukla Pratipada/Dwitiya. Lag, elongation, and illumination checks are labeled as a simplified modern crescent-visibility heuristic, not a classical shloka-based threshold.
Chandra sunset factors moon_sun_elongation_at_sunset_degrees and moon_illumination_at_sunset_percent Festival snapshots include these values so Chandra Darshana can expose a transparent visibility_assessment with lag, elongation, illumination, pass/fail flags, and basis labels.
Eclipse visibility Local visibility plus ritual magnitude threshold Lunar ritual minimum is 1/16; solar ritual minimum is 1/12. Sutak applies only when the eclipse is ritually visible at the location.
Eclipse sutak Lunar 3 prahar, Solar 4 prahar Prahar boundaries are variable: day length divided by 4 and night length divided by 4.
Eclipse edge handling Grastodaya/Grastasta, local-visible windows, penumbral/mandya filtering, and half-ghadi short-visibility profile Ritual output separates astronomical eclipse data from local observability and tradition-profile restrictions.
Month system amanta default; purnimanta supported This controls month-name representation. It does not change the underlying limb arithmetic.

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 default locale, calendar type, and representation formatting across package output without truncating the raw calculation floats.

Default Calculation Options

The defaults array configures localization, calendar-system selection, and formatting representations.

Default calculation configuration options
Setting Description Acceptable Values
locale Language used for localized names and descriptions. en, hi, gu
calendar_type Preferred lunar month naming system for representation. amanta: month ends at Amavasya
purnimanta: month ends at Purnima
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.668339
dms: "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.0
seconds: 5400.0
hours: 1.5

Festival Calculation Settings

The festivals array provides defaults for region and tradition if not explicitly supplied.

Festival calculation configuration
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, Gujarat

Cache Settings

The cache array controls package cache behavior in Laravel applications.

Cache configuration options
Setting Description Default / Environment
enabled Enable package cache. PANCHANG_CACHE_ENABLED=true
ttl Cache lifetime in seconds. PANCHANG_CACHE_TTL=86400
prefix Cache key prefix. PANCHANG_CACHE_PREFIX=panchang_

⚠️ Critical Implementation Notes

1. Panchang Day Context (Sunrise to Sunrise)

Most Important: In Vedic Panchang, a day runs from sunrise to next sunrise, NOT midnight to midnight. This affects:

  • Tithi calculation: The tithi at sunrise determines the day's primary tithi
  • Festival resolution: If a tithi ends before sunrise, it belongs to the previous Panchang day
  • Time outputs: Times earlier than sunrise are dated to the next civil date
// Example: Sunrise at 6:14 AM
// Event at 5:30 AM belongs to NEXT Panchang day
$details = $panchang->getDayDetails($date, $lat, $lon, $tz);
// Times before sunrise in output are dated to next civil date

2. ISO Timestamps vs Time-Only Fields

All time-like fields include date-qualified companions with _iso suffix:

// Time-only (for display)
$varjyam_start = $details['Varjyam']['varjyam_start']; // "03:31:48 AM"

// Full ISO timestamp (for storage/database)
$varjyam_start_iso = $details['Varjyam']['varjyam_start_iso']; // "28/03/2026 03:31:48 AM"

// ALWAYS use _iso fields when:
// - Storing in database
// - Displaying to users
// - Comparing across timezones

3. Multiple Varjyam Windows

Varjyam can occur 0, 1, or 2 times per day depending on nakshatra transitions:

// Check how many windows exist
$windowCount = $details['Varjyam']['window_count']; // 0, 1, or 2

// Access all windows
foreach ($details['Varjyam']['windows'] as $window) {
    echo $window['window_start_iso'] . " - " . $window['window_end_iso'];
    echo $window['visible_start_iso'] . " - " . $window['visible_end_iso'];
}

// Top-level keys maintain backward compatibility
$details['Varjyam']['varjyam_start']; // First window start
$details['Varjyam']['varjyam_end'];   // First window end

// Amrita_Kaal uses the same window payload shape
$details['Amrita_Kaal']['windows'][0]['window_start_iso'];
$details['Amrita_Kaal']['windows'][0]['window_end_iso'];

4. Pradosha Kaal Calculation

Pradosha is computed from two factors:

  1. Local sunset anchor: The base window begins at the calculated local sunset and continues for six fixed ghaṭīs (144 minutes)
  2. Trayodashi overlap: Only auspicious when Trayodashi tithi overlaps the window
// Returns both base and effective windows
$pradosha = $details['Pradosha_Kaal'];
$base_start = $pradosha['base_pradosha_start_iso'];
$base_end = $pradosha['base_pradosha_end_iso'];       // Sunset + 6 fixed ghaṭīs
$effective_start = $pradosha['pradosha_start_iso'];
$effective_end = $pradosha['pradosha_end_iso'];       // Trayodashi overlap

5. Hindu Calendar Month Resolution

The package uses exact amavasya-to-amavasya solar transit logic:

  • Amanta: Month ends at new moon (amavasya)
  • Purnimanta: Month ends at full moon (purnima)
  • Adhika Masa: Extra month when two amavasyas occur without solar transit
  • Kshaya Masa: Lost month when no amavasya occurs in solar month (rare)

Note: Final month output can differ from simpler longitude-only heuristics used by other packages.

6. Karmakala Windows in getDayDetails()

The following dedicated Karmakala outputs are available:

$badTimes   = $details['Rahu_Kaal_Gulika_Yamaganda'];
$abhijit    = $details['Abhijit_Muhurta'];
$praharas   = $details['Prahara_Full_Day'];
$daylight   = $details['Daylight_Fivefold_Division']; // Morning, Forenoon, Midday, Afternoon, Evening
$brahma     = $details['Brahma_Muhurta'];
$dur        = $details['Dur_Muhurta_Full_Day'];
$nishita    = $details['Nishita_Muhurta'];            // Night midpoint
$vijaya     = $details['Vijaya_Muhurta'];             // 11th of 15 day muhurtas
$godhuli    = $details['Godhuli_Muhurta'];            // Evening twilight
$sandhya    = $details['Sandhya'];                    // Morning, Noon, Evening
$gowri      = $details['Gowri_Panchangam'];           // Tamil 8-part division
$kalaVela   = $details['Kala_Vela'];                  // Kala, Mrityu, etc.
$karmakala  = $details['Karmakala_Windows'];
$varjyam    = $details['Varjyam'];
$amrita     = $details['Amrita_Kaal'];
$pradosha   = $details['Pradosha_Kaal'];

7. Special Yoga and Vaasa Outputs

Festival snapshots expose general panchang/electional signals without requiring consumers to rebuild the rule tables:

$specialYogas = $snapshot['Special_Yogas'];
$anandadi     = $snapshot['Anandadi_Yoga'];
$amritadi     = $snapshot['Amritadi_Yoga'];
$panchak      = $snapshot['Panchak'];
$maitreya     = $snapshot['Maitreya_Yoga'];
$gajachchhaya = $snapshot['Gajachchhaya_Yoga'];
$nakShool     = $snapshot['Nakshatra_Shool'];
$dishaShool   = $snapshot['Disha_Shool'];
$rahuVaasa    = $snapshot['Rahu_Vaasa'];
$chandraVaasa = $snapshot['Chandra_Vaasa'];
$shivaVaasa   = $snapshot['Shiva_Vaasa'];
$agniVaasa    = $snapshot['Agni_Vaasa'];
$yoginiVaasa  = $snapshot['Yogini_Vaasa'];
$ekadashi     = $snapshot['Ekadashi_Observance'];

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();         // "Pitris"
echo $nakshatra->getRulingPlanet();  // "Ketu"
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

Ashwini
Bharani
Krittika
Rohini
Mrigashira
Ardra
Punarvasu
Pushya
Ashlesha
Magha
PurvaPhalguni
UttaraPhalguni
Hasta
Chitra
Swati
Vishakha
Anuradha
Jyeshtha
Mula
PurvaAshadha
UttaraAshadha
Shravana
Dhanishta
Shatabhisha
PurvaBhadrapada
UttaraBhadrapada
Revati

Methods

getName()

Get Sanskrit name

public function getName(): string
Returns:string— Sanskrit name

getDeity()

Get deity of the nakṣatra

public function getDeity(): string
Returns:string— Deity name

getRulingPlanet()

Get ruling planet

public function getRulingPlanet(): string
Returns:string— Planet name

getSymbol()

Get Vedic symbol

public function getSymbol(): string
Returns:string— Symbol description

getLongitudeRange()

Get Vedic longitude range

public function getLongitudeRange(): array{start: float, end: float}
Returns:array— Longitude range in degrees

fromLongitude()

Get nakṣatra from longitude

public static function fromLongitude(float $longitude): self
Parameters:
  • $longitude(float) — Longitude in degrees (0–360)
Returns:self— Nakṣatra instance

getPada()

Get pada (quarter) from longitude

public static function getPada(float $longitude): int
Parameters:
  • $longitude(float) — Longitude in degrees
Returns: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\Paksha;
use JayeshMepani\PanchangCore\Core\Enums\Tithi;

// Get tithi by index (1-30)
$tithi = Tithi::from(12); // enum case: ShuklaDwadashi

echo $tithi->getName();            // "Twelfth Lunar Day of Bright Half"
echo $tithi->getName('hi');        // "शुक्ल द्वादशी"
echo $tithi->getName('gu');        // "સુદ બારસ"
echo $tithi->getPaksha()->name;    // "Shukla"
echo $tithi->getPaksha()->getName(); // "Bright Half (waxing)"

// Check paksha
if ($tithi->getPaksha() === Paksha::Shukla) {
    echo "Waxing moon phase\n";    // Waxing moon phase
}

// Get normalized index (1-15 for both pakshas)
echo $tithi->getNormalizedIndex(); // 12

Cases

ShuklaPratipada
ShuklaDwitiya
ShuklaTritiya
ShuklaChaturthi
ShuklaPanchami
ShuklaShashthi
ShuklaSaptami
ShuklaAshtami
ShuklaNavami
ShuklaDashami
ShuklaEkadashi
ShuklaDwadashi
ShuklaTrayodashi
ShuklaChaturdashi
Purnima
KrishnaPratipada
KrishnaDwitiya
KrishnaTritiya
KrishnaChaturthi
KrishnaPanchami
KrishnaShashthi
KrishnaSaptami
KrishnaAshtami
KrishnaNavami
KrishnaDashami
KrishnaEkadashi
KrishnaDwadashi
KrishnaTrayodashi
KrishnaChaturdashi
Amavasya

Methods

getName()

Get localized tithi name

public function getName(): string
Returns:string— Name (e.g., 'First Lunar Day of Bright Half', 'Full Moon')

getPaksha()

Get pakṣa (fortnight)

public function getPaksha(): Paksha
Returns:Paksha— Shukla or Krishna

getNormalizedIndex()

Get normalized index (1–15)

public function getNormalizedIndex(): int
Returns:int— Index within pakṣa

isEkadashi()

Check if this is Ekadashi

public function isEkadashi(): bool
Returns:bool

isPurnimaOrAmavasya()

Check if Purnima or Amavasya

public function isPurnimaOrAmavasya(): bool
Returns:bool

fromLongitudes()

Get tithi from Sun-Moon longitudes

public static function fromLongitudes(float $sunLon, float $moonLon): self
Parameters:
  • $sunLon(float) — Sun longitude in degrees
  • $moonLon(float) — Moon longitude in degrees
Returns:self

getFractionRemaining()

Get fraction remaining in tithi

public static function getFractionRemaining(float $sunLon, float $moonLon): float
Returns:float— Fraction (0.0–1.0)

Paksha

Enum: JayeshMepani\PanchangCore\Core\Enums\Paksha

Represents the two fortnights in a lunar month.

Cases

Shukla = 0
Krishna = 1

Methods

getName()

Get Sanskrit name (localized)

public function getName(?string $locale = null): string
Parameters:
  • $locale (string|null) — Locale code ('en', 'hi', 'gu'). Defaults to configured locale.
Example:
use JayeshMepani\PanchangCore\Core\Enums\Paksha;

$paksha = Paksha::Shukla;
echo $paksha->getName();        // "Bright Half (waxing)"
echo $paksha->getName('hi');    // "शुक्ल"
echo $paksha->getName('gu');    // "શુક્લ"
echo $paksha->getDescription(); // "Waxing moon fortnight (bright half)"

isShukla()

Check if this is the Shukla (bright) fortnight

public function isShukla(): bool

isKrishna()

Check if this is the Krishna (dark) fortnight

public function isKrishna(): bool

opposite()

Get the opposite paksha (Shukla ↔ Krishna)

public function opposite(): self

getRawName()

Get raw programmatic name without localization

public function getRawName(): string
Example:
echo Paksha::Shukla->getRawName();  // "Shukla"
echo Paksha::Krishna->getRawName(); // "Krishna"

getDescription()

Get description

public function getDescription(): string

getTithiRange()

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): bool

normalizeTithi()

Normalize tithi to 1–15 range

public function normalizeTithi(int $tithiIndex): int

Yoga

Enum: JayeshMepani\PanchangCore\Core\Enums\Yoga

Represents the 27 yogas. Each yoga is completed when the Sun-Moon longitude sum advances by 13°20'.

Quick Usage

use JayeshMepani\PanchangCore\Core\Enums\Yoga;

$yoga = Yoga::fromLongitudes(10.0, 20.0); // Ayushman

echo $yoga->getName();                    // "Ayushman"
echo $yoga->getName('hi');                // "आयुष्मान"
echo $yoga->getName('gu');                // "આયુષ્માન"

$remaining = Yoga::getFractionRemaining(10.0, 20.0);
echo round($remaining, 2);                // 0.75

Cases

Vishkumbha
Priti
Ayushman
Saubhagya
Shobhana
Atiganda
Sukarma
Dhriti
Shula
Ganda
Vriddhi
Dhruva
Vyaghata
Harshana
Vajra
Siddhi
Vyatipata
Variyana
Parigha
Shiva
Siddha
Sadhya
Shubha
Shukla
Brahma
Indra
Vaidhriti

Methods

getName()

Get Sanskrit name (localized)

public function getName(?string $locale = null): string
Parameters:
  • $locale (string|null) — Locale code ('en', 'hi', 'gu'). Defaults to configured locale.

fromLongitudes()

Get yoga from Sun-Moon longitudes

public static function fromLongitudes(float $sunLon, float $moonLon): self

getFractionRemaining()

Calculate the fraction of the current yoga that has elapsed

public static function getFractionRemaining(float $sunLon, float $moonLon): float
Parameters:
  • $sunLon (float) — Sun longitude in degrees.
  • $moonLon (float) — Moon longitude in degrees.
Returns:float — Fraction from 0.0 to 1.0

Karana

Enum: JayeshMepani\PanchangCore\Core\Enums\Karana

Represents the 11 karanas (half lunar days). Each tithi is divided into two karanas. Index values: 0-10 (normalized in v4.0 from 1-11).

Quick Usage

use JayeshMepani\PanchangCore\Core\Enums\Karana;

$karana = Karana::fromTithi(12, 0.25); // Bava

echo $karana->getName();               // "Bava"
echo $karana->getName('hi');           // "बव"
echo $karana->getName('gu');           // "બવ"

[$name, $index] = Karana::getFromLongitudes(10.0, 80.0);
echo $name;                            // "Taitila"
echo $index;                           // 12

Cases

Bava = 0
Balava = 1
Kaulava = 2
Taitila = 3
Gara = 4
Vanija = 5
Vishti = 6
Shakuni = 7
Chatushpada = 8
Naga = 9
Kintughna = 10

Methods

getName()

Get Sanskrit name (localized)

public function getName(?string $locale = null): string
Parameters:
  • $locale (string|null) — Locale code ('en', 'hi', 'gu'). Defaults to configured locale.

fromTithi()

Get karana from tithi

public static function fromTithi(int $tithiIndex, float $fraction): self

getFromLongitudes()

Get karana directly from Sun-Moon longitudes

public static function getFromLongitudes(float $sunLon, float $moonLon): array{0: self, 1: int}
Parameters:
  • $sunLon (float) — Sun longitude.
  • $moonLon (float) — Moon longitude.
Returns:array — [Karana enum, index]

Vara

Enum: JayeshMepani\PanchangCore\Core\Enums\Vara

Represents the 7 weekdays, each ruled by a planet.

Quick Usage

use JayeshMepani\PanchangCore\Core\Enums\Vara;

$vara = Vara::fromDayOfWeek(2); // Tuesday

echo $vara->getName();          // "Tuesday"
echo $vara->getName('hi');      // "मंगलवार"
echo $vara->getName('gu');      // "મંગળવાર"
echo $vara->getRulingPlanet();  // "Maṅgala (Mars)"

Cases

Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday

Methods

getName()

Get Sanskrit name

public function getName(): string

getEnglishName()

Get English name

public function getEnglishName(): string

getRulingPlanet()

Get ruling planet

public function getRulingPlanet(): string

fromJulianDay()

Get weekday from Julian Day

public static function fromJulianDay(float $jd): self

Core 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)

Methods

getName()

Get ritu name (localized)

public function getName(?string $locale = null): string

fromSunLongitude()

Get ritu from Sun longitude

public static function fromSunLongitude(float $sunLon): self
Usage:PanchangaEngine::getRitu($sunLon)returns season from Sun longitude

Masa (Lunar Months)

Represents the 12 lunar months in the Hindu calendar.

Chaitra
Vaishakha
Jyeshtha
Ashadha
Shravana
Bhadrapada
Ashvina
Kartika
Margashirsha
Pausha
Magha
Phalguna

Methods

getName()

Get masa name (localized)

public function getName(?string $locale = null): string

fromSunLongitude()

Get masa from Sun longitude

public static function fromSunLongitude(float $sunLon): self

fromAmantaIndex()

Get masa from Amanta month index (0-11)

public static function fromAmantaIndex(int $index): self
Usage:PanchangaEngine::getHinduMonth($sunLon, $moonLon)

Samvatsara (60-Year Cycle)

Represents the 60 years in the Jupiter cycle.

Prabhava
Vibhava
Shukla
Pramoda
Prajapati
… (60 total)
Usage: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)
Usage:Used internally for sign calculations. Each rasi spans 30°.

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 (15 day + 15 night, approx 48 minutes each). Expanded from 15 to 30 cases in v4.0.

Rudra
Ahi
Mitra
Pitri
Vasu
Udaka
Vishvedeva
Vidhatr
… (30 total)
Usage:MuhurtaService::calculateMuhurtaTable($sunrise, $sunset, $nextSunrise)

Methods

getName()

Get muhurta name (localized)

public function getName(?string $locale = null): string

getDaySequence()

Get the 15 daytime muhurtas

public static function getDaySequence(): array

getNightSequence()

Get the 15 nighttime muhurtas

public static function getNightSequence(): array

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)
Usage:MuhurtaService::calculateChogadiyaTable()

Hora

24 hourly planetary divisions of a day.

Sun
Venus
Mercury
Moon
Saturn
Jupiter
Mars

Methods

getName()

Get hora name (localized)

public function getName(?string $locale = null): string

getSequence()

Get the full 24-hour planetary hora sequence for a weekday

public static function getSequence(Vara $vara): array
Parameters:
  • $vara (Vara) — Weekday enum.
Returns:array — Array of 24 Hora enums.

toPlanetIndex()

Get planet index for localization mapping

public function toPlanetIndex(): int
Usage:MuhurtaService::calculateHoraTable()— Each hora spans ~1 hour

CalendarType

Enum: JayeshMepani\PanchangCore\Core\Enums\CalendarType

Determines how lunar months are named and which festivals are observed. Amanta months end on Amavasya (New Moon), while Purnimanta months end on Purnima (Full Moon).

Cases

Amanta
Purnimanta

Methods

getLocalizedName()

Get the localized name for this calendar type.

public function getLocalizedName(?string $locale = null): string
Parameters:
  • $locale (string|null) — Locale code ('en', 'hi', 'gu'). Defaults to null.
Returns:string — Localized calendar type name.
Example:
use JayeshMepani\PanchangCore\Core\Enums\CalendarType;

$amanta = CalendarType::Amanta;
echo $amanta->getLocalizedName('hi'); // "अमांत"

isAmanta()

Check if this calendar follows the Amavasya-Ending system.

public function isAmanta(): bool
Returns:bool — True for Amanta, false otherwise.

isPurnimanta()

Check if this calendar follows the Purnima-Ending system.

public function isPurnimanta(): bool
Returns:bool — True for Purnimanta, false otherwise.

PanchangService

Service: JayeshMepani\PanchangCore\Panchanga\PanchangService

The primary facade-like service that orchestrates all underlying astronomical and astrological components to provide high-level daily and yearly details.

Public Methods

configure()

Configure the JME native ephemeris path for standalone usage.

public function configure(string $ephePath = ""): void

getDayDetails()

Returns exhaustive Panchanga and Muhurta details for a given date and location.

public function getDayDetails(CarbonImmutable $date, float $lat, float $lon, string $tz, float $elevation=0.0, ?CarbonImmutable $calculationAt=null, CalendarType|string $calendarType=CalendarType::Amanta, array $options=[]): array

getSelectedDetails()

Calculate only requested day-detail sections instead of building the full getDayDetails() payload in memory. Returned section values are parity-tested against the original full output.

public function getSelectedDetails(CarbonImmutable $date, float $lat, float $lon, string $tz, array $sections, float $elevation=0.0, ?CarbonImmutable $calculationAt=null, CalendarType|string $calendarType=CalendarType::Amanta, array $options=[]): array
Selectable daily sections:
  • Basic_Details, Panchanga, Special_Yogas, Anandadi_Yoga, Amritadi_Yoga, Nitya_Yoga_Observations, Panchak
  • Maitreya_Yoga, Gajachchhaya_Yoga, Nakshatra_Shool, Disha_Shool, Yatra_Screening
  • Rahu_Vaasa, Chandra_Vaasa, Shiva_Vaasa, Agni_Vaasa, Yogini_Vaasa
  • Panchaka_Rahita, Vara_Tithi_Doshas, Tithi_Observance_Analysis, Vrata_Parana, Hora_Full_Day, Chogadiya_Full_Day, Muhurta_Full_Day, Lagna_Full_Day
  • Rahu_Kaal_Gulika_Yamaganda, Abhijit_Muhurta, Prahara_Full_Day, Daylight_Fivefold_Division
  • Brahma_Muhurta, Dur_Muhurta_Full_Day, Nishita_Muhurta, Vijaya_Muhurta, Godhuli_Muhurta
  • Sandhya, Day_Night_Measures, Gowri_Panchangam, Kala_Vela, Karmakala_Windows, Varjyam, Nakshatra_Tyajya, Amrita_Kaal
  • Pradosha_Kaal, Bhadra, Dharma_Sindhu
Example:
$selected = $panchang->getSelectedDetails(
    $date,
    $lat,
    $lon,
    $tz,
    ['Panchanga', 'Muhurta_Full_Day', 'Dharma_Sindhu'],
    calculationAt: CarbonImmutable::now($tz)
);

$tithi = $selected['Panchanga']['Current_Tithi_At_Input_Now']['name'];

Daily convenience selective APIs

Shortcuts for common selected sections. These use the same selective calculation path as getSelectedDetails().

getBasicDetails(...): array
getPanchanga(...): array
getSpecialYogas(...): array
getMuhurtaFullDay(...): array
getAbhijitMuhurta(...): array
getVarjyam(...): array
getDharmaSindhu(...): array
getSection(CarbonImmutable $date, float $lat, float $lon, string $tz, string $section, float $elevation=0.0, ?CarbonImmutable $calculationAt=null, CalendarType|string $calendarType=CalendarType::Amanta, array $options=[]): array

Panchanga limb selective APIs

Return one Panchanga limb or current-time limb without returning unrelated sections.

getTithi(...): array
getCurrentTithi(...): array
getNakshatra(...): array
getCurrentNakshatra(...): array
getYoga(...): array
getCurrentYoga(...): array
getKarana(...): array
getCurrentKarana(...): array
getVara(...): array

getFields()

Return selected dot-path fields while calculating only the required source sections.

public function getFields(CarbonImmutable $date, float $lat, float $lon, string $tz, array $fields, float $elevation=0.0, ?CarbonImmutable $calculationAt=null, CalendarType|string $calendarType=CalendarType::Amanta, array $options=[]): array
Example:
$fields = $panchang->getFields($date, $lat, $lon, $tz, [
    'Panchanga.Current_Tithi_At_Input_Now.name',
    'Abhijit_Muhurta.abhijit_start',
    'Sunrise',
]);

getFestivalSnapshot()

A lightweight version of getDayDetails() containing only the data required for festival resolution.

public function getFestivalSnapshot(CarbonImmutable $date, float $lat, float $lon, string $tz, float $elevation=0.0, ?CarbonImmutable $calculationAt=null, CalendarType|string $calendarType=CalendarType::Amanta): array

getFestivalYearCalendar()

Builds a complete Gregorian-year calendar of festivals, correctly handling relative dates and consolidation.

public function getFestivalYearCalendar(int $year, float $lat, float $lon, string $tz, float $elevation=0.0, ?CarbonImmutable $calculationAt=null, CalendarType|string $calendarType=CalendarType::Amanta): array

getMonthCalendar()

Build a month-wise calendar summary with canonical festival orchestration, moon visibility fields, Chandra Darshana timing fields, and compact daily Panchang snapshots.

public function getMonthCalendar(int $year, int $month, float $lat, float $lon, string $tz, float $elevation=0.0, array $options=[], ?CarbonImmutable $calculationAt=null, CalendarType|string $calendarType=CalendarType::Amanta): array

getMonthFields()

Build a month calendar with only requested logical field groups. Festival resolution is skipped unless the festivals group is requested.

public function getMonthFields(int $year, int $month, float $lat, float $lon, string $tz, array $fields, float $elevation=0.0, array $options=[], ?CarbonImmutable $calculationAt=null, CalendarType|string $calendarType=CalendarType::Amanta): array
Month field groups:
  • tithi returns tithi, tithi_display, tithi_windows
  • nakshatra returns nakshatra, nakshatra_windows, nakshatra_padas
  • yoga returns yoga, yoga_windows
  • karana returns karana, karana_windows
  • vara returns vara
  • sun returns sun_sign, sunrise, sunset
  • moon returns moon_sign, moon_phase, moonrise/moonset fields, and moon_visibility
  • hindu_calendar returns hindu_calendar
  • festivals returns festivals, daily_observances, sankranti

getCalendarPeriodWindowsRange()

Build dedicated Hindu calendar period windows for a month range without generating full daily month rows. Use this when the client only needs period-level calendar context such as Ayana, Ritu, Samvat, Samvatsara, or Amanta/Purnimanta month windows.

public function getCalendarPeriodWindowsRange(int $fromYear, int $fromMonth, int $toYear, int $toMonth, float $lat, float $lon, string $tz, array $fields=[], float $elevation=0.0, CalendarType|string $calendarType=CalendarType::Amanta): array
Selectable period fields:
  • ayana returns ayana_windows
  • ritu returns ritu_windows
  • vikram_samvat returns vikram_samvat_windows
  • gujarati_samvat returns gujarati_samvat_windows
  • saka_samvat returns saka_samvat_windows
  • kali_samvat returns kali_samvat_windows
  • samvatsara returns samvatsara_windows
  • samvatsara_north returns samvatsara_north_windows
  • amanta_month returns amanta_month_windows
  • purnimanta_month returns purnimanta_month_windows

Window objects intentionally return only name, start_iso, and end_iso. Month windows additionally include index. Internal calculation fields such as Julian day values are not exposed.

getElectionalSnapshot()

Return electional-analysis inputs built from day details, planetary states, sunrise context, and transit moorthy helpers.

public function getElectionalSnapshot(CarbonImmutable $date, float $lat, float $lon, string $tz, float $elevation=0.0, array $options=[]): array

getDailyMuhurtaEvaluation()

Checks current time against all doshas (Bhadra, Varjyam, Rahu Kaal, etc.) and returns a rejection report.

public function getDailyMuhurtaEvaluation(CarbonImmutable $date, float $lat, float $lon, string $tz, ?CarbonImmutable $currentAt=null, float $elevation=0.0, array $options=[]): array

FestivalService

Service: JayeshMepani\PanchangCore\Festivals\FestivalService

Calculates 324 unique festival identities and 122 unique vrat identities based on Tithi, Nakshatra, and complex regional traditions.

Current festival output includes source-aware rule metadata such as source_refs, ritual_profile, localized calculation-basis labels, Chandra Darshana visibility windows, and Satsangi Jeevan / Swaminarayan annual observance profiles.

Recent Festival Rule Coverage

  • Chandra Darshana: resolved from the first likely visible waxing crescent after Amavasya, with visibility_window, observance_window, start_iso, end_iso, duration_seconds, duration_minutes, duration_min, and visibility_assessment.
  • Satsangi Jeevan annual entries: Ramanand Swami Appearance Festival, Chandrayan Vrat, Nara-Narayan Arjun Janmotsav, Dharmadev Janmotsav, Hatadi Festival, Swaminarayan Kurma Jayanti, Snanyatra, Swaminarayan Rathyatra, Hindola Festival Begins, Pavitra Festival, Swaminarayan Varaha Jayanti, and related Dhanurmas, Ramnavami, Parashurama, Narasimha, Gangavatar/Dasahara, Vijayadashami, Sharad Purnima Rasa, Alankar Marjan, and Pushpa-Dolotsav ritual profiles.
  • Profile metadata: festival rows can expose tradition_profile, ritual_profile, ritual_profile_key, source_refs, sect-specific flags, aliases, and localized deity/description strings in English, Hindi, and Gujarati.

Methods

resolveFestivalsForDate()

The primary resolution method using triple-day context (yesterday, today, tomorrow) for high-precision boundaries.

public function resolveFestivalsForDate(CarbonImmutable $date, array $todayDetails, array $tomorrowDetails, ?array $yesterdayDetails = null, ?callable $fetchHistoricalSnapshot = null, bool $includeExtraWinners = false): array
Example:
$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";
}

buildFestivalPayload()

Build the canonical resolved festival object used by service and script outputs. It preserves raw rule keys for integrations while adding localized companion labels, source references, ritual-profile labels, and explicit Chandra Darshana visibility/observance windows for human-facing JSON.

public function buildFestivalPayload(string $name, array $rules, ?array $resolved=null): array

getDailyObservances()

Return generic daily vrata/observance guidance (e.g. Pradosha, Ekadashi).

public function getDailyObservances(array $panchangDetails): array

getFestivalsForYear()

Intentionally disabled at this catalog layer. Year-wide festival output is built by PanchangService::getFestivalYearCalendar(), which owns location-aware Panchang orchestration.

public function getFestivalsForYear(int $year, string $pakshaSystem='Amanta'): array
Throws:LogicException

OutputGeneratorService

Service: JayeshMepani\PanchangCore\Panchanga\OutputGeneratorService

Designed for batch processing and CLI tools. It simplifies the creation of large JSON payloads for static site generation or mobile app bundling.

Batch Methods

generateTodayPanchang()

Generates a snapshot of everything happening "Right Now" including full day details and a muhurta evaluation.

public function generateTodayPanchang(float $lat, float $lon, string $tz, float $elevation=0.0, CalendarType|string $calendarType=CalendarType::Amanta): array

generateTodaySelected()

Generate only selected today-output branches. The details branch accepts the same daily section names as getSelectedDetails().

public function generateTodaySelected(float $lat, float $lon, string $tz, array $sections, array $detailSections=['Basic_Details'], float $elevation=0.0, CalendarType|string $calendarType=CalendarType::Amanta): array
Selectable sections:
  • details, today, or todays_complete_details returns the selected daily details branch.
  • muhurta, muhurta_evaluation, or evaluation returns the current muhurta evaluation branch.

generateFestivals()

Generates a massive year-long JSON-ready array of every festival defined in the package.

public function generateFestivals(int $year, float $lat, float $lon, string $tz, float $elevation=0.0, CalendarType|string $calendarType=CalendarType::Amanta): array

generateFestivalsSelected()

Generate selected festival output branches from the canonical yearly festival calendar.

public function generateFestivalsSelected(int $year, float $lat, float $lon, string $tz, array $sections, float $elevation=0.0, CalendarType|string $calendarType=CalendarType::Amanta): array
Selectable sections:
  • by_date aliases: date, dates
  • flat
  • festival_day_count alias: day_count
  • festival_entry_count alias: entry_count
  • total_festivals aliases: unique_festival_count, festival_identity_count
  • total_vrats aliases: unique_vrat_count, vrat_identity_count

festival_entry_count counts dated occurrences. total_festivals and total_vrats count unique observance identities, so repeated observances such as Pradosh variants or monthly/seasonal vrats are counted once per distinct identity name.

generateFestivalByDate() / generateFestivalFlat()

Convenience wrappers around generateFestivalsSelected() for a single festival branch.

public function generateFestivalByDate(int $year, float $lat, float $lon, string $tz, float $elevation=0.0, CalendarType|string $calendarType=CalendarType::Amanta): array
public function generateFestivalFlat(int $year, float $lat, float $lon, string $tz, float $elevation=0.0, CalendarType|string $calendarType=CalendarType::Amanta): array

generateFestivalsOnly() / generateVrats()

Dedicated selective yearly outputs for non-vrat festivals and vrat-only observances. These use dedicated resolver filtering instead of building the combined yearly payload and slicing it afterward. Their total_festivals and total_vrats fields count unique identities, while festival_entry_count and vrat_entry_count count dated occurrences.

public function generateFestivalsOnly(int $year, float $lat, float $lon, string $tz, float $elevation=0.0, CalendarType|string $calendarType=CalendarType::Amanta): array
public function generateVrats(int $year, float $lat, float $lon, string $tz, float $elevation=0.0, CalendarType|string $calendarType=CalendarType::Amanta): array

generateFestivalsOnlySelected() / generateVratsSelected()

Selective branch readers for the dedicated festival-only and vrat-only yearly pipelines.

public function generateFestivalsOnlySelected(int $year, float $lat, float $lon, string $tz, array $sections, float $elevation=0.0, CalendarType|string $calendarType=CalendarType::Amanta): array
public function generateVratsSelected(int $year, float $lat, float $lon, string $tz, array $sections, float $elevation=0.0, CalendarType|string $calendarType=CalendarType::Amanta): array

generateVratsByDateCompact()

Generates the compact yearly vrat contract used by the CLI, keeping dated observances under by_date while extracting simple weekly weekday vrats into a shared recurring_weekday_vrats block.

public function generateVratsByDateCompact(int $year, float $lat, float $lon, string $tz, float $elevation=0.0, CalendarType|string $calendarType=CalendarType::Amanta): array

generateEclipses()

Generates a list of all solar and lunar eclipses for a range of years.

public function generateEclipses(int $startYear, int $endYear, float $lat, float $lon, string $tz): array

generateEclipsesSelected()

Generate selected eclipse output branches for a year range.

public function generateEclipsesSelected(int $startYear, int $endYear, float $lat, float $lon, string $tz, array $sections): array
Selectable sections:
  • by_year aliases: year, years
  • flat
  • total_eclipse_count alias: count

generateEclipseByYear() / generateEclipseFlat()

Convenience wrappers around generateEclipsesSelected() for a single eclipse branch.

public function generateEclipseByYear(int $startYear, int $endYear, float $lat, float $lon, string $tz): array
public function generateEclipseFlat(int $startYear, int $endYear, float $lat, float $lon, string $tz): array

generateMonthSelected()

Generate selected month-output branches. The calendar branch uses getMonthFields() to return only requested month groups.

public function generateMonthSelected(int $year, int $month, float $lat, float $lon, string $tz, array $sections, array $calendarFields, float $elevation=0.0, array $options=[], ?CarbonImmutable $calculationAt=null, CalendarType|string $calendarType=CalendarType::Amanta): array
Selectable sections:
  • meta alias: metadata
  • calendar aliases: month, fields

generateMonthCalendarFields()

Convenience wrapper for returning only the selected month calendar field groups.

public function generateMonthCalendarFields(int $year, int $month, float $lat, float $lon, string $tz, array $calendarFields, float $elevation=0.0, array $options=[], ?CarbonImmutable $calculationAt=null, CalendarType|string $calendarType=CalendarType::Amanta): array

generateAll()

Combines festivals, eclipses, and today's details into one final unified payload.

public function generateAll(int $festivalYear, int $eclipseStartYear, int $eclipseEndYear, float $lat, float $lon, string $tz, float $elevation=0.0, CalendarType|string $calendarType=CalendarType::Amanta): array

configure()

Global configuration for the service (typically used in standalone mode).

public static function configure(string $ephePath): void
Parameters:
  • $ephePath(string) — Absolute path to ephemeris files

Output Notes

  • Hindu_Calendar in service output includes Month_Amanta, Month_Purnimanta, Is_Adhika, Is_Kshaya, Amanta_Index, and Purnimanta_Index.
  • Service-level month resolution uses exact solar transit boundaries between amavasyas for final day output.
  • Saṅkrānti tagging is mapped to civil-day ingress (00:00-24:00 local date), so pre-sunrise ingress remains on that same calendar date.
  • Empty arrays such as Bhadra: [] or Dharma_Sindhu: [] are valid when no applicable window exists for that Panchang day.
  • The verified yearly catalog currently reports 324 unique festival identities and 122 unique vrat identities after merging true alias/variant duplicates; distinct observances that fall on the same tithi remain separate entries.
  • Named Karmakala windows are exposed directly in Karmakala_Windows so festival-side karmakala_type concepts such as sunrise, madhyahna, aparahna, pradosha, and nishitha map cleanly to daily output.
  • Pratah, Sangava, Madhyahna, Aparahna, Sayahna, Abhijit, Vijaya, Nishitha, Godhuli, Pratah Sandhya, and Sayahna Sandhya use actual local daytime or nighttime proportions where their rule depends on dinamāna or rātrimāna. Arunodaya, Pradosha, and Madhyahna Sandhya use fixed ghaṭī offsets from local solar anchors.

AstronomyService

Service: JayeshMepani\PanchangCore\Astronomy\AstronomyService

High-precision astronomical engine powered by JME native ephemeris FFI.

Methods

getPlanets()

Returns absolute tropical longitudes for all major planets at a given timestamp.

public function getPlanets(array $birth): array

getAscendant()

Calculates the precise longitude of the Ascendant (Lagna) for the given coordinates and time.

public function getAscendant(array $birth): float

SunService

Service: JayeshMepani\PanchangCore\Astronomy\SunService

Dedicated engine for solar/lunar rise and set timings and local time divisions.

Methods

getSunriseSunset() / getMoonriseMoonset()

Calculates rise/set times with sub-second precision.

public function getSunriseSunset(array $birth): array
public function getMoonriseMoonset(array $birth): array

getIshtkaal()

Calculates Ishtkaal (Vedic time elapsed since local sunrise).

public function getIshtkaal(CarbonImmutable $currentTime, CarbonImmutable $sunrise): string

getDaylightFivefoldDivision()

Divides the day into morning, forenoon, midday, afternoon, and evening windows.

public function getDaylightFivefoldDivision(CarbonImmutable $sunrise, CarbonImmutable $sunset): array

getSolarTransits()

Calculates the local solar noon and transit boundaries for the observer.

public function getSolarTransits(array $birth): array

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
Parameters:
$sunLon(float) — Sun longitude in degrees.
$moonLon(float) — Moon longitude in degrees.
Returns:array{index, name, paksha, fraction_left}
Example:

$tithi = $engine->calculateTithi(350.5, 125.3);
echo $tithi['name']; // "Twelfth Lunar Day of Bright Half"
                

getNakshatraInfo()

Determine Nakshatra and Pada from a specific longitude.

public function getNakshatraInfo(float $longitude): array
Parameters:
$longitude(float) — Celestial longitude in degrees.
Returns:array[name, pada, lord]

calculateYoga()

Calculate Yoga from the sum of Sun and Moon longitudes.

public function calculateYoga(float $sunLon, float $moonLon): array
Parameters:
  • $sunLon(float) — Sun longitude.
  • $moonLon(float) — Moon longitude.
Returns:array{index, name}

getKarana()

Get the Karana (half-tithi) from celestial longitudes.

public function getKarana(float $sunLon, float $moonLon): array
Parameters:
  • $sunLon(float) — Sun longitude.
  • $moonLon(float) — Moon longitude.
Returns:array[name, number]

calculateVara()

Calculate weekday (Vara) relative to local sunrise.

public function calculateVara(array $birth, SunService $sunService): array
Parameters:
  • $birth(array) — Timestamp details with location and time.
  • $sunService(SunService) — Helper for sunrise timing.
Returns:array{index, name, lord}

getRitu()

Identify the Vedic season (Ritu) based on solar longitude.

public function getRitu(float $sunLon): string
Parameters:
  • $sunLon(float) — Sun longitude.
Returns:string — Sanskrit name of the season (e.g., "Sharad").

getAyana()

Identify the solar hemisphere (Uttarayana or Dakshinayana).

public function getAyana(float $sunLon): string
Parameters:
  • $sunLon(float) — Sun longitude.
Returns:string — "Uttarayana" or "Dakshinayana".

getSamvat()

Calculate Vikram Samvat and Saka Samvat years.

public function getSamvat(int $year, int $month): array
Parameters:
  • $year(int) — Gregorian year.
  • $month(int) — Gregorian month (1-12).
Returns:array{Vikram_Samvat, Saka_Samvat}

getSamvatsara()

Identify the Samvatsara name in the 60-year Jupiter cycle.

public function getSamvatsara(int $vikramSamvat): string
Parameters:
  • $vikramSamvat(int) — Vikram Samvat year.
Returns:string — Samvatsara name.

getHinduMonth()

Identify the Hindu lunar month for a given moment.

public function getHinduMonth(float $sunLon, float $moonLon, string $paksha='Shukla'): array
Parameters:
  • $sunLon(float) — Sun longitude.
  • $moonLon(float) — Moon longitude.
  • $paksha(string) — Current lunar phase.
Returns:array{Amanta, Purnimanta, Amanta_Index, Purnimanta_Index}

Note: This method documents the simpler PanchangaEngine month helper. Final PanchangService day output uses a stricter true-month resolution based on exact amavasya and sankranti boundaries, and therefore also exposes flags such as Is_Adhika and Is_Kshaya.

getSamvatsaraNorth()

Calculate North Indian Samvatsara name (variant cycle).

public function getSamvatsaraNorth(int $vikramSamvat): string
Parameters:
  • $vikramSamvat(int) — Vikram Samvat year.
Returns:string — North Samvatsara name.

getKaliSamvat()

Calculate the year in the Kali Yuga era.

public function getKaliSamvat(int $vikramSamvat): int
Parameters:
  • $vikramSamvat(int) — Vikram Samvat year.
Returns:int — Kali Samvat year.

getGujaratiSamvat()

Calculate the year in the Gujarati (Kartikadi) Samvat era.

public function getGujaratiSamvat(int $vikramSamvat, int $monthIdx): int
Parameters:
  • $vikramSamvat(int) — Vikram Samvat year.
  • $monthIdx(int) — Month index (0-11).
Returns: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
Parameters:
  • $tithi(int) — Tithi index.
  • $vara(int) — Weekday index.
  • $nak(int) — Nakshatra index.
  • $lagna(int) — Lagna index.
Returns:array{status, classification}

calculateKundaLagna()

Calculate Kunda Lagna (Ascendant * 81) used for birth time rectification.

public function calculateKundaLagna(float $ascendantLongitude): array
Parameters:
  • $ascendantLongitude(float) — Longitude of the Ascendant.
Returns:array{degrees, rasi}

isVishtiKarana()

Determine if the current moment falls under the inauspicious Vishti Karana (Bhadra).

public function isVishtiKarana(float $sunLon, float $moonLon): bool
Parameters:
  • $sunLon(float) — Sun longitude.
  • $moonLon(float) — Moon longitude.
Returns:bool — True if Bhadra is active.

CliBootstrap

Trait: JayeshMepani\PanchangCore\Traits\CliBootstrap

CLI Bootstrap trait for streamlined CLI script setup and service dependency injection. Sets up env(), config(), and the DI container so the package works without a full Laravel framework.

Usage in Scripts

require __DIR__ . '/vendor/autoload.php';

CliBootstrap::init(__DIR__);
$panchangService = CliBootstrap::makePanchangService();

Static Methods

init()

Set up the standalone environment. Call this once at the top of a script.

public static function init(string $baseDir): void
Parameters:
  • $baseDir (string) — Directory containing vendor/autoload.php and config/
Returns:void
Example:
CliBootstrap::init(__DIR__);

makePanchangService()

Create a fully wired PanchangService for standalone usage.

public static function makePanchangService(): PanchangService
Returns:PanchangService — Fully configured service instance.
Example:
$panchangService = CliBootstrap::makePanchangService();

makeEclipseService()

Create an EclipseService.

public static function makeEclipseService(): EclipseService
Returns:EclipseService

makeOutputGenerator()

Create an OutputGeneratorService.

public static function makeOutputGenerator(PanchangService $panchang): OutputGeneratorService
Parameters:
  • $panchang (PanchangService) — PanchangService instance
Returns:OutputGeneratorService

MuhurtaService

Service: JayeshMepani\PanchangCore\Panchanga\MuhurtaService

Advanced engine for time-based divisions, auspicious periods, and negative time clusters.

Methods

calculateHora()

Return the currently active Hora at the supplied calculation moment.

public function calculateHora(CarbonImmutable $sunrise, CarbonImmutable $sunset, CarbonImmutable $nextSunrise, CarbonImmutable $birthAt, int $varaIdx): array

calculateChogadiya()

Return the currently active Chogadiya at the supplied calculation moment.

public function calculateChogadiya(CarbonImmutable $sunrise, CarbonImmutable $sunset, CarbonImmutable $nextSunrise, CarbonImmutable $birthAt, int $varaIdx): array

calculateMuhurtaTable()

Calculate all 30 named Muhurtas for a full 24-hour cycle.

public function calculateMuhurtaTable(CarbonImmutable $sunrise, CarbonImmutable $sunset, CarbonImmutable $nextSunrise): array
Parameters:
  • $sunrise(CarbonImmutable) — Current day sunrise.
  • $sunset(CarbonImmutable) — Current day sunset.
  • $nextSunrise(CarbonImmutable) — Next day sunrise.
Returns:array — 30 muhurta objects with {name, start, end}.

calculateChogadiyaTable()

Calculate 8 day and 8 night Chogadiya periods.

public function calculateChogadiyaTable(CarbonImmutable $sunrise, CarbonImmutable $sunset, CarbonImmutable $nextSunrise, int $varaIdx): array
Parameters:
  • $sunrise(CarbonImmutable) — Sunrise time.
  • $sunset(CarbonImmutable) — Sunset time.
  • $nextSunrise(CarbonImmutable) — Next sunrise time.
  • $varaIdx(int) — Weekday index (0-6).
Returns:array — Detailed list of 16 Chogadiya divisions.

calculateDaylightFivefoldDivision()

Calculate the canonical five daylight divisions: morning, forenoon, midday, afternoon, and evening.

public function calculateDaylightFivefoldDivision(CarbonImmutable $sunrise, CarbonImmutable $sunset): array

calculateNishitaMuhurta()

Calculate the 8th of 15 night Muhurtas centered on the night midpoint.

public function calculateNishitaMuhurta(CarbonImmutable $sunset, CarbonImmutable $nextSunrise): array

calculateVijayaMuhurta()

Calculate the 11th of 15 daytime Muhurtas.

public function calculateVijayaMuhurta(CarbonImmutable $sunrise, CarbonImmutable $sunset): array

calculateGodhuliMuhurta()

Calculate the evening twilight Godhuli Muhurta near sunset.

public function calculateGodhuliMuhurta(CarbonImmutable $sunset, CarbonImmutable $nextSunrise): array

calculateSandhya()

Calculate morning, noon, and evening Sandhya windows. Pratah and Sayahna use three dynamic rātrimāna-ghaṭīs around local sunrise and sunset; Madhyahna remains fixed-ghaṭī based around local solar noon.

public function calculateSandhya(CarbonImmutable $sunrise, CarbonImmutable $sunset, CarbonImmutable $nextSunrise, CarbonImmutable $solarNoon): array

calculateGowriPanchangam()

Calculate weekday-specific Gowri Panchangam day and night divisions.

public function calculateGowriPanchangam(CarbonImmutable $sunrise, CarbonImmutable $sunset, CarbonImmutable $nextSunrise, int $varaIdx): array

calculateKalaVela()

Calculate Kala Vela day/night divisions and named Kala Vela windows.

public function calculateKalaVela(CarbonImmutable $sunrise, CarbonImmutable $sunset, CarbonImmutable $nextSunrise, int $varaIdx): array

calculateHoraTable()

Identify the 24 planetary Hora rulers for the day.

public function calculateHoraTable(CarbonImmutable $sunrise, CarbonImmutable $sunset, CarbonImmutable $nextSunrise, int $varaIdx): array
Parameters:
  • $sunrise(CarbonImmutable) — Sunrise time.
  • $sunset(CarbonImmutable) — Sunset time.
  • $nextSunrise(CarbonImmutable) — Next sunrise time.
  • $varaIdx(int) — Weekday index (0-6).
Returns:array — 24 Hora objects with {planet, start, end}.

calculateAbhijitMuhurta()

Determine the most auspicious midday period (Abhijit).

public function calculateAbhijitMuhurta(CarbonImmutable $sunrise, CarbonImmutable $sunset): array
Parameters:
  • $sunrise(CarbonImmutable) — Sunrise time.
  • $sunset(CarbonImmutable) — Sunset time.
Returns:array{start, end, duration}.

calculateBrahmaMuhurta()

Identify the pre-dawn auspicious period using the dynamic night-muhurta convention. The fixed 48-minute convention is preserved in the returned payload.

public function calculateBrahmaMuhurta(CarbonImmutable $previousSunset, CarbonImmutable $sunrise): array
Parameters:
  • $previousSunset(CarbonImmutable) — Previous civil day's sunset.
  • $sunrise(CarbonImmutable) — Current day's sunrise.
Returns:array{brahma_muhurta_start, brahma_muhurta_end, calculation_convention, fixed_48_minute_convention}

calculateLagna()

Calculate the current sidereal Lagna/ascendant sign for one timestamp and location.

public function calculateLagna(CarbonImmutable $current, CarbonImmutable $sunrise, float $sunriseSunLongitude, float $ayanamsaDeg, float $lat, float $lon, JmeEphFFI $jme): array
Returns:array — Current Lagna longitude, sign index/name, degree in sign, and applied ayanamsa.

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, JmeEphFFI $jme): array
Parameters:
  • $sunrise, $sunset, $nextSunrise(CarbonImmutable) — Boundary timestamps.
  • $sunriseSunLon(float) — Sun longitude at sunrise.
  • $ayanamsa(float) — Calculation offset.
  • $lat, $lon(float) — Coordinates.
Returns: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
Parameters:
  • $sunrise, $sunset, $nextSunrise(CarbonImmutable) — Boundary timestamps.
Returns: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, int $varaIdx): array
Parameters:
  • $sunrise, $sunset, $nextSunrise(CarbonImmutable) — Boundary timestamps.
  • $varaIdx(int) — Weekday index.
Returns:array — List of Dur-Muhurta periods.

calculateVarjyam()

Compatibility helper for one Varjyam (Tyajyam) window for a specific Nakshatra span. For scoped day-level Varjyam and Amrita windows, prefer calculateNakshatraPeriodWindows().

public function calculateVarjyam(CarbonImmutable $sunrise, CarbonImmutable $sunset, CarbonImmutable $nextSunrise, int $nakIdx, float $nakStartJd, float $nakEndJd): array
Parameters:
  • $sunrise, $sunset, $nextSunrise(CarbonImmutable) — Boundary timestamps.
  • $nakIdx(int) — Nakshatra index.
  • $nakStartJd, $nakEndJd(float) — Nakshatra span boundaries.
Returns:array — Varjyam window payload for that Nakshatra. Day-level aggregation is done in PanchangService.

calculateNakshatraPeriodWindows()

Calculate scoped Nakshatra-based period windows using independent ghati offset tables for varjyam or amrita_kaal.

public function calculateNakshatraPeriodWindows(string $type, CarbonImmutable $timezoneReference, int $nakshatraIndex, float $nakshatraStartJd, float $nakshatraEndJd, float $scopeStartJd, float $scopeEndJd): array
Parameters:
  • $type(string) — varjyam or amrita_kaal.
  • $timezoneReference(CarbonImmutable) — Timezone source for formatted output.
  • $nakshatraIndex(int) — Zero-based Nakshatra index.
  • $nakshatraStartJd, $nakshatraEndJd(float) — Exact Nakshatra span.
  • $scopeStartJd, $scopeEndJd(float) — Panchang-day scope, usually sunrise to next sunrise.
Returns:array — zero or more windows with {type, offset_ghati, duration_ghati, window_start_jd, window_end_jd, visible_start_jd, visible_end_jd, is_partial_start, is_partial_end, is_auspicious}.

calculateAmritaKaal()

Legacy compatibility helper. It no longer derives Amrita Kaal from Varjyam end time; day-level Amrita Kaal is calculated independently from nakshatra-specific Amrita ghati offsets.

public function calculateAmritaKaal(CarbonImmutable $sunrise, array $varjyam): array
Parameters:
  • $sunrise(CarbonImmutable) — Sunrise time.
  • $varjyam(array) — Calculated Varjyam results.
Returns:array{is_available: false, window_count: 0, windows: [], calculation_note}. Use calculateNakshatraPeriodWindows('amrita_kaal', ...) for actual Amrita windows.

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
Parameters:
  • $sunset(CarbonImmutable) — Sunset time.
  • $tithiNum(int) — Absolute Tithi index.
Returns:array — Pradosha timings.

calculateBadTimes()

Calculate Rahu Kala, Gulika, and Yamaganda for a given day.

public function calculateBadTimes(CarbonImmutable $sunrise, CarbonImmutable $sunset, int $varaIdx): array
Parameters:
  • $sunrise, $sunset(CarbonImmutable) — Sunrise/Sunset.
  • $varaIdx(int) — Weekday index.
Returns: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
Parameters:
  • $year(int) — Gregorian year.
  • $lat, $lon(float) — Coordinates.
  • $tz(string) — Timezone.
Returns:array — List of eclipse events with times, global type, local type, and visibility. eclipse_type and global_eclipse_type describe the global catalog event; local_eclipse_type describes the event at the requested coordinates when locally applicable.

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
Parameters:
  • $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'.
Returns:array— {mukha, madhya, puchha, lok, status}

ElectionalEvaluator

Service: JayeshMepani\PanchangCore\Panchanga\ElectionalEvaluator

The calculation engine for classical electional (Muhurta) doshas and transit classifications.

Static Methods

calculatePanchakaDosha()

Calculates the 5-fold Panchaka Rahita / Panchaka Dosha classification based on Tithi, Vara, Nakshatra, and Lagna. This is the electional remainder check and is separate from active Moon-in-Panchak weekday subtype labels.

public static function calculatePanchakaDosha(int $tithiNumber, int $varaNumber, int $nakshatraNumber, int $lagnaNumber): array
Returns: array{remainder: int, classification: string, is_auspicious: bool}

calculateDagdhaTithi() / calculateDagdhaYoga()

Checks if current weekday/tithi/moon-sign combinations result in 'Burnt' (Dagdha) status.

public static function calculateDagdhaTithi(int $tithiNumber, int $moonSignIdx): array
public static function calculateDagdhaYoga(int $varaNumber, int $tithiNumber): array

calculateRiktaTithi()

Identifies if the tithi is a 'Rikta' (Empty) tithi (4, 9, 14).

public static function calculateRiktaTithi(int $tithiNumber, bool $isKrishnaPaksha): array

calculateTransitMoorthy()

Classifies planetary transit quality (Gold, Silver, Copper, Iron) relative to the Moon's sign.

public static function calculateTransitMoorthy(string $nakshatraName): array
Returns: array{quality: string, label: string, is_auspicious: bool}

calculateBhadra()

Checks if Bhadra (Vishti Karana) is active based on moon sign index.

public static function calculateBhadra(int $moonSignIdx): array

calculateVarjyam() / calculateAmritaKaal()

Static calculation for Visha Ghati and its corresponding auspicious window.

public static function calculateVarjyam(int $nakshatraNumber, float $nakshatraStartTime, float $nakshatraDurationMinutes): array
public static function calculateAmritaKaal(int $varaNumber, float $sunrise, float $sunset, float $nextSunrise, float $currentTime): array

calculateAbhijitCancellation()

Checks if Abhijit Muhurta is cancelled due to a Wednesday (Budhavara).

public static function calculateAbhijitCancellation(float $sunrise, float $sunset, int $varaNumber, float $currentTime): array

generateRejectionReport()

Takes a bundle of evaluation results and generates a human-readable list of active doshas and an overall verdict.

public static function generateRejectionReport(array $evaluationResults): array

KalaNirnayaEngine

Service: JayeshMepani\PanchangCore\Panchanga\KalaNirnayaEngine

Advanced engine for resolving festival dates based on Punya Kaal, Viddha Tithi, and complex religious timing priorities.

Public Methods

determineEkadashi()

Resolves Smarta vs Vaishnava Ekadashi dates based on Arunodaya and Dashami-overlap rules. The observance payload can include Satsangi Jeevan fasting guidance, standard unable-person allowances, and stricter Prabodhini guidance when Kartika Shukla Ekadashi is active.

public function determineEkadashi(CarbonImmutable $date, array $panchangData): array

calculatePunyaKaal()

Identifies the auspicious 'Punya Kaal' window for Sankrantis.

public function calculatePunyaKaal(string $sankrantiName, float $sankrantiJd, float $sunriseJd, float $sunsetJd, float $nextSunriseJd): array

generateKalaNirnayaReport()

Generates a detailed report explaining WHY a specific festival was resolved to a specific day.

public function generateKalaNirnayaReport(string $festivalName, CarbonImmutable $date, array $panchangDetails): array

VimshottariDasha

Enum: JayeshMepani\PanchangCore\Core\Enums\VimshottariDasha

Calculates planetary periods (Dashas) based on birth Nakshatra.

Methods

getName()

Get dasha name (localized)

public function getName(?string $locale = null): string

fromNakshatra()

Identifies the starting Dasha lord.

public static function fromNakshatra(Nakshatra $nak): self

getDashaYears()

Returns the planetary duration in years.

public function getDashaYears(): int

JSON Response Schema

Complete reference of keys returned by the getDayDetails() "God Object".

v4.0.0 Breaking Change: Inside the nested Panchanga block, Sunrise, Sunset, Moonrise, and Moonset are now objects. Top-level convenience fields such as Sunrise and Moonrise still expose formatted strings.

Core Panchang

  • Tithi — sunrise-based compatibility field; use Tithi_At_Sunrise for explicit sunrise semantics
  • Current_Tithi_At_Input_Now — runtime/input-time tithi
  • Nakshatra — {index, name, lord, pada, end, end_iso, fraction_remaining}
  • Yoga — sunrise-based yoga; Current_Yoga_At_Input_Now exposes runtime/input-time yoga
  • Karana — sunrise-based compatibility field; use Current_Karana_At_Input_Now for runtime/input-time karana
  • Karana_At_Sunrise — explicit sunrise Karana alias
  • Vara — {index, name, lord}

Sun & Moon (Structured Objects)

  • Sunrise / Sunset — {jd, iso, display, timestamp}
  • Moonrise / Moonset — {jd, iso, display, timestamp}
  • Ishtkaal — (Local time elapsed since sunrise)
  • Sun_Longitude / Moon_Longitude — (Decimal Degrees)
  • Sun_Sign / Moon_Sign — {index, name}

Auspicious & Inauspicious Windows

KeyTypeStructure
Abhijit_MuhurtaObject{abhijit_start, abhijit_end, daylight_midpoint, muhurta_duration_minutes}
Brahma_MuhurtaObject{brahma_muhurta_start, brahma_muhurta_end, calculation_convention, fixed_48_minute_convention}
Rahu_Kaal_Gulika_YamagandaObject{rahu_kaal: {start, end}, gulika, yamaganda}
VarjyamObject{is_available, window_count, windows: [{varjyam_start, varjyam_end, window_start_jd, window_end_jd, visible_start_jd, visible_end_jd, offset_ghati, duration_ghati}]}
Amrita_KaalObject{is_available, window_count, windows: [{amrita_kaal_start, amrita_kaal_end, window_start_jd, window_end_jd, visible_start_jd, visible_end_jd, offset_ghati, duration_ghati}]}
Pradosha_KaalObject{base_pradosha_start_iso, base_pradosha_end_iso, pradosha_start_iso, pradosha_end_iso, trayodashi_overlaps}
BhadraArray|null[{name, start, end, mukha, madhya, puchha, lok, status}]

Directional and Transition Outputs

KeyTypeStructure
Chandra_VaasaObject{rule_system: moon_rashi_direction_4_direction, moon_sign, direction, windows, nakshatra_pada_vaasa}
Current_Nakshatra_At_Input_NowObject{name, pada, lord}; runtime/current Nakshatra for the calculation instant
Moon_Phase_At_SunriseObject{key, name, visibility_key, visibility, illumination_band, illumination_fraction, illumination_percent, phase_angle_degrees, synodic_age_days}
Current_Moon_Phase_At_Input_NowObject{key, name, visibility_key, visibility, illumination_band, illumination_fraction, illumination_percent, phase_angle_degrees, synodic_age_days}
Nakshatra_At_SunriseObject{name, pada, lord}; explicit sunrise Nakshatra
TransitionsObject{tithi, nakshatra, yoga, karana, moon_sign, sun_sign}; each current field is input-time based and includes current_at_sunrise where relevant
Resolution_ContextObject{date_iso, sunrise_iso, next_sunrise_iso, tithi_start_jd, tithi_end_jd, nakshatra_start_jd, nakshatra_end_jd, sankranti_rashi}
Day_TypesObject{civil_day_length_seconds, mean_solar_day_seconds, apparent_solar_day_seconds, apparent_solar_noon, solar_midnight}

CLI Tooling & Scripts

Built-in scripts for rapid data generation, batch processing, and data export.

All scripts utilize the CliBootstrap trait for environment-aware dependency injection. Use these for generating JSON data suitable for static sites, mobile apps, or offline use.

Available Scripts

Script Description Output
panchang_today.php Generates today's complete panchang and muhurta evaluation today_panchang.json
panchang_festivals.php [year] [all|festivals|vrats] Exports combined observances, festival-only output, or vrat-only output for a given year as by_date-only JSON festivals_YYYY.json, festivals_only_YYYY.json, or vrats_YYYY.json
panchang_eclipses.php [start] [end] Exports eclipses for a range of years eclipses_YYYY_YYYY.json
panchang_month_output.php [year] [month] Exports monthly panchang data; defaults to current month when no year/month is passed Prints to stdout
panchang_raw_output.php Combines today's data, festivals, and eclipses meta.json, festivals_YYYY.json, etc.

Usage Examples

Generate Today's Panchang
cd scripts
php panchang_today.php
Generate Festivals for 2026
cd scripts
php panchang_festivals.php 2026
Generate Festival-Only and Vrat-Only Yearly Output
cd scripts
php panchang_festivals.php 2026 festivals
php panchang_festivals.php 2026 vrats

Yearly festival JSON files generated by the CLI now emit the compact by_date branch only. The dedicated vrat file also pulls repeated weekly weekday vrats into a shared recurring_weekday_vrats block instead of repeating them on every date. Use the selective runtime APIs when you also need a flat list.

Generate Monthly Data
cd scripts
php panchang_month_output.php 2026 5 > month_2026_05.json

Localization and Calendar Types

Use environment variables to control output format:

Localized Output
PANCHANG_LOCALE=hi PANCHANG_CALENDAR_TYPE=purnimanta php panchang_today.php

Supported locales: en, hi, gu. Calendar types: amanta, purnimanta.

Configuration

Complete reference for config/panchang.php.

Key Type Default Description
ephe_path string __DIR__ . '/../ephe' Path to a JPL .bsp kernel file or a directory containing JPL kernels. Required only for strict jpl mode.
defaults.locale string 'en' Output localization. Supported values: en, hi, gu.
defaults.calendar_type string 'amanta' Preferred lunar month representation. Supported values: amanta, purnimanta.
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.
festivals.supported_traditions array ['Smarta', 'Vaishnava'] Supported tradition identifiers for consumer-side validation.
festivals.supported_regions array ['North', 'South', 'Bengal', 'Maharashtra', 'Tamil', 'Gujarat'] Supported region identifiers for consumer-side validation.
defaults.coordinate_format string 'decimal' Coordinate output format.
defaults.angle_unit string 'degree' Angle formatting for longitudes and ayanamsa.
defaults.duration_format string 'mixed' Duration formatting mode.
cache.enabled bool true Enable package caching.
cache.ttl int 86400 Cache time-to-live in seconds.
cache.prefix string 'panchang_' Cache key prefix.

Batch Processing

Efficiently generating large JSON datasets for applications.

If you are building a static website or a mobile app that needs to work offline, use OutputGeneratorService to export pre-calculated data.

use JayeshMepani\PanchangCore\Panchanga\OutputGeneratorService;

$generator = app(OutputGeneratorService::class);

// 1. Export 10 years of eclipses
$eclipses = $generator->generateEclipses(2025, 2035, 23.24, 69.66, 'Asia/Kolkata');

// 2. Export full year of festivals
$festivals = $generator->generateFestivals(2026, 23.24, 69.66, 'Asia/Kolkata');

// 3. One massive unified export
$all = $generator->generateAll(2026, 2026, 2030, 23.24, 69.66, 'Asia/Kolkata');

Localization

Multilingual support for English, Hindi, and Gujarati.

The package automatically translates all display names (Tithi, Nakshatra, Ritu, etc.) and descriptions based on the defaults.locale config or environment variable.

Switching Locales at Runtime

// Using environment variables (Global)
putenv('PANCHANG_LOCALE=gu');

// The output of any service will now use Gujarati script
$details = Panchang::getDayDetails($date, $lat, $lon, $tz);
echo $details['Current_Tithi_At_Input_Now']['name']; // "વદ તેરસ"

Direct Localization Usage

Use the Localization class directly for custom translations:

use JayeshMepani\PanchangCore\Core\Localization;

// Get translated Nakshatra name
$nakshatraName = Localization::translate('Nakshatra', 0, 'hi'); // "अश्विनी"

// Get translated Tithi
$tithiName = Localization::translate('Tithi', 15, 'gu'); // "પૂનમ"

// Available categories: Nakshatra, Vara, Tithi, Rasi, Yoga, Karana, Choghadiya, Muhurta, Masa, Paksha, Ritu, Ayana, Planet, Samvatsara, Vrata, Eclipse, Festival

Supported Languages

  • en — English
  • hi — Hindi (Devanagari script)
  • gu — Gujarati (Gujarati script)

The Localization class contains comprehensive translations for all panchang elements, including festival names, planetary names, and astrological terms.

Usage Patterns (How do I...?)

Practical code snippets for specific needs. Prefer selective APIs when you do not need the full daily, monthly, festival, or eclipse payload.

I only want the current Tithi name

$tithi = Panchang::getCurrentTithi(
    date: $date,
    lat: $lat,
    lon: $lon,
    tz: $tz,
    calculationAt: CarbonImmutable::now($tz)
);

echo "Current Tithi is: " . $tithi['name'];
// Example output: Current Tithi is: Twelfth Lunar Day of Bright Half

I only want a few exact fields

$fields = Panchang::getFields($date, $lat, $lon, $tz, [
    'Panchanga.Current_Tithi_At_Input_Now.name',
    'Panchanga.Current_Nakshatra_At_Input_Now.name',
    'Abhijit_Muhurta.abhijit_start',
    'Abhijit_Muhurta.abhijit_end',
]);

echo $fields['Panchanga']['Current_Tithi_At_Input_Now']['name'];
// Example output: Twelfth Lunar Day of Bright Half

echo $fields['Abhijit_Muhurta']['abhijit_start'];
// Example output: 12:23:28 PM

I only want the five Panchanga limbs

$panchanga = Panchang::getPanchanga(
    date: $date,
    lat: $lat,
    lon: $lon,
    tz: $tz,
    calculationAt: CarbonImmutable::now($tz)
);

$tithi = $panchanga['Current_Tithi_At_Input_Now'];
$nakshatra = $panchanga['Current_Nakshatra_At_Input_Now'];
$yoga = $panchanga['Current_Yoga_At_Input_Now'];
$karana = $panchanga['Current_Karana_At_Input_Now'];
$vara = $panchanga['Vara'];

echo $tithi['name'];     // Example output: "Twelfth Lunar Day of Bright Half"
echo $nakshatra['name']; // Example output: "Magha"
echo $yoga['name'];      // Example output: "Ayushman"
echo $karana['name'];    // Example output: "Bava"
echo $vara['name'];      // Example output: "Tuesday"

I only want selected daily sections

$selected = Panchang::getSelectedDetails($date, $lat, $lon, $tz, [
    'Panchanga',
    'Muhurta_Full_Day',
    'Abhijit_Muhurta',
    'Dharma_Sindhu',
], calculationAt: CarbonImmutable::now($tz));

$muhurtas = $selected['Muhurta_Full_Day'];
$dharmaSindhu = $selected['Dharma_Sindhu'];

echo count($muhurtas); // Example output: 30
echo $selected['Abhijit_Muhurta']['abhijit_start']; // Example output: "12:23:28 PM"

I want to check if Bhadra (Vishti) is active right now

$eval = Panchang::getDailyMuhurtaEvaluation($date, $lat, $lon, $tz, CarbonImmutable::now());
if ($eval['evaluation_results']['bhadra']['is_active']) {
    echo "Bhadra is active!";
}

echo $eval['evaluation_results']['bhadra']['is_active'] ? 'yes' : 'no';
// Example output: no

I want to get the start and end time of a specific Nakshatra

$details = Panchang::getSelectedDetails($date, $lat, $lon, $tz, ['Panchanga']);

echo "Starts: " . $details['Panchanga']['Nakshatra']['start_iso'];
// Example output: Starts: 23/05/2026 07:28:11 AM

echo "Ends: " . $details['Panchanga']['Nakshatra']['end_iso'];
// Example output: Ends: 24/05/2026 05:48:42 AM

I only want Tithi cells for a month calendar

$calendar = Panchang::getMonthFields(
    year: 2026,
    month: 6,
    lat: $lat,
    lon: $lon,
    tz: $tz,
    fields: ['tithi']
);

$firstDay = $calendar['2026-06-01'];
echo $firstDay['tithi_display']['display'];
// Example output: 16

print_r(array_keys($firstDay));
// Example output: ['date', 'day', 'tithi', 'tithi_display', 'tithi_windows']

I want month calendar cells with festivals, but not every month field

$calendar = Panchang::getMonthFields(
    year: 2026,
    month: 6,
    lat: $lat,
    lon: $lon,
    tz: $tz,
    fields: ['tithi', 'nakshatra', 'festivals'],
    options: ['festival_scope' => 'month']
);

$festivals = $calendar['2026-06-01']['festivals'];
// Example output: []

print_r(array_keys($calendar['2026-06-01']));
// Example output: ['date', 'day', 'tithi', 'tithi_display', 'tithi_windows', 'nakshatra', 'nakshatra_windows', 'nakshatra_padas', 'festivals', 'daily_observances', 'sankranti']

I only want Hindu calendar period windows for a month range

$periods = Panchang::getCalendarPeriodWindowsRange(
    fromYear: 2026,
    fromMonth: 4,
    toYear: 2026,
    toMonth: 6,
    lat: $lat,
    lon: $lon,
    tz: $tz,
    fields: ['ayana', 'ritu', 'amanta_month', 'purnimanta_month']
);

echo $periods['ayana_windows'][0]['name'];
// Example output: Southward Course

print_r($periods['amanta_month_windows'][2]);
// Example output:
// [
//   'name' => 'Jyeshtha (Intercalary)',
//   'start_iso' => '17/05/2026 01:30:56 AM',
//   'end_iso' => '15/06/2026 08:24:04 AM',
//   'index' => 2,
// ]

print_r($periods['purnimanta_month_windows'][2]);
// Example output:
// [
//   'name' => 'Jyeshtha (Intercalary)',
//   'start_iso' => '01/05/2026 10:51:36 PM',
//   'end_iso' => '31/05/2026 02:13:37 PM',
//   'index' => 2,
// ]

I only want festival flat output for a year

$generator = app(\JayeshMepani\PanchangCore\Panchanga\OutputGeneratorService::class);

$flat = $generator->generateFestivalFlat(
    year: 2026,
    lat: $lat,
    lon: $lon,
    tz: $tz
);

foreach ($flat['flat'] as $entry) {
    echo $entry['date'] . ': ' . $entry['festival']['name'] . PHP_EOL;
    // Example output: 2026-01-14: Makara Sankranti
}

I only want eclipse flat output for a year range

$generator = app(\JayeshMepani\PanchangCore\Panchanga\OutputGeneratorService::class);

$eclipses = $generator->generateEclipseFlat(
    startYear: 2026,
    endYear: 2032,
    lat: $lat,
    lon: $lon,
    tz: $tz
);

$count = count($eclipses['flat']);
echo $count;
// Example output: 18

I want the full payload only when I really need everything

$details = Panchang::getDayDetails($date, $lat, $lon, $tz);

$allMuhurtas = $details['Muhurta_Full_Day'];
$allLagnas = $details['Lagna_Full_Day'];
$allDailySections = $details;

echo count($allMuhurtas); // Example output: 30
echo count($allLagnas);   // Example output: 13
echo $details['Panchanga']['Current_Tithi_At_Input_Now']['name'];
// Example output: Twelfth Lunar Day of Bright Half

Constants & Enums

Available options for calculation parameters.

Ayanamsa System

  • LAHIRI — Chitra Paksha (fixed, mandatory for this package)

Traditions

  • Smarta— Standard Dharmasindhu rules
  • Vaishnava— ISKCON/Gaudiya rules

Regions

  • North— Purnimanta calendar (UP, Delhi, Rajasthan)
  • South— Amanta calendar (Karnataka, Andhra, TN)
  • Maharashtra, Gujarat— Regional variations
  • Bengal— Solar calendar variations

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', __DIR__ . '/../ephe'),
    'defaults' => [
        'locale' => env('PANCHANG_LOCALE', 'en'),
        'calendar_type' => env('PANCHANG_CALENDAR_TYPE', 'amanta'),
        'measurement_system' => 'indian_metric',
        'date_time_format' => 'indian_12h',
        'time_notation' => '12h',
        'coordinate_format' => 'decimal',
        'angle_unit' => 'degree',
        'duration_format' => 'mixed',
    ],
    'festivals' => [
        'default_tradition' => 'Smarta',
        'default_region' => 'North',
        'supported_traditions' => ['Smarta', 'Vaishnava'],
        'supported_regions' => ['North', 'South', 'Bengal', 'Maharashtra', 'Tamil', 'Gujarat'],
    ],
    'cache' => [
        'enabled' => true,
        'ttl' => 86400,
        'prefix' => 'panchang_',
    ],
];

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_At_Sunrise']['name']; // "Twelfth Lunar Day of Bright Half"
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

[
  'Display_Settings' => [...],
  'Units' => [...],
  'Tithi' => ['index' => 12, 'name' => 'Twelfth Lunar Day of Bright Half', 'paksha' => 'Shukla'],
  'Tithi_At_Sunrise' => ['index' => 12, 'name' => 'Twelfth Lunar Day of Bright Half', 'paksha' => 'Shukla'],
  'Current_Tithi_At_Input_Now' => ['index' => 13, 'name' => 'Thirteenth Lunar Day of Bright Half', 'paksha' => 'Shukla'],
  'Nakshatra' => ['index' => 10, 'name' => 'Magha', 'pada' => 2, 'lord' => 'Ketu'],
  'Nakshatra_At_Sunrise' => ['index' => 10, 'name' => 'Magha', 'pada' => 2, 'lord' => 'Ketu'],
  'Current_Nakshatra_At_Input_Now' => ['index' => 11, 'name' => 'Purva Phalguni', 'pada' => 1, 'lord' => 'Venus'],
  'Yoga' => ['index' => 9, 'name' => 'Shula'],
  'Current_Yoga_At_Input_Now' => ['index' => 10, 'name' => 'Ganda'],
  'Karana' => ['index' => 23, 'name' => 'Bava'],
  'Karana_At_Sunrise' => ['index' => 23, 'name' => 'Bava'],
  'Current_Karana_At_Input_Now' => ['index' => 24, 'name' => 'Balava'],
  'Vara' => ['index' => 2, 'name' => 'Tuesday', 'lord' => 'Mars'],
  'Hindu_Calendar' => [
    'Month_Amanta' => 'Chaitra',
    'Month_Purnimanta' => 'Chaitra',
    'Is_Adhika' => false,
    'Is_Kshaya' => false,
    'Amanta_Index' => 1,
    'Purnimanta_Index' => 1,
  ],
  'Moon_Phase_At_Sunrise' => [
    'key' => 'waxing_gibbous',
    'name' => 'Waxing Gibbous',
    'visibility' => 'Late afternoon and most of night',
    'illumination_fraction' => 0.73,
    'phase_angle_degrees' => 117.4,
    'synodic_age_days' => 9.62,
  ],
  'Current_Moon_Phase_At_Input_Now' => [
    'key' => 'waxing_gibbous',
    'name' => 'Waxing Gibbous',
    'visibility' => 'Late afternoon and most of night',
    'illumination_fraction' => 0.76,
    'phase_angle_degrees' => 121.1,
    'synodic_age_days' => 9.93,
  ],
  'Rahu_Kaal_Gulika_Yamaganda' => [...],
  'Abhijit_Muhurta' => [
    'abhijit_start' => '12:24:00 PM',
    'abhijit_end' => '01:12:00 PM',
    'daylight_midpoint' => '12:48:00 PM',
  ],
  'Brahma_Muhurta' => [
    'calculation_convention' => 'dynamic_night_muhurta',
    'fixed_48_minute_convention' => [...],
  ],
  'Hora_Full_Day' => [...],
  'Chogadiya_Full_Day' => [...],
  'Muhurta_Full_Day' => [...],
  'Prahara_Full_Day' => [...],
  'Lagna_Full_Day' => [
    [
      'sign_name' => 'Taurus',
      'start_iso' => '...',
      'end_iso' => '...',
      'visible_start_iso' => '...',
      'visible_end_iso' => '...',
      'is_partial_start' => true,
      'is_partial_end' => false,
    ],
  ],
  'Dur_Muhurta_Full_Day' => [...],
  'Daylight_Fivefold_Division' => [...],
  'Nishita_Muhurta' => [...],
  'Vijaya_Muhurta' => [...],
  'Godhuli_Muhurta' => [...],
  'Sandhya' => [...],
  'Gowri_Panchangam' => [...],
  'Kala_Vela' => [...],
  'Karmakala_Windows' => [...],
  'Varjyam' => ['is_available' => true, 'window_count' => 1, 'windows' => [[
    'type' => 'varjyam',
    'offset_ghati' => 14,
    'duration_ghati' => 4,
    'visible_start_iso' => '...',
    'visible_end_iso' => '...',
  ]]],
  'Amrita_Kaal' => ['is_available' => true, 'window_count' => 1, 'windows' => [[
    'type' => 'amrita_kaal',
    'offset_ghati' => 38,
    'duration_ghati' => 4,
    'visible_start_iso' => '...',
    'visible_end_iso' => '...',
  ]]],
  'Pradosha_Kaal' => [...],
  'Bhadra' => [...],
  'Dharma_Sindhu' => [...],
  'Festivals' => [...],
  'Daily_Observances' => [...],
  'Special_Yogas' => [...],
  'Anandadi_Yoga' => [...],
  'Amritadi_Yoga' => [...],
  'Nitya_Yoga_Observations' => ['yoga_index' => 17, 'yoga_name' => 'Vyatipata', 'is_kranti_dosha' => true],
  'Panchak' => [...],
  'Maitreya_Yoga' => [...],
  'Gajachchhaya_Yoga' => [...],
  'Nakshatra_Shool' => [...],
  'Disha_Shool' => [...],
  'Yatra_Screening' => ['current_at_input_now' => ['blocked_directions' => [...], 'direction_grid' => [...]]],
  'Rahu_Vaasa' => [...],
  'Chandra_Vaasa' => [
    'rule_system' => 'moon_rashi_direction_4_direction',
    'direction_key' => 'West',
    'nakshatra_pada_vaasa' => [...],
  ],
  'Shiva_Vaasa' => [...],
  'Agni_Vaasa' => [...],
  'Yogini_Vaasa' => [...],
  'Ekadashi_Observance' => [...],
  // Ekadashi_Observance can include:
  // fasting_guidance.profile
  // fasting_guidance.guidance_keys
  // fasting_guidance.guidance
  // fasting_guidance.source_refs
  'Vara_Tithi_Doshas' => ['active_keys' => ['dagdha'], 'all' => [...]],
  'Tithi_Observance_Analysis' => ['rule_system' => 'smarta_udaya_tithi_structural_analysis', 'current_at_input_now' => ['status' => 'Shuddha'], 'at_sunrise' => ['status' => 'Shuddha']],
  'Vrata_Parana' => ['supported_families' => [['family_key' => 'sankashti_chaturthi']], 'current_at_input_now' => ['family_key' => 'sankashti_chaturthi']],
  'Day_Night_Measures' => ['dinamana' => ['ghati' => 33], 'ratrimana' => ['ghati' => 26]],
  'Nakshatra_Tyajya' => ['is_equivalent_to_varjyam' => true],
  'Transitions' => [...],
  'Resolution_Context' => [...],
]

getFestivalSnapshot() Return Structure

[
  'Festivals' => [
    [
      'name' => 'Holika Dahan',
      'description' => 'Holika bonfire ritual',
      'deity' => 'Vishnu/Prahlada',
      'fasting' => false,
      'regions' => ['Pan-India'],
      'aliases' => [],
      'observance_note' => null,
      'calculation_basis' => [
        'type' => 'tithi',
        'type_name' => 'tithi',
        'basis' => 'tithi',
        'basis_name' => 'tithi',
        'tithi' => [...],
        'paksha' => 'Shukla',
        'paksha_name' => 'Shukla',
        'month' => [
          'calendar_type' => 'amanta',
          'value' => 'Phalguna',
          'name' => 'Phalguna',
        ],
        'karmakala_type' => 'pradosha',
        'karmakala_type_name' => 'pradosha',
      ],
      'resolution' => [...],
      'rules_applied' => [...],
    ],
  ],
  'Tithi' => [...],
  'Vara' => [...],
  'Nakshatra' => [...],
  'Yoga' => [...],
  'Karana' => [...],
  'Sunrise' => '06:14:00 AM',
  'Sunset' => '06:52:00 PM',
  'Moonrise' => '10:12:35 PM',
  'Moonset' => '09:00:37 AM',
  'Moonrise_Date' => '2026-04-05',
  'Moonset_Date' => '2026-04-06',
  'Moonrise_ISO' => '05/04/2026 10:12:35 PM',
  'Moonset_ISO' => '06/04/2026 09:00:37 AM',
  'Moonset_Day_Relation' => 'next_day',
  'Special_Yogas' => [...],
  'Anandadi_Yoga' => [...],
  'Amritadi_Yoga' => [...],
  'Nitya_Yoga_Observations' => [...],
  'Panchak' => [...],
  'Maitreya_Yoga' => [...],
  'Gajachchhaya_Yoga' => [...],
  'Nakshatra_Shool' => [...],
  'Disha_Shool' => [...],
  'Yatra_Screening' => [...],
  'Rahu_Vaasa' => [...],
  'Chandra_Vaasa' => [...],
  'Shiva_Vaasa' => [...],
  'Agni_Vaasa' => [...],
  'Yogini_Vaasa' => [...],
  'Ekadashi_Observance' => [...],
  'Vara_Tithi_Doshas' => [...],
  'Tithi_Observance_Analysis' => [...],
  'Vrata_Parana' => [...],
  'Day_Night_Measures' => [...],
  'Nakshatra_Tyajya' => [...],
  'Resolution_Context' => [...],
]

Festival metadata keeps canonical values for code and localized companion fields for display. The calculation_basis.month block follows the active calendar_type only; it does not emit both amanta and purnimanta months in the same localized output.

getMonthCalendar() Return Structure

[
  '2026-04-01' => [
    'date' => '2026-04-01',
    'day' => 1,
    'tithi' => [...],
    'tithi_display' => [
      'display' => '14',
      'indexes' => [14],
      'phase_indexes' => [14],
      'names' => ['Fourteenth Lunar Day of Bright Half'],
      'has_multiple_tithis' => false,
      'has_kshaya_tithi' => false,
      'kshaya_tithi' => null,
    ],
    'tithi_windows' => [...],
    'nakshatra' => [...],
    'nakshatra_windows' => [...],
    'nakshatra_padas' => [...],
    'yoga' => [...],
    'yoga_windows' => [...],
    'karana' => [...],
    'karana_windows' => [...],
    'vara' => [...],
    'sun_sign' => [...],
    'moon_sign' => [...],
    'moon_phase' => [
      'key' => 'waxing_gibbous',
      'name' => 'Waxing Gibbous',
      'visibility' => 'Late afternoon and most of night',
      'illumination_band' => '51%-99%',
      'illumination_fraction' => 0.73,
      'illumination_percent' => 73.0,
      'phase_angle_degrees' => 117.4,
      'synodic_age_days' => 9.62,
    ],
    'sunrise' => '06:43:00 AM',
    'sunset' => '07:11:00 PM',
    'moonrise' => '...',
    'moonset' => '...',
    'moonrise_date' => '2026-04-01',
    'moonset_date' => '2026-04-02',
    'moonrise_iso' => '01/04/2026 06:26:00 PM',
    'moonset_iso' => '02/04/2026 06:05:00 AM',
    'moonset_day_relation' => 'next_day',
    'moon_visibility' => [
      'starts_at' => '...',
      'starts_on' => '2026-04-01',
      'starts_iso' => '...',
      'ends_at' => '...',
      'ends_on' => '2026-04-02',
      'ends_iso' => '...',
      'ends_day_relation' => 'next_day',
    ],
    'hindu_calendar' => [...],
    'festivals' => [...],
    'daily_observances' => [...],
    'sankranti' => null,
  ],
]

Month calendar note: tithi remains the sunrise-based day label for compatibility, while tithi_display is the calendar-cell helper for UI use. On kshaya/skip days it can expose compact values such as 30/1 together with structured kshaya_tithi metadata.

Moon visibility note: month output preserves compact moonrise and moonset display fields, but also includes date-qualified fields because a moonset can occur after midnight on the next civil date.

Moon phase note: moon_phase is a visual phase classification derived from exact Sun-Moon elongation and illuminated fraction. It is intentionally separate from Tithi.

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 "Current Tithi: " . $today['Current_Tithi_At_Input_Now']['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. Planetary Positions for a Timestamp

// Get planetary positions and ascendant for a timestamp/location
$timestampData = [
    'year' => 1990, 'month' => 5, 'day' => 15,
    'hour' => 14, 'minute' => 30, 'second' => 0,
    'tz' => 'Asia/Kolkata', 'lat' => 28.61, 'lon' => 77.20
];

$planets = $astronomy->getPlanets($timestampData);
$ascendant = $astronomy->getAscendant($timestampData);

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);

$currentTithi = $details['Current_Tithi_At_Input_Now']; // Runtime tithi
$sunriseTithi = $details['Tithi_At_Sunrise'];           // Sunrise tithi
$currentKarana = $details['Current_Karana_At_Input_Now'];
$sunriseKarana = $details['Karana_At_Sunrise'];
$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
$brahma   = $details['Brahma_Muhurta'];      // Dynamic night-muhurta convention
$badTimes = $details['Rahu_Kaal_Gulika_Yamaganda']; // Rahu, Gulika, Yamaganda
$durs     = $details['Dur_Muhurta_Full_Day']; // Inauspicious Muhurtas
$sandhya  = $details['Sandhya'];              // Morning / Noon / Evening
$gowri    = $details['Gowri_Panchangam'];     // Day + night Gowri divisions
$karmakala = $details['Karmakala_Windows'];   // Named daily windows

6. Transit-Only Muhurta Evaluation

$evaluation = Panchang::getDailyMuhurtaEvaluation(
    date: CarbonImmutable::now()->startOfDay(),
    lat: $lat,
    lon: $lon,
    tz: $tz,    currentAt: CarbonImmutable::now($tz)
);

$verdict = $evaluation['rejection_report']['overall_verdict'];
$bhadraActive = $evaluation['evaluation_results']['bhadra']['is_active'];
$varjyamActive = $evaluation['evaluation_results']['varjyam']['is_active'];

7. Raw JSON Exporter

Use this when you want the complete all-in-one package output in a single JSON file:

php scripts/panchang_raw_output.php > output.json

This writes meta, festivals_2026, eclipses_2026_2032, todays_complete_details, and muhurta_evaluation in one file.

Additional standalone exporters are available in scripts/:

php scripts/panchang_today.php
php scripts/panchang_month_output.php 2026 5 > month_2026_05.json
php scripts/panchang_eclipses.php 2026 2032
php scripts/panchang_festivals.php 2026

panchang_today.php writes today_panchang.json automatically and prints status text only. panchang_month_output.php prints JSON to stdout only, so choose the filename with shell redirection. Without arguments it generates the current month. panchang_eclipses.php writes eclipses_YYYY_YYYY.json automatically and prints status text only. panchang_festivals.php writes festivals_YYYY.json automatically and prints status lines; do not redirect its stdout as raw JSON.

Use PANCHANG_LOCALE=en|hi|gu and PANCHANG_CALENDAR_TYPE=amanta|purnimanta to generate localized/calendar-type variants. For a dedicated output directory, move implicit-output files after generation and redirect stdout-only scripts directly:

cd scripts
dir="output/amanta/gu"
mkdir -p "$dir"

PANCHANG_CALENDAR_TYPE=amanta PANCHANG_LOCALE=gu php panchang_today.php > /tmp/today.log
mv -f today_panchang.json "$dir/today.json"

PANCHANG_CALENDAR_TYPE=amanta PANCHANG_LOCALE=gu php panchang_festivals.php 2026 > /tmp/festivals.log
mv -f festivals_2026.json "$dir/festivals_2026.json"

PANCHANG_CALENDAR_TYPE=amanta PANCHANG_LOCALE=gu php panchang_month_output.php 2026 5 > "$dir/month_2026_05.json"

PANCHANG_CALENDAR_TYPE=amanta PANCHANG_LOCALE=gu php panchang_eclipses.php 2026 2032 > /tmp/eclipses.log
mv -f eclipses_2026_2032.json "$dir/eclipses_2026_2032.json"

Accuracy & Date Range

Technical specifications of the JME native 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

*Strict JPL mode requires a compatible .bsp kernel file. Analytical modes are provided by the native JME runtime.

Kernel File Choices

JPL mode can use one of the published JME kernel release assets:

  • de440s.bsp — small kernel for lightweight installs
  • de440.bsp — medium kernel recommended for normal JPL testing
  • de441.bsp — large long-range kernel, published as split release assets

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

Common exceptions and how to handle them
Exception When It Occurs How to Handle
RuntimeException JME native 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: Lahiri is fixed and cannot be changed in this package.
  • Location: Ensure exact latitude/longitude.
  • Tradition: Smarta vs Vaishnava have different rules.
  • Engine Mode: The default moshier mode is analytical and does not need external files. Strict jpl mode requires a compatible .bsp kernel configured through PANCHANG_EPHE_PATH.
  • Panchang Day: Remember we use sunrise-to-sunrise days, not midnight-to-midnight.
⚠️ Why is the time wrong in my database/storage?
Answer

Always use _iso fields for storage. Time-only fields lack date context:

// WRONG - loses date context
DB::table('events')->insert([
    'varjyam_start' => $details['Varjyam']['varjyam_start'] // "03:31 AM"
]);

// CORRECT - includes full date
DB::table('events')->insert([
    'varjyam_start' => $details['Varjyam']['varjyam_start_iso'] // "28/03/2026 03:31 AM"
]);
⚠️ Why does Varjyam show different times than expected?
Answer

Varjyam can occur 0, 1, or 2 times per day. Always check window_count:

// Check how many windows exist
$count = $details['Varjyam']['window_count'];

if ($count === 0) {
    // No Varjyam today
} elseif ($count === 1) {
    // One window - use top-level keys
    $start = $details['Varjyam']['varjyam_start'];
} else {
    // Two windows - iterate windows array
    foreach ($details['Varjyam']['windows'] as $window) {
        $start = $window['window_start_iso'];
        $end = $window['window_end_iso'];
    }
}
⚠️ Why is the Hindu month different from other calendars?
Answer

We use exact amavasya-to-amavasya solar transit logic, not simple longitude heuristics:

  • Month is determined by which solar transit occurs between two amavasyas
  • Adhika Masa (extra month) occurs when two amavasyas happen without a solar transit
  • Kshaya Masa (lost month) occurs when no amavasya occurs in a solar month (very rare)

This is more accurate than simpler methods but can differ from other packages.

Can I change the ayanamsa?
Answer
No. This package is Lahiri-only by design for Panchang correctness.
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 configured festival tradition profile or compare adjacent-day festival outputs.

How accurate are the calculations?
Answer

We use JME native 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! JME native ephemeris supports dates from 3000 BCE to 3000 CE. Just pass any valid CarbonImmutable date.

How do I handle multiple traditions?
Answer

Calculate for both traditions and compare:

$smarta = $panchang->getDayDetails($date, $lat, $lon, $tz, elevation: 0.0, options: ['tradition' => 'Smarta']);
$vaishnava = $panchang->getDayDetails($date, $lat, $lon, $tz, elevation: 0.0, options: ['tradition' => 'Vaishnava']);

// Compare festivals
$smartaFestivals = $smarta['Festivals'];
$vaishnavaFestivals = $vaishnava['Festivals'];

Release and Upgrade Notes

Current release history and compatibility notes from v1.0.0 through the latest v10.4.1 release.

Upgrade Notes

Review the version-specific notes below before upgrading. v10.4.1 restores Ashvina-season festival and vrat output after the English month display spelling changed to Ashwin, preserving the v10.4.0 dynamic kala and chronometry behavior while recovering the expected 324 festival / 122 vrat identity set. v10.4.0 moves key kala and vedha chronometry from fixed elapsed-time assumptions to dynamic dinamāna / rātrimāna divisions where required, adds generated night fivefold and full ten-kāla outputs, refines Pradosha and parāṇa timing metadata, and hardens multilingual user-facing localization. v10.3.1 corrects the Govardhan Puja / Bali Pratipada / Annakut decision path with sayahna-vyapini Pratipada and Sthula Chandra Darshana safeguards. v10.3.0 completes the Chandra Darshana visibility architecture, adds Hindola higher-tithi preference, corrects eclipse Sutak relaxed-start times, and exposes modern crescent-visibility metrics in all Chandra Darshana outputs. v10.2.0 adds generated calendar-period windows, Sayana ayana/ritu output, Mahadiksha guidance, Vratni Purnima coverage, and refreshed 324 festival / 122 vrat identity documentation. The prior corrections from v10.1.0 through v10.0.0 remain unchanged.

Current Documentation Snapshot

This documentation is refreshed from the latest generated 2026 outputs for v10.4.1: 324 festival identities and 122 vrat identities, with Amanta/Purnimanta output in English, Hindi, and Gujarati.

Generated today, month, and raw output include calendar_period_windows with sidereal and Sayana ayana/ritu windows; day-detail payloads also expose Sayana_Ayana, Sayana_Ritu, and Mahadiksha_Guidance where included.

Published Releases

  1. 10.4.1
    Ashwin Month Alias Restoration and Festival Catalog Output FixLatest Release

    Patch release restoring Ashvina-season festival and vrat emission after the English month display spelling was normalized to Ashwin. Month matching now treats Ashwin, Ashwina, and Ashvina as the same canonical lunar month for rule selection, recovering Navaratri, Deepavali-family observances, Ashvina Ekadashi vrats, Ahoi Ashtami, Karva Chauth, and related output while keeping the v10.4.0 dynamic timing behavior intact.

  2. 10.4.0
    Dynamic Day-Night Kala Timing, Pradosha and Parana Chronometry, and Localization Refinement

    Minor release aligning key Panchang timing windows with dynamic day and night divisions where the Nirnay-style rules require them. This release adds generated night fivefold and full ten-kāla outputs, moves Pradosha and related night timing from fixed offsets to rātrimāna-based windows, refines dynamic ghadi reporting in Ekadashi parāṇa and allied rule metadata, and tightens English, Hindi, and Gujarati user-facing localization across nakshatra, month, festival-rule, and observance output.

  3. 10.3.1
    Govardhan Puja and Bali Pratipada Decision Correction

    Patch release correcting the Govardhan Puja / Bali Pratipada / Annakut selection path. The decision now requires sayahna-vyapini Pratipada, protects against Sthula Chandra Darshana risk when Pratipada is too short after sunrise, keeps Bestu Varas separate, and updates localized decision labels in English, Hindi, and Gujarati. The 2026 Bhuj generated output shifts Govardhan Puja and Bali Pratipada from November 10 to November 9 without changing festival or vrat identity totals.

  4. 10.3.0
    Chandra Darshana Visibility Architecture, Hindola Higher-Tithi Preference, and Eclipse Sutak Corrections

    Minor release completing the Chandra Darshana modern crescent-visibility engine: the visibility gate now applies across all three resolution branches (short Pratipada, Dwitiya fallback, Kshaya); modern astronomical metrics (lag, elongation, illumination) are always embedded in visibility_assessment.modern_visibility for auditing; yesterday's sunset/moonset data is injected into Resolution_Context; the Dwitiya branch gains a double-observation guard using yesterday's visibility; and Hindola Festival gains a prefer_higher_tithi_option to resolve Dwitiya over Pratipada when both qualify. Eclipse Sutak relaxed-start times are corrected for 8 of 9 events. New Gujarati localization strings are added for all new Chandra Darshana reason keys.

  5. 10.2.0
    Calendar Period Windows, Mahadiksha Guidance, and Vrat Rule Expansion

    Minor release adding generated calendar-period windows for today, month, and raw outputs; exposing sidereal and Sayana ayana/ritu windows; adding day-detail Mahadiksha guidance; refreshing festival/vrat rule metadata and localization; adding generic Vratni Purnima coverage; and regenerating Amanta/Purnimanta JSON across English, Hindi, and Gujarati. The latest generated output reports 324 festival identities and 122 vrat identities.

  6. 10.1.0
    Nirnay Rule Expansion, Eclipse Ritual Refinements, and Multilingual Output Refresh

    Minor release refreshing festival and vrat rule coverage, calendar-specific Nag Panchami handling, eclipse ritual guidance, and generated Amanta/Purnimanta JSON output across English, Hindi, and Gujarati.

  7. 10.0.8
    Ekadashi Alias Expansion and Formal Naming Cleanup

    Patch release expanding canonical alias coverage across the Ekadashi family and aligning the festival registry, identity documentation, and localization layer with the refreshed identity set.

  8. 10.0.7
    Phuldolotsava Rule Refinement, Purnimanta Month Corrections, and Calendar-Aware Paksha Support

    Patch release refining Phuldolotsava (Satsangi Jeevan Dolotsav) with accurate Krishna Pratipada + Uttara Phalguni vyapini rules and structured metadata, introducing paksha_amanta / paksha_purnimanta support, correcting month_purnimanta values across multiple avatar and tithi observances, exposing richer rule metadata, and updating localization. All outputs regenerated.

  9. 10.0.6
    Festival Catalog and Localization Refresh

    Patch release refreshing the public festival and vrat catalog, tightening overlapping alias and rule handling in the current registry, and keeping the updated user-facing labels aligned across supported languages.

  10. 10.0.4
    Festival Identity and Rule Alignment

    Patch release consolidating Siddhivinayaka Chaturthi into the Vinayaka Chaturthi alias set, separating Kurma Jayanti from Vaishakha Purnima convention handling, aligning Skanda Sashti with its evening decision path, and localizing the new user-facing festival-rule labels.

  11. 10.0.3
    Adhika and Kshaya Maas Boundary Correction

    Patch release correcting rare lunar month-boundary handling for Adhika Maas, Kshaya Maas, and returning Nija Maas across both Amanta and Purnimanta systems. Keeps skipped months out of the active month label, preserves intercalary Jyeshtha timing in 2026, and aligns rare 2123–2124 Pausha-Kshaya sequencing with expected public Panchang behavior.

  12. 10.0.2
    Dynamic Sandhya Timing Alignment

    Patch release aligning Pratah and Sayahna Sandhya timing with the dynamic rātrimāna-ghaṭī convention used by published Panchang output. Pratah Sandhya now ends at sunrise, Sayahna Sandhya begins at sunset, and both use three dynamic night-ghaṭīs based on actual local rātrimāna.

  13. 10.0.1
    Ekadashi Parana Timing Correction

    Patch release correcting Ekadashi parana timing. Enforces the first-six-ghaṭī morning cap when Dvādaśī continues past Madhyāhna, applies restricted nakṣatra-pada blocking only when active at parana opening, and reopens the remaining Dvādaśī window if an active restriction consumes the early cap.

  14. 10.0.0
    Relaxed Eclipse-Sutak Timing Correction

    Major release with a corrected relaxed food restriction window during visible eclipses. The window for children, elderly people and the unwell now starts one full local prahara before eclipse contact. Regular Sutak timing is unchanged. All eclipse and raw outputs have been refreshed.

  15. 9.8.0
    Dynamic Dinamāna/Rātrimāna Periods and Raksha Bandhan Rule Correction

    Corrects day and night period handling so proportional windows use actual local dinamāna and rātrimāna, while ghaṭī remains a fixed elapsed-time unit. Adds dedicated Raksha Bandhan Nirnay selection with a dynamic three-day-muhūrta Udaya Purnima threshold, improves karmakāla windows, and refreshes generated festival and vrat output.

  16. 9.7.0
    Classical Muhurta Quality Correction and Nārada-Aligned Durmuhūrta Schedule

    Aligns the 30 muhūrtas with classical sources: corrects base tyājya labels (Indragni and Īśa now Inauspicious; Arka and Vāyu now Auspicious). Introduces clear separation between fixed base quality and weekday-specific Durmuhūrta using the Nārada verse. Adds quality and index fields to muhūrta table output and provides authoritative weekday Durmuhūrta indexes.

  17. 9.6.0
    Sun and Moon Position Accuracy Fix

    Fixes a double annual aberration error in JPL ephemeris calculations for Sun and Moon. Applies the NO_ABERRATION flag consistently in key astronomy services and traits for correct apparent positions. All 2026 data regenerated with improved precision.

  18. 9.5.0
    Chandra Darshana Visibility and Satsangi Jeevan Observance Expansion

    Adds support for Chandra Darshana (the first visible waxing crescent), expands Swaminarayan tradition festivals and vrats, provides improved Ekadashi fasting guidance, includes a dedicated decision tree document, and regenerates all 2026 localized outputs.

  19. 9.4.0
    Ekadashi Parana Classification and Preferred Window Output

    Expands Ekadashi observance output with explicit Tithyavasara versus Harivasara classification, preferred first-six-ghatika daytime parana windows when Dwadashi runs past Madhyahna, localized user-facing parana labels, and regenerated daily, festival, vrat, and raw artifacts.

  20. 9.3.0
    Eclipse Ritual Gating and Festival Truth Table Refinements

    Refines local eclipse ritual visibility and sutak handling, corrects Panchak weekday locking to JD-based resolution, and updates major festival decision tables including Diwali, Ram Navami, Hari Jayanti, Vamana Jayanti, Samaveda Upakarma, and Phuldolotsava.

  21. 9.2.0
    General Panchang Rule Outputs and Localization Hardening

    Expands the public non-natal daily rule-engine surface with Panchak subtype locking, Nitya Yoga flags, Tithi and vrata observance analysis, Yatra screening, Nakshatra Tyajya, and localized user-facing output cleanup.

  22. 9.1.0
    Calendar Period Selective API and Purnimanta Intercalary Fix

    Minor release adding a dedicated selective API for Hindu calendar period windows and correcting intercalary month labeling in Purnimanta month-window output.

  23. 9.0.0
    Verified Nirnay Rules, Panchang Conventions, and Localized Output Contract

    Major release aligning festival, vrat, eclipse, sunrise, moonrise, Ekadashi-parana, and generated JSON behavior with verified engine conventions and localized user-facing output.

  24. 8.4.0
    Exact Month-Range Selective APIs

    Minor release adding true exact month-range selective generation for month calendars, festivals, vrats, and eclipses so consumers can request only the bounded span they need.

  25. 8.3.0
    Selective Festival/Vrat Outputs and Compact Vrat JSON

    Minor release adding dedicated yearly festival-only and vrat-only generation paths, switching generated yearly observance files to by-date output, compacting repeated weekday vrats into a shared recurring block, and extending the selective model to exact month-range generation for months, festivals, vrats, and eclipses.

  26. 8.2.1
    Localization Corrections and Output Cleanup

    Patch release focused on user-facing localization corrections, generated output cleanup, and documentation sync across daily, month, and raw Panchang outputs.

  27. 8.2.0
    High-Precision Eclipse Obscuration and JPL Mapping Refinements

    Significant improvement to eclipse accuracy. This version introduces a new geometric engine for area-based obscuration, corrects JME/JPL data structure mappings for solar and lunar diameters, and adds specific support for annular eclipse phases.

  28. 8.1.0
    Selective APIs and Modular Output Generation

    Backward-compatible feature release adding selective daily, month, today, festival, and eclipse APIs so consumers can calculate and return only the branches they need.

  29. 8.0.0
    Moon Phase, Kshaya Tithi, and Calendar Output Refresh

    Major release focused on clearer calendar output, richer month-view data, better English-facing labels, and first-class moon phase information for daily and monthly Panchang use.

  30. 7.0.2
    Brahma Muhurta Calculation Fix

    Fixes a before-sunrise Brahma Muhurta calculation issue that could stop daily Panchang JSON generation.

  31. 7.0.1
    Regional Localization and Festival calculation improvements

    A backward-compatible update modifying 2 core PHP files to consolidate festival definitions (such as Shakambhari Purnima and Pradosh Vrat) and standardise Hindi/Gujarati translation formatting.

  32. 7.0.0
    Panchang Accuracy, Festival Expansion, and Output Improvements

    Major release focused on improving Panchang clarity, Muhurta accuracy, festival coverage, eclipse handling, and overall timing precision.

  33. 6.0.2
    Today Output Field Corrections

    Clarifies current-time versus sunrise-based output fields and corrects daily Panchang details after the v6 migration.

  34. 6.0.1
    JPL Fail-Fast and Eclipse Logic Refinements

    Hardens JME/JPL configuration handling and refines eclipse visibility logic.

  35. 6.0.0
    JME Native Ephemeris Migration

    Migrates the astronomical backend to the project-owned JME native ephemeris FFI path. Validate deployment FFI configuration before upgrading production environments.

  36. 5.0.0
    Yoga, Shoola, Vaasa and Moon Visibility Expansion

    Expands day-level output with special yogas, direction checks, Vaasa signals, and moon visibility fields.

  37. 4.1.1
    PHP 8.3+ Syntax Modernization and Documentation Polish

    Modernizes syntax and documentation while keeping the v4 public model intact.

  38. 4.1.0
    Festival Registry Refine and Minor Fixes

    Refines festival registry behavior and resolves smaller v4 follow-up issues.

  39. 4.0.0
    Universal Panchanga: Architectural Maturity and Global Reach

    Major compatibility release. See the dedicated v4.0.0 compatibility notes below.

  40. 3.0.0
    Lahiri-only, Sankranti Fix and Quality Hardening

    Standardizes the calculation model around Lahiri ayanamsa and tightens Sankranti behavior.

  41. 2.0.1
    Purge of Activity-Based Muhurta Logic

    Removes activity-specific Muhurta assumptions in favor of calculation-first daily windows.

  42. 2.0.0
    Expanded Karmakala Support, Transit-Only Muhurta Cleanup and Output Normalization

    Introduces wider Karmakala support and normalizes Muhurta output structures.

  43. 1.2.0
    Festival Registry Refactor, True Hindu Month Resolution and Precision Output Cleanup

    Refactors festival rules and improves month-resolution precision.

  44. 1.1.0
    Precision Calendar Fixes and Raw JSON Exporter

    Adds raw JSON export support and fixes precision calendar output details.

  45. 1.0.0
    Initial Release

    Initial public Panchang Core package release.

v10.4.1 Upgrade & Release Notes

This patch release restores Ashvina-season festival and vrat output after the English display month spelling changed to Ashwin, without changing the v10.4.0 dynamic timing model.

Compatibility Notes

  • Festival and vrat identity totals are restored: generated output again reports 324 festival identities and 122 vrat identities.
  • Ashvina / Ashwin month matching is canonicalized: rule matching now treats Ashwin, Ashwina, and Ashvina as the same lunar month while preserving user-facing month spelling.
  • Ashvina-season observances are restored: Navaratri, Deepavali-family festivals, Ashvina Ekadashi vrats, Ahoi Ashtami, Karva Chauth, and related entries are emitted again in generated festival and vrat JSON.
  • No payload structure changed: this is a catalog restoration and rule-matching patch, not a schema redesign.

Upgrade Actions

  • Regenerate cached festival, vrat, month, today, and raw JSON after upgrading from v10.4.0.
  • Rebaseline snapshots that compare exact festival counts, vrat counts, Ashvina/Ashwin month observances, or generated festival/vrat identity sets.

v10.4.0 Upgrade & Release Notes

This release upgrades core Panchang chronometry to dynamic day and night division logic where the rule system depends on dinamāna and rātrimāna, expands generated kala output, and refreshes multilingual user-facing labeling.

Compatibility Notes

  • Night-window timing is broader and more explicit: generated Panchang output now includes Nighttime_Fivefold_Division and DayNight_Tenfold_Kala_Division in the day-detail surface.
  • Pradosha timing now follows dynamic night division: Pradosha is calculated from local sunset using three night muhūrtas derived from actual rātrimāna, instead of a fixed elapsed-time approximation.
  • Dynamic ghadi metadata is now exposed more clearly: Ekadashi parāṇa and related outputs report dynamic day-based ghadi interpretation where the rule depends on day length.
  • Localized user-facing labels were refreshed: generated English, Hindi, and Gujarati festival and vrat outputs now use corrected spellings and fuller localization for rule names, notes, and metadata labels.
  • Identity totals are unchanged: the generated output continues to report 324 festival identities and 122 vrat identities.

Upgrade Actions

  • Regenerate cached today, month, raw, festival, vrat, and localized JSON output after upgrading.
  • Rebaseline snapshots or downstream comparisons that assert on Pradosha windows, night-kāla fields, parāṇa ghadi metadata, or localized user-facing strings.

v10.3.1 Upgrade & Release Notes

This patch release corrects the Govardhan Puja / Bali Pratipada / Annakut decision path and regenerates the public JSON outputs without changing identity totals.

Compatibility Notes

  • Govardhan-family observance date corrected: for the 2026 Bhuj generated output, Govardhan Puja and Bali Pratipada move from November 10 to November 9.
  • Sayahna-vyapini Pratipada is enforced: Govardhan / Annakut selection now requires Pratipada to remain active in the evening window.
  • Sthula Chandra Darshana safeguard refined: if Pratipada is too short after sunrise or leads to an evening Dwitiya / Chandra Darshana risk, the observance uses the Amavasya-viddha previous day.
  • Bestu Varas remains separate: the sunrise-based new year observance is not moved by the Govardhan / Annakut evening rule.
  • Identity totals are unchanged: the latest generated output still reports 324 festival identities and 122 vrat identities.
  • Localized decision labels updated: new Govardhan-family decision reasons are available in English, Hindi, and Gujarati output.

Upgrade Actions

  • Regenerate cached festival, month, today, raw, and localized JSON output after upgrading.
  • Rebaseline tests or snapshots that assert on Govardhan Puja, Bali Pratipada, Annakut, or Deepotsav-family observance dates.

v10.3.0 Upgrade & Release Notes

This release completes the Chandra Darshana visibility engine, introduces the higher-tithi festival preference system, corrects eclipse Sutak relaxed-start times, and regenerates the public JSON outputs.

Compatibility Notes

  • Eclipse Sutak relaxed-start times corrected: relaxed_start in the eclipse output changed for 8 of 9 events (2026–2032). Rebaseline any snapshot tests that assert on exact eclipse Sutak times.
  • visibility_assessment now includes modern_visibility: all Chandra Darshana outputs include a new nested modern_visibility object with lag_minutes, elongation_degrees, illumination_percent, and individual pass/fail flags, regardless of whether the heuristic flag is enabled. Consumers that iterate over keys of visibility_assessment should handle this new nested object.
  • Modern visibility gate is a true rejection filter when enabled: when chandra_darshana_visibility_affects_selection: true is set on a festival rule, the crescent-visibility check now applies to all resolution branches (short Pratipada, Dwitiya fallback, Kshaya Pratipada), not only to the long-Pratipada override. The default (flag absent or false) is unchanged.
  • Dwitiya double-observation guard added: when the visibility flag is enabled and Dwitiya is active at the preceding day's sunset, the engine skips the Dwitiya candidate to prevent a double-observation. This new Resolution_Context data (prev_sunset_jd, prev_moonset_jd, prev_moon_sun_elongation_at_sunset_degrees, prev_moon_illumination_at_sunset_percent) is always populated by PanchangService.
  • Hindola Festival prefers Dwitiya over Pratipada: a new prefer_higher_tithi_option flag on the Hindola Festival rule ensures that when both Pratipada and Dwitiya candidates are present, Dwitiya is selected. This is also exposed in calculation_basis.prefer_higher_tithi_option in the festival output.
  • New localization keys: Gujarati localization adds translations for chandra_darshana_sud1_crescent_visible_at_sunset, chandra_darshana_dwitiya_fallback_at_local_sunset, and related reason keys.
  • Exporter output changed: regenerated today, month, raw, festival-only, combined festival, vrat, and eclipse JSON snapshots differ from v10.2.0 outputs due to eclipse Sutak corrections and Chandra Darshana metadata expansion.

Upgrade Actions

  • Regenerate cached eclipse, today, month, raw, festival, and vrat output after upgrading.
  • Rebaseline tests or snapshots that assert on visibility_assessment structure, eclipse relaxed_start times, or Chandra Darshana winning_reason_key values.
  • Review any code that destructures visibility_assessment as a flat string-keyed map — it now contains a nested modern_visibility object.

v10.2.0 Upgrade & Release Notes

This release expands generated calendar-period output, adds day-detail Mahadiksha guidance, refreshes festival and vrat metadata, and regenerates the public JSON outputs.

Compatibility Notes

  • Generated identity totals changed: the latest generated output reports 324 festival identities and 122 vrat identities.
  • Calendar period windows are now emitted: today, month, and raw outputs include calendar_period_windows with sidereal ayana, sidereal ritu, Sayana ayana, Sayana ritu, samvat, samvatsara, and lunar-month windows.
  • Sayana fields are visible in day details: day-detail payloads expose localized Sayana_Ayana and Sayana_Ritu branches where included.
  • Mahadiksha guidance is available: today and raw day-detail output can include Mahadiksha_Guidance for initiation-related ritual screening guidance.
  • Vrat catalog expanded: generic monthly Vratni Purnima is documented and emitted alongside named Purnima vrat identities, bringing the current generated vrat identity total to 122.
  • Rule metadata is cleaner: family-based vrat and festival outputs keep applicable truth-table flags and user-facing rule labels aligned with localization in English, Hindi, and Gujarati.
  • Exporter output changed: regenerated today, month, raw, festival-only, combined festival, vrat, and eclipse JSON snapshots may differ from earlier cached files.

Upgrade Actions

  • Regenerate cached today, month, raw, festival, vrat, and eclipse output after upgrading.
  • Rebaseline tests or snapshots that compare generated JSON structure, identity totals, calendar-period windows, or day-detail ritual guidance fields.
  • Review UI code that assumes day-detail output only contains sidereal ayana/ritu fields; Sayana ayana/ritu and Mahadiksha guidance may now be available.

v10.1.0 Upgrade & Release Notes

This release refreshes festival and vrat rule coverage, improves eclipse ritual output, and regenerates the public Amanta/Purnimanta JSON outputs across English, Hindi, and Gujarati.

Compatibility Notes

  • Festival and vrat rule coverage changed: regenerated output may differ for touched Nirnay-style festival and vrat decisions.
  • Nag Panchami is calendar-specific: Amanta output follows the Shravan Vad Pancham / Gujarat convention, while Purnimanta output keeps the Shravan Shukla Panchami convention.
  • Rule decisions are refreshed: touched observances now reflect the updated festival and vrat decision rules, aliases, and localized display names.
  • Eclipse ritual output is clearer: local visibility, ritual magnitude, Chudamani Yoga, Grastodaya/Grastasta guidance, and post-eclipse ritual completion wording are tightened.
  • No structural API redesign: this is a rule, catalog, localization, and generated-output refresh.

Upgrade Actions

  • Regenerate cached festival, vrat, month, eclipse, today, and raw yearly output after upgrading.
  • Rebaseline snapshots that compare exact festival dates, vrat dates, aliases, localized names, or eclipse ritual fields.
  • Review applications that display Nag Panchami, Sankashti, Chandra Darshana, Deepotsav, or eclipse-sutak guidance from cached JSON.

v10.0.8 Upgrade & Release Notes

This release expands the canonical alias set for the 26 named Ekadashis and keeps the festival registry, documentation, and localization layer aligned with the current Ekadashi identity set.

Compatibility Notes

  • Ekadashi aliases are broader: the named Ekadashi family now carries a fuller canonical alias set in the registry and public identity docs.
  • Localization is aligned: touched Ekadashi aliases and related user-facing names are now consistently covered in English, Hindi, and Gujarati.
  • No structural payload redesign: this is a naming, alias, and localization cleanup release.
  • Historical note: this patch focused on naming, alias, and localization cleanup; use the current documentation snapshot above for the latest generated identity totals.

Upgrade Actions

  • Regenerate cached festival, vrat, month, or raw yearly output if your application displays Ekadashi aliases or localized festival names.
  • Rebaseline snapshots or tests that assert on Ekadashi alias lists, localized festival names, or user-facing festival identity strings.
  • Prefer the refreshed canonical Ekadashi alias set in UI display, search, and documentation surfaces.

v10.0.7 Upgrade & Release Notes

This release improves precision for Satsangi tradition observances and adds first-class support for calendar-specific paksha and month definitions in the festival registry.

Compatibility Notes

  • Phuldolotsava date and identity updated: Now resolved on Krishna Pratipada (Phalguna amanta / Chaitra purnimanta) with Uttara Phalguni sunrise vyapini requirement per Satsangi Jeevan.
  • New rule structure for some festivals: Affected entries now publish calendar_rule, astronomy_rule, resolution_policy, and ritual_layers.
  • Purnimanta month labels corrected: Several Krishna Paksha Jayantis and tithi observances had incorrect month_purnimanta values; these are now accurate.
  • Paksha selection is now calendar-aware: Rules can declare separate paksha_amanta / paksha_purnimanta.
  • No payload structure breaking change: Output format is unchanged; only rule evaluation and labels for touched observances are affected.
  • Historical note: this patch focused on Phuldolotsava and purnimanta rule corrections; use the current documentation snapshot above for the latest generated identity totals.

Upgrade Actions

  • Regenerate any cached yearly festival, vrat, month, or raw outputs.
  • Rebaseline tests/snapshots that assert on Phuldolotsava date, name, tithi, or nakshatra rules, or on purnimanta month names for avatar observances.
  • Review Dhuleti vs Phuldolotsava distinction if your application treats Holi-cluster observances specially.

v10.0.6 Upgrade & Release Notes

This release updates the festival module more broadly: some observances were added, some overlapping identities were merged or cleaned up, several decision rules were corrected, and the related user-facing labels were aligned across supported languages.

Compatibility Notes

  • Festival and vrat totals differed from earlier releases: this release refreshed the canonical observance registry; use the current documentation snapshot above for the latest generated identity totals.
  • The festival registry was corrected, not just renamed: this release includes festival additions, canonical-identity cleanup, alias merges, and rule corrections for touched observances.
  • Decision output may change for touched observances: corrected rule paths and observance wording can change resolved names, aliases, and decision notes in generated output.
  • User-facing wording is refreshed: new and corrected festival descriptions, tradition labels, and decision strings are aligned in English, Hindi, and Gujarati output.
  • No payload structure changed: this is a festival catalog, rule, and localization correction release, not a structural API redesign.

Upgrade Actions

  • Regenerate cached festival, vrat, month, and raw output if you store canonical observance names, total counts, aliases, descriptions, or decision labels.
  • Rebaseline tests or snapshots that compare exact festival totals, vrat totals, resolved observance names, aliases, or user-facing festival decision strings.
  • Expect generated observance output to reflect refreshed canonical identities and corrected touched festival decisions.

v10.0.4 Upgrade & Release Notes

Festival identity and rule handling is now cleaner across the Ganesh Chaturthi family, Kurma Jayanti, Vaishakha Purnima, and Skanda Sashti, with the related user-facing labels localized consistently.

Compatibility Notes

  • Festival identity totals change: The canonical festival list now reports 325 unique festival identities because Siddhivinayaka Chaturthi is no longer emitted as a separate identity.
  • Ganesh-family aliasing is cleaner: Ganesh Chaturthi and Siddhivinayaka Chaturthi are now represented through the Vinayaka Chaturthi alias set instead of separate competing registry entries.
  • Kurma and Vaishakha Purnima no longer blur together: Kurma-related handling now stays distinct from the broader Vaishakha Purnima observance convention.
  • Skanda Sashti follows the corrected observance path: Evening-based rule handling is now reflected in the public decision output.
  • No payload structure changed: This is a festival rule and identity correction release, not a structural API redesign.

Upgrade Actions

  • Regenerate cached festival, month, and raw output if you store canonical festival identity names, total festival counts, or detailed decision reasons.
  • Rebaseline tests or snapshots that compare exact festival identity totals, Ganesh Chaturthi family aliases, or festival decision notes.
  • Expect Vinayaka Chaturthi and Ganesh Chaturthi to stay aligned on the same resolved Bhadrapada observance date.
  • Expect Kurma Jayanti, Vaishakha Purnima, and Skanda Sashti outputs to reflect their corrected public rule wording.

v10.0.3 Upgrade & Release Notes

Rare Adhika, Kshaya, and Nija month transitions now keep the active month sequence aligned in both Amanta and Purnimanta output.

Compatibility Notes

  • Rare month labels can change: Kshaya month spans no longer display the omitted month itself as the active month name.
  • Adhika to Nija return is tightened: Intercalary month end and the return to the regular month now stay aligned across Amanta and Purnimanta boundaries.
  • No public payload shape changed: This is a correctness release for month naming and status flags, not a structural API change.
  • Rare-year snapshots may differ: Generated month, festival, vrat, and raw output can change for uncommon Adhika/Kshaya years such as 2026 and 2123–2124.

Upgrade Actions

  • Regenerate cached month, daily, festival, vrat, and raw output if you store lunar month names or month-status flags.
  • Rebaseline tests or snapshots that compare exact Amanta or Purnimanta month labels near Adhika or Kshaya transitions.
  • Expect corrected output especially around Adhika Jyeshtha in 2026 and the Pausha Kshaya sequence in 2123–2124.

v10.0.2 Upgrade & Release Notes

Sandhya timing now follows the dynamic rātrimāna-ghaṭī convention used by published Panchang output.

Compatibility Notes

  • Sandhya timings can change: Pratah Sandhya now runs from three dynamic night-ghaṭīs before sunrise until sunrise. Sayahna Sandhya now runs from sunset until three dynamic night-ghaṭīs after sunset.
  • Godhuli is unchanged: Godhuli already used the dynamic night-ghaṭī convention and remains aligned with published Panchang timing.
  • Public method signature changed: calculateSandhya() now requires $nextSunrise so the actual local rātrimāna can be used.
  • Madhyahna Sandhya remains fixed-ghaṭī based: The noon Sandhya window continues to use fixed ghaṭī offsets around local solar noon.

Upgrade Actions

  • Update direct calls to calculateSandhya() to pass $nextSunrise between $sunset and $solarNoon.
  • Regenerate cached daily, today, month, and raw output if you store Sandhya timings.
  • Rebaseline tests or snapshots that compare exact Pratah or Sayahna Sandhya start/end times.

v10.0.1 Upgrade & Release Notes

Ekadashi parana timing now strictly follows the first-six-ghaṭī cap when Dvādaśī extends beyond Madhyāhna, while nakṣatra blocking is limited to restrictions active at parana opening.

Compatibility Notes

  • Parana end times can change: When Dvādaśī continues beyond Madhyāhna, the actual parana end now stops at the first six ghaṭīs of the morning unless an active opening restriction pushes it later within Dvādaśī.
  • Future nakṣatra blocks no longer split the window: Restricted nakṣatra-pada windows that begin later in Dvādaśī are no longer subtracted unless they are active when parana opens.
  • Fallback handling is corrected: If an active restricted nakṣatra consumes the early-morning cap, parana now reopens in the remaining Dvādaśī span instead of reporting a misleading early cutoff.
  • No public API shape changed: This is a behavior correction release; constants, month scopes, and exposed parana fields remain the same.

Upgrade Actions

  • Regenerate cached Ekadashi observance, vrat, festival, and raw yearly output if you store parana timings.
  • Rebaseline tests or snapshots that compare exact parana start/end windows.
  • Expect corrected parana results especially on Dvādaśī days that extend past Madhyāhna or begin under Anuradha 1, Shravana 2-3, or Revati 4 restrictions.

v10.0.0 Upgrade & Breaking Changes

The relaxed food window during visible eclipses now starts one full local prahara before the eclipse contact, instead of the beginning of the previous time segment.

Compatibility Notes

  • Relaxed Sutak timing has changed: The start time for the relaxed food restriction (for children, elderly people, and the unwell) is now different for visible eclipses.
  • Regular Sutak is unchanged: The main Sutak period for general use continues to follow the traditional four-prahara (solar) or three-prahara (lunar) rule.
  • Only visible eclipses are affected: Locations where the eclipse is not visible continue to show no Sutak as before.
  • Relaxed categories remain the same: This one-prahara relaxation is specifically for children, elderly people, and those who are sick. It is not automatically applied based on pregnancy.

Practical Example

For the solar eclipse visible from Bhuj on 2 August 2027:

  • v9.8.0 showed the relaxed window starting around 9:39 AM (based on the previous segment).
  • v10.0.0 now correctly shows it starting around 12:21 PM — one full local daytime prahara before the eclipse begins.

The calculation uses the actual length of the prahara in which the eclipse contact occurs, rather than simply taking the start of the segment before it.

Upgrade Actions

  • Regenerate any eclipse data or combined raw output files you maintain.
  • Review and update any tests or comparisons that rely on the previous relaxed Sutak start times.
  • Keep pregnancy-related precautions separate — the relaxed window is intended only for children, elderly people, and the unwell.
  • Use the regular Sutak timing for general use, and the relaxed timing only for the specific vulnerable groups mentioned.

v9.8.0 Upgrade & Release Notes

Dynamic day/night period correction across festival, vrat, and daily timing logic with dedicated Raksha Bandhan Nirnay handling.

Compatibility Notes

  • Festival and vrat dates can change: Karmakāla windows now use actual local dinamāna and rātrimāna where proportional day/night periods are required.
  • Raksha Bandhan selection is stricter: Shravana Purnima / Raksha Bandhan now uses a dedicated truth-table path with a dynamic three-day-muhūrta Udaya Purnima threshold and previous-day fallback handling.
  • Generated output should be regenerated: Festival, vrat, daily, month, raw yearly, and localized generated JSON should be refreshed after upgrading.
  • Ghaṭī remains fixed: Iṣṭakāla and ghaṭī-based offsets continue to use fixed elapsed ghaṭī units. Only proportional day/night windows are scaled by actual dinamāna or rātrimāna.

Highlights

  • Dynamic Day/Night Periods: Daytime muhūrtas, nighttime muhūrtas, fivefold day periods, Abhijit, Vijaya, and Niśītha now follow actual local sunrise, sunset, and next sunrise boundaries.
  • Fixed-Offset Ritual Windows Preserved: Aruṇodaya, Sandhyā, Pradoṣa, and fixed ghaṭī durations remain sunrise/sunset anchored fixed elapsed-time intervals where tradition requires that treatment.
  • Raksha Bandhan Nirnay: The package now distinguishes Udaya Purnima selection from previous-day fallback and exposes the basis used for the decision.
  • Ekadashi Parana Refinement: Preferred parana guidance now uses dynamic day midpoint for Madhyāhna while keeping first-six-ghaṭī preference as a fixed elapsed-time rule.
  • Generated Count Alignment: Generated observance output is refreshed for the corrected 326 festival and 90 vrat identity set.

Upgrade Notes

  • Rebaseline generated festival and vrat snapshots because corrected dynamic period rules can shift or remove observances that were previously selected by overly broad static windows.
  • Review Raksha Bandhan displays and aliases: Shravana Purnima now carries the Raksha Bandhan/Rakshabandhan/Rakshabandh aliases and uses Aparāhna-based Nirnay selection.
  • Do not treat normalized day/night divisions as classical ghaṭīs. Classical ghaṭī remains 24 minutes; proportional divisions are derived from local dinamāna or rātrimāna.

v9.7.0 Upgrade & Release Notes

Classical muhūrta base quality alignment with Vṛddha Vasiṣṭha/Nārada tradition and correct weekday Durmuhūrta schedule.

Compatibility Notes

  • Muhūrta table rows now include quality information: calculateMuhurtaTable() and Muhurta_Full_Day output now carry quality ("Inauspicious" / "Auspicious") and is_auspicious based on the fixed classical tyājya list.
  • Additional index field: Every muhūrta row now also includes the absolute 0-based index (0–29) alongside the traditional 1-based muhurta_number (within day or night).
  • Durmuhūrta behavior updated: The weekday Durmuhūrta list now follows the authoritative Nārada schedule. Previous internal logic has been replaced.
  • Base quality is now queryable: The Muhurta enum exposes getBaseQuality(), isBaseAuspicious(), and the full getMuhurtaBaseQualityMap().

Highlights

  • Corrected Base Muhūrta Qualities: Day tyājya (Inauspicious) are now Rudra, Ahi, Pitṛ, Indrāgni, Nirṛti, and Bhaga. Night krūra are Īśa, Ajapāda, Yama, and Vahni. Indrāgni and Īśa are properly marked Inauspicious; Arka and Vāyu are Auspicious.
  • Clear Separation of Layers: Fixed base quality (from Muhūrtādhyāya) is now independent of weekday Durmuhūrta (Nārada verse). The engine applies both layers correctly.
  • Accurate Weekday Durmuhūrta Schedule: Sunday Aryamā (14th), Monday Nirṛti + Brahmā, Tuesday Pitṛ + Agni, Wednesday Vidhātṛ/Abhijit (8th), and so on — using traditional numbering as explained in the sources.
  • Nārada Verse Support: The Durmuhūrta implementation now directly follows the well-known śloka beginning “अर्यमा राक्षसब्राह्मौ...” with correct 1-based positions documented.
  • Documentation Improvements: MASTER.md and the new MUHURTA_TEXT_SOURCES.md now contain clear, user-friendly explanations of the thirty muhūrtas, their qualities, and the distinction between base and weekday rules.

Upgrade Notes

  • If you consume the full muhūrta table, expect two new fields (quality and index) on each row. Existing fields remain unchanged.
  • Weekday Durmuhūrta results may differ on certain days compared to previous versions because the schedule now matches classical sources.
  • New methods on the Muhurta enum make it easy to inspect base quality or retrieve the Durmuhūrta indexes for a given vara without parsing tables.
  • No changes to other panchāṅga limbs (tithi, nakṣatra, yoga, etc.) or festival/vrat logic.

v9.6.0 Upgrade & Release Notes

Precision improvements to Sun and Moon astronomical calculations with aberration fix and regenerated data.

Compatibility Notes

  • More accurate Sun and Moon positions: A fix was applied to prevent double-counting of annual aberration in JPL ephemeris mode. This corrects Sun longitude by approximately 20.5 arcseconds.
  • Generated data has been refreshed: All Amanta and Purnimanta JSON artifacts (English, Hindi, Gujarati) have been regenerated using the corrected calculations for 2026 and beyond.
  • Affects precise astronomy: Improvements apply to tithi, nakshatra, yoga, festival timing windows, moon visibility, birth month calculations, and any features relying on accurate solar/lunar longitudes.

Highlights

  • JME Aberration Correction: Added the NO_ABERRATION flag consistently in four key files (AstronomyService, TransitEngine, and two helper traits) to produce correct single-aberration apparent positions for the Sun and Moon.
  • Four files updated: AstronomyService, TransitEngine, PanchangAstronomyHelpersTrait, and PanchangBirthMonthHelpersTrait now all use the corrected calculation flags.
  • Verified accuracy: Positions now align with published 2026 equinox and solstice instants.
  • Data regeneration: All output files (today, month, festivals, vrats, eclipses, raw) have been updated with the improved precision.

Upgrade Notes

  • Regenerate any stored or cached JSON data for 2026+ to benefit from the corrected Sun/Moon positions.
  • This is a pure accuracy improvement. No changes to API structure or field names.
  • Users working in strict JPL mode with high-precision requirements (eclipses, exact festival timings, etc.) will see the most noticeable benefits.
  • The fix has been applied uniformly so all calculation paths (daily panchang, festival resolution, birth month helpers, transit angles) are consistent.

v9.4.0 Upgrade & Release Notes

Feature release focused on richer Ekadashi observance output, clearer parana classification, and localized user-facing parana terminology.

Compatibility Notes

  • Ekadashi observance payload expanded: Parana output now includes additional classification and preference fields such as hari_vasara_classification_key, daytime_preference_rule, preferred_parana_windows, and the corresponding preferred start/end timestamps.
  • Generated JSON changed: Today, yearly festival, yearly vrat, raw yearly, and month/day artifacts have been regenerated to include the richer Ekadashi-parana structure and localized display labels.
  • Client display text can change: New parana labels now surface in English, Hindi, and Gujarati for Tithyavasara, Harivasara, Pratah Kala first six ghatis, and standard Dwadashi parana.

Added and Improved

  • Parana basis classification: Ekadashi output now distinguishes ordinary Tithyavasara parana from nakshatra-restricted Harivasara resolution.
  • Preferred daytime window: When Dwadashi continues past Madhyahna, the public payload now exposes the traditional first-six-ghatika Pratah Kala preference as an explicit rule and preferred parana window set.
  • Richer preferred-window fields: Ekadashi parana now includes preferred start/end fields in addition to the full allowed window set, making client rendering simpler for common observance views.
  • Localized parana terminology: The newly added parana classifications and daytime-preference rule labels are now localized in English, Hindi, and Gujarati output.

Fixed

  • Public Ekadashi parity: The exposed Ekadashi observance payload now reflects the newer Nirnay decision tree already encoded in the engine instead of stopping at only the basic allowed-window view.
  • Preferred-window semantics: Clients can now distinguish the full valid parana span from the traditionally preferred early-day portion when the Dwadashi duration is long enough to require that distinction.

Upgrade Notes

  • Regenerate stored today, festival, vrat, month, and raw yearly JSON after upgrading.
  • If your application displays Ekadashi parana, prefer the new preferred_parana_windows branch when present and fall back to parana_windows only when no preferred window is published.
  • If your application shows user-facing parana labels, consume the localized classification and rule-label fields instead of deriving display text from raw keys.

v9.3.0 Upgrade & Release Notes

Feature release focused on stronger eclipse ritual gating, corrected Panchak weekday resolution, and verified festival-rule refinements in the Nirnay layer.

Compatibility Notes

  • Generated eclipse output can change: Local eclipse visibility, sutak applicability, and ritual-boundary classification are stricter in this release. Short or penumbral-only local cases can now be rejected even when earlier output treated them as visible.
  • Festival observance dates can shift for affected rules: Diwali-family observances, Ram Navami / Hari Jayanti selection, Vamana Jayanti, Samaveda Upakarma, and Phuldolotsava use updated rule inputs and truth tables.
  • Panchak weekday labels are now JD-based: Panchak weekday and subtype output no longer depends on parsing formatted English timestamps. This fixes locale-sensitive weekday drift in non-English output.

Added and Improved

  • Eclipse scriptural classification: Eclipse output now includes explicit scriptural instruction text for Grastodaya, Grastasta, ordinary visible eclipses, and not-applicable cases.
  • Nishita JD fields: Nishita Muhurta output now carries Julian-day start and end values in addition to formatted timestamps.
  • Additional localized period labels: Localization coverage now includes period labels such as Abhijit, Pratah Kal, Arunodaya, Sangava, Vijaya Kaal, and Nishitha.

Fixed

  • Lunar eclipse ritual visibility: Local ritual visibility now rejects penumbral-only lunar cases and requires a minimum visible duration before marking an eclipse as visible for ritual purposes.
  • Solar eclipse ritual visibility: Solar ritual visibility now also enforces a minimum visible duration before local visibility and sutak are considered applicable.
  • Sutak boundaries: Sutak now fails closed when local prahara boundaries cannot be resolved, and returned sutak duration reflects the actual computed interval instead of a fixed nominal hour count.
  • Panchak weekday locking: Panchak subtype determination now uses JD-based weekday resolution instead of parsing localized formatted timestamps.

Festival Rule Refinements

  • Diwali truth table: Added explicit Pradosha-based day-selection truth-table handling when Amavasya spans competing evenings.
  • Ram Navami: Added explicit handling for Vriddhi, Kshaya, and Ashtami-viddha rejection around Navami selection.
  • Swaminarayan Jayanti (Hari-Nom): Rule profile now follows sunrise-vyapini Navami with first-day preference for Vriddhi/Kshaya handling, while keeping the incarnation remembrance context distinct.
  • Vamana Jayanti: Primary observance window now uses Abhijit rather than Madhyahna while retaining Shravana Nakshatra preference.
  • Govardhan Puja: Morning observance basis is now modeled through Pratah Kal instead of raw sunrise.
  • Samaveda Upakarma: Rule emphasis now follows a primarily Hasta-Nakshatra-based profile with sunrise observance handling.
  • Phuldolotsava: Tithi and month mapping now follow the corrected Holi-cluster tithi placement in the staged rules.

Upgrade Notes

  • Regenerate eclipse, today, festival, and raw yearly artifacts after upgrading.
  • If your application compares exact ritual visibility or sutak fields, rebaseline expected output for short local eclipses and penumbral lunar cases.
  • If your application depends on Panchak weekday display fields in Hindi or Gujarati output, no client change is needed; the correction is internal and output-only.
  • If you cached festival observance dates for the affected festival families, regenerate those caches after upgrading.

v9.2.0 Upgrade & Release Notes

Feature release focused on expanding the public non-natal daily rule-engine surface, tightening Panchak and travel logic, and hardening localized user-facing generated output.

Breaking and Compatibility Notes

  • Removed natal-derived surface: Transit_Moorthy is no longer part of the documented/public daily output surface, and getPlanetaryStates() is no longer part of the documented API surface. This keeps the package aligned with the non-natal policy.
  • Generated daily and raw JSON changed: Daily, today, and raw yearly artifacts now include additional non-natal rule-analysis branches and localized user-facing display fields. Rebaseline stored snapshots if your tests compare full payloads.
  • Panchak subtype semantics are stricter: Panchak subtype is now locked to the weekday at the true cycle-entry moment, not the current running weekday inside the active Panchak span.

Added

  • New public daily rule outputs: Added Nitya_Yoga_Observations, Vara_Tithi_Doshas, Tithi_Observance_Analysis, Vrata_Parana, Yatra_Screening, Day_Night_Measures, and Nakshatra_Tyajya to full day details and selectable daily APIs.
  • Panchak subtype classification: Public Panchak output now includes entry-weekday subtype classification for Roga Panchaka, Raja Panchaka, Agni Panchaka, Chora Panchaka, Mrityu Panchaka, and Shubha Panchaka / no named five-dosha subtype, with related keys tied to the cycle-entry weekday.
  • Day and night traditional duration metrics: Added explicit Dinamana and Ratrimana style payloads with seconds, minutes, hours, ghati, and pala.
  • Supported non-Ekadashi parana families: Added structured parana-family output for supported non-Ekadashi observances including Sankashti Chaturthi, Pradosha Vrat, Masik Shivaratri, and Skanda Shashthi.

Improved

  • Panchak window metadata: Panchak windows now expose localized start_weekday, localized current_running_weekday, subtype key, and the explicit entry_weekday lock semantics. The current-day payload also exposes current_weekday_type and current_weekday_type_key when the calculation time is inside an active Panchak window.
  • Yatra screening: Directional travel screening now exposes a full direction grid, blocked-direction determination, and urgent-travel exception guidance in the public output.
  • Tithi observance analysis: Structural sunrise-based tithi observance analysis is now exposed explicitly as a non-festival-specific engine with Shuddha, Viddha, Kshaya, and Vriddhi-style state reporting.
  • Nitya Yoga flags: Public output now exposes explicit Vyatipata / Vaidhriti style Kranti-dosha flagging and general Nitya-yoga avoidance scope.

Localization and Output Cleanup

  • User-facing leak audit: English generated JSON is clean of Hindi/Gujarati display text, and Hindi/Gujarati generated JSON is clean of English display text for audited user-facing fields.
  • Localized new sections: Newly added or modified user-facing fields in the rule-engine outputs are localized across English, Hindi, and Gujarati, including Panchak weekday labels, dosha display labels, parana labels, and shared fallback phrases.
  • Translation-first English labels: Where practical, newly added English-facing labels now use translation rather than transliteration.

Upgrade Notes

  • Use canonical keys such as weekday_type_key, dosha_key, family_key, and related machine fields for program logic. Treat localized display fields as presentation text.
  • Tithi_Observance_Analysis is a structural sunrise-tithi engine, not a complete festival-specific decision engine. Festival-specific overrides still belong to the observance rule families.
  • Vrata_Parana is intentionally limited to the supported non-Ekadashi families in this release. Do not assume universal parana coverage for every vrata family.

v9.1.0 Upgrade & Release Notes

Backward-compatible feature release focused on selective Hindu calendar period windows and a Purnimanta intercalary month-window correction.

Breaking Changes

None. v9.1.0 adds a new selective API and fixes a Purnimanta calendar-period label issue without removing or redefining existing public APIs.

Added

  • Dedicated calendar-period selective API: Added getCalendarPeriodWindowsRange() for month-range period windows without generating full daily month rows.
  • Selectable calendar period fields: Consumers can request only the period branches they need: ayana, ritu, vikram_samvat, gujarati_samvat, saka_samvat, kali_samvat, samvatsara, samvatsara_north, amanta_month, and purnimanta_month.
  • Lean output contract: Period windows expose only name, start_iso, and end_iso. Amanta and Purnimanta month windows additionally expose index.

Fixed

  • Purnimanta intercalary month windows: Purnimanta month-window labels now preserve the intercalary suffix where applicable. For example, the 2026 repeated Jyeshtha period is returned as Jyeshtha (Intercalary) followed by normal Jyeshtha.

Upgrade Notes

  • Use getCalendarPeriodWindowsRange() when your API or UI needs only period windows such as Ayana, Ritu, Samvat, or lunar month ranges.
  • Use getMonthFields() or getMonthRangeFields() when you need daily calendar cells. Calendar-period windows are intentionally separate from daily month rows.
  • If you cached Purnimanta month-window output generated before v9.1.0, regenerate it for ranges containing adhik months.

v9.0.0 Upgrade & Release Notes

Major release focused on verified Hindu Panchang conventions, Nirnay-rule festival decisions, eclipse ritual thresholds, Ekadashi parana restrictions, localized generated output, and regenerated 2026-2032 JSON artifacts.

Breaking Changes (Generated Output and Rule Decisions)

  • Generated JSON changed across all supported locale/calendar artifacts: Regenerate and rebaseline any stored amanta/purnimanta output for English, Hindi, and Gujarati. Festival, vrat, eclipse, month, today, and raw yearly files have changed.
  • Festival and vrat observance dates can shift: Rules now use stricter karmakala overlap, sunrise, Bhadra, Nakshatra, and truth-table decisions for items such as Pausha Purnima Vrat, Janmashtami, Mahashivaratri, Vijayadashami, Govatsa Dwadashi, Holika Dahan, Naraka Chaturdashi Abhyanga Snan, Govardhan Puja, Mahavir Jayanti, Samaveda Upakarma, and Phuldolotsava.
  • Vrat and festival labels are more explicit: Some observances are now separated or clarified by purpose, such as labeled Purnima vrat days versus Purnima festival days, location-sensitive Deepotsav items, and sect-specific Swaminarayan/BAPS Phuldolotsava metadata.
  • Eclipse ritual fields are stricter: visible, sutak.applicable, and ritual windows now require local visibility plus the configured ritual magnitude minimum. Lunar eclipses use the 1/16 umbral threshold and solar eclipses use the 1/12 threshold.
  • Nested decision metadata now localizes display values: Raw rule codes are preserved under *_key fields where needed, while user-facing fields such as reason, winning_reason, aliases, labels, and descriptions are localized.
  • Hindi and Gujarati generated outputs no longer preserve English display aliases by default: Clients that matched display strings such as Kali Chaudas, Abhyanga Snan, Paush Purnima Vrat, or Phuldol should match canonical keys or English reference fields instead.

Verified Engine Conventions

  • Ayanamsa: Panchanga limb calculations continue to use Lahiri / Chitra Paksha via JME_SIDEREAL_LAHIRI; the package does not switch Panchanga limbs to dynamic True Citra.
  • Sunrise and sunset: Rise/set calculations use visible upper limb with standard atmospheric refraction, standard pressure, and standard temperature.
  • Panchanga Moon: Tithi, Nakshatra, Yoga, Karana, moon sign, and transition searches use geocentric sidereal Sun/Moon longitudes. Moonrise/moonset remains topocentric for the observer location.
  • Moonrise/moonset daily semantics: The civil-day moon visibility interval starts only from a moonrise inside that civil date. If no moonrise occurs inside the date, both moonrise and moonset are returned as null for that daily output.
  • Panchang day boundary: Daily Panchang decisions continue to use sunrise-to-next-sunrise boundaries, with runtime/current-at-input fields exposed separately where applicable.
  • Prahar and Brahma Muhurta: Prahars are variable day/night quarters, and Brahma Muhurta follows the dynamic night-muhurta convention.

Nirnay and Festival Rule Improvements

  • Vaishnava Ekadashi: Dashami-vedha handling uses the 55-ghatika threshold from the previous sunrise for Nirnay-style Vaishnava decisions.
  • Hari Vasara and Parana: Parana starts after the first quarter of Dwadashi and now exposes restricted and allowed windows. Gujarati/Nirnay month-paksha restrictions block Ashadha Shukla Anuradha pada 1, Bhadrapada Shukla Shravana padas 2-3, and Kartika Shukla Revati pada 4. The public payload now also distinguishes ordinary Tithyavasara parana from nakshatra-restricted Harivasara style resolution and exposes the first-six-ghaṭikā daytime preference when Dwadashi continues past Madhyahna.
  • Festival karmakala engine: Pradosha, Nishitha, Madhyahna, Aparahna, Sangava, Arunodaya, and Vijaya Kaal decisions use window overlap and coverage metadata instead of only single-point matching.
  • Holika Dahan: Bhadra Mukha/Madhya rejection, Bhadra Puchha preference, lunar-eclipse exception logic, and Purnima-in-Pradosha requirements are implemented in the decision engine.
  • Major truth tables: Janmashtami, Mahashivaratri, Vijayadashami, and Govatsa Dwadashi now use dedicated decision branches with tie-breakers and fallback handling encoded in the engine.
  • Deepotsav sequence: Vagh Baras, Dhanteras, Naraka Chaturdashi Abhyanga Snan, Kali Chaudas, Diwali/Kali Puja, Govardhan/Annakut, and Bhai Beej expose sequence metadata; location-sensitive observances are marked accordingly.
  • Specific corrected observances: Pausha Purnima Vrat uses the labeled sunrise-based vrat day, Mahavir Jayanti uses Chaitra Shukla Trayodashi at sunrise, Samavedi Shravani consolidates to the best annual Hasta/Aparahna observance, and Phuldolotsava is marked as a Swaminarayan/BAPS sect-specific tithi observance.

Eclipse and Ritual Visibility Updates

  • Ritual minimums: Lunar ritual minimum is umbral magnitude >= 0.0625; solar ritual minimum is local/eclipse disk magnitude >= 0.083333....
  • Sutak gating: Sutak is not applicable when the eclipse is not ritually visible at the configured location.
  • Dynamic sutak windows: Lunar sutak uses a 3-prahar lookback and solar sutak uses a 4-prahar lookback, anchored to local variable prahar divisions.
  • Ritual classification: Eclipse output includes local visibility classification, Grast Uday/Grast Ast status, telescope-only status, and post-eclipse bath/fresh-food guidance where applicable.

Localization and Documentation

  • Hindi/Gujarati output cleanup: User-facing generated JSON was scanned for cross-language leakage. English output is clean of Hindi/Gujarati display text, Hindi output is clean of English/Gujarati display text, and Gujarati output is clean of English/Hindi display text for audited user-facing fields.
  • Localized aliases and decision reasons: Added missing display translations for Deepotsav aliases, Purnima vrat aliases, Phuldol labels, deity composites, festival descriptions, karmakala names, and rule-decision reasons.
  • Traditional source docs: The traditional-source documentation now includes the current engine convention matrix, verified Nirnay decisions promoted to code, and the expanded traditional/source-family reference list.

Upgrade Notes

  • Do not compare v9 generated yearly JSON against v8 by expecting identical dates or identical localized strings. Rebaseline festival, vrat, eclipse, and daily output snapshots after upgrading.
  • Use canonical IDs, keys, or *_key fields for application logic. Treat localized display fields as presentation text that can change when translations are corrected.
  • Review any client logic that assumes visible, sutak.applicable, or meets_ritual_minimum can be interpreted independently. In v9 ritual eclipse handling is intentionally gated by local visibility and magnitude threshold.
  • Review any UI copy or tests that assume civil-day moonset appears without a same-day moonrise. The daily output intentionally returns a visibility interval beginning with a moonrise inside the date.

v8.4.0 Upgrade & Release Notes

Minor release focused on exact month-range selective generation across month calendars, festivals, vrats, and eclipses.

Breaking Changes

None. v8.4.0 adds new selective range APIs and does not remove or redefine the existing yearly or single-month API surface.

Added and Improved

  • Exact month-range selective month generation: Consumers can now request only the months they need instead of looping externally and assembling the range themselves.
  • Exact month-range selective festival and vrat generation: Festival and vrat range requests now calculate only the requested bounded window rather than generating full surrounding years and filtering afterward.
  • Exact month-range selective eclipse generation: Eclipse range requests now support direct date-range generation instead of relying only on year-bucket generation.
  • Range-aware observance consolidation: Multi-year range output now preserves yearly observances correctly without collapsing independent observances from different years together.

Upgrade Notes

  • Use the new range-selective APIs when your application needs a bounded span such as October 2026 through August 2028.
  • The new range APIs are designed to avoid full-year overcompute. They calculate the requested span, with only minimal boundary support needed for correct observance resolution.
  • Existing yearly and single-month APIs remain available for current integrations.

v8.3.0 Upgrade & Release Notes

Minor release focused on true selective yearly observance generation and smaller dedicated vrat JSON artifacts.

Breaking Changes (Generated Yearly JSON)

  • Generated yearly festival JSON files now emit the compact by_date branch only instead of carrying both by_date and flat.
  • The dedicated yearly vrat file now separates repeated weekday vrats into a shared recurring_weekday_vrats block instead of repeating them under every matching date.

Added and Improved

  • Dedicated yearly selective outputs: Added true festival-only and vrat-only yearly generation paths instead of building the combined yearly observance payload first and slicing it afterward.
  • Compact generated artifacts: Yearly generated observance files now stay focused on date-indexed consumption for app and API use.
  • Smaller vrat payloads: Repeated weekday vrats such as Monday, Friday, and Saturday fasts are stored once under a recurring block and no longer inflate the dated vrat list.
  • Consistent raw output: The yearly festival branch embedded in raw output now follows the same compact by-date contract as the standalone generated festival file.

Upgrade Notes

  • If your app was reading the generated yearly flat branch from festival or vrat JSON files, switch to the selective runtime APIs for flat output or update the client to consume the dated contract.
  • If your app displays weekday-recurring vrats from the dedicated vrat file, read them from recurring_weekday_vrats instead of expecting them to be repeated inside by_date.
  • Regenerate stored yearly observance files after upgrading so the compact structure is applied consistently.

v8.2.1 Upgrade & Release Notes

Patch release focused on localized label corrections, generated output cleanup, and documentation alignment.

Breaking Changes

None. v8.2.1 does not introduce new API structures or schema changes. It is a corrective release for user-facing localization quality and output consistency.

Localization and Output Corrections

  • User-facing labels: Corrected localized display labels in generated output so month and daily calendar data read naturally in supported languages.
  • Composed labels: Corrected generated Nakshatra Pada labels in localized month output so runtime-composed names match the selected locale cleanly.
  • Output consistency: Refreshed generated JSON so corrected localized labels appear consistently across daily, month, festival, eclipse, and raw output files.
  • Documentation sync: Updated release notes and related documentation to match the current output behavior.

v8.2.0 Upgrade & Release Notes

High-precision update focused on eclipse obscuration accuracy and JME/JPL data structure alignment.

Breaking Changes (Data Format)

Eclipse Obscuration: The obscuration value in the magnitudes object of eclipse outputs has changed. It now correctly represents the area coverage (fraction of the Sun's disk covered by the Moon) calculated via a geometric intersection engine. Previously, this field incorrectly returned the center-to-center angular separation.

Eclipse Precision Improvements

  • New Geometric Engine: Implemented calculateSolarObscuration() using the standard geometric formula for the intersection of two circles to provide authentic area-based coverage metrics.
  • JME/JPL Data Mapping: Corrected the interpretation of the JME attr[] array. Sun and Moon diameters are now correctly converted from arcseconds to degrees before calculating the overlap.
  • Annular Eclipse Support: Added specific handling for annular phases where the Moon is entirely within the Sun's disk, ensuring area coverage reflects the ratio of the Moon's disk area to the Sun's disk area.
  • DE440 Validation: Verified contact times and magnitudes against NASA and PIB benchmarks for high-precision DE440/JPL mode configurations.
  • Numerical Stability: Added guards for trigonometric domain limits to prevent NaN results during extreme partial eclipse phases.

v8.1.0 Upgrade & Release Notes

Backward-compatible feature release focused on selective APIs and modular output generation.

Breaking Changes

None. v8.1.0 is a minor feature release. Existing v8.0.0 calls such as getDayDetails(), getMonthCalendar(), generateTodayPanchang(), generateFestivals(), and generateEclipses() continue to work.

Added Selective APIs

  • Daily selective details: Added getSelectedDetails() to calculate only requested day-detail sections instead of building the full getDayDetails() payload.
  • Daily convenience methods: Added getBasicDetails(), getPanchanga(), getSpecialYogas(), getMuhurtaFullDay(), getAbhijitMuhurta(), getVarjyam(), getDharmaSindhu(), and getSection().
  • Panchanga limb methods: Added getTithi(), getCurrentTithi(), getNakshatra(), getCurrentNakshatra(), getYoga(), getCurrentYoga(), getKarana(), getCurrentKarana(), and getVara().
  • Dot-path field picker: Added getFields() for returning only specific nested values such as Panchanga.Current_Tithi_At_Input_Now.name.
  • Month field groups: Added getMonthFields() with selectable groups for tithi, nakshatra, yoga, karana, vara, sun, moon, hindu_calendar, and festivals.
  • Today output branches: Added generateTodaySelected() for selecting todays_complete_details and/or muhurta_evaluation.
  • Festival output branches: Added generateFestivalsSelected(), generateFestivalByDate(), and generateFestivalFlat().
  • Eclipse output branches: Added generateEclipsesSelected(), generateEclipseByYear(), and generateEclipseFlat().
  • Month output branches: Added generateMonthSelected() and generateMonthCalendarFields().

Behavior and Parity

  • Selective daily sections are designed to avoid calculating unrelated heavy branches while still running shared base dependencies when required.
  • Selective values were tested against the original full outputs for exact equality, including JSON-equivalent structure and values.
  • Month selected output preserves the same canonical field order as getMonthCalendar() when all groups are requested.
  • Festival resolution is skipped in month field generation unless the festivals group is requested.

Documentation

  • Added selective API reference entries for all new service and output-generator methods.
  • Updated usage patterns to prefer selective APIs for small reads and added sample output comments.
  • Updated examples to match current localized English/Hindi/Gujarati display strings from Localization.php.

v8.0.0 Upgrade & Release Notes

Major release focused on clearer calendar output, richer month-view data, better English-facing labels, and first-class moon phase information for daily and monthly Panchang use.

Breaking Changes

  • English output now uses more natural translated labels where clear English equivalents exist, so some existing display values changed from transliterated forms to standard English forms.
  • Month calendar output is now richer and more explicit, which means apps that assumed the older simpler month-data shape should review their display logic.
  • Special Tithi situations in month view now have explicit structured output instead of needing to be inferred externally.

Added Features & Improvements

  • Moon Phase Output:
    • Added moon phase information to daily Panchang and month calendar output.
    • Moon phase output now includes visual phase name, visibility guidance, illumination range, illumination percentage, and lunar age.
    • Moon phase is now treated as its own first-class output instead of being left for client apps to infer.
  • Month Calendar Improvements:
    • Added compact Tithi display support for month cells.
    • Added explicit metadata for skipped or compressed Tithi cases.
    • Added richer timing information for intra-day Nakshatra, Yoga, Karana, and related transitions so calendar UIs can show day-level changes more accurately.
  • English Output Refresh:
    • Improved English-facing labels so user-facing output feels more natural in apps and websites.
    • Kept traditional Panchang terms where transliteration remains the clearer and more accurate choice.

Fixed Issues

  • Corrected compact month-calendar Tithi display for skipped-Tithi cases such as 30/1.
  • Corrected English label consistency across generated outputs.
  • Corrected related generated output paths so the refreshed labels and richer calendar fields appear consistently.

Upgrade Notes

  • Regenerate stored JSON after upgrading so month and daily output reflect the richer v8.0.0 structure.
  • If your app depends on exact English output text, review user-facing labels and display expectations.
  • If your app renders month cells, prefer the dedicated compact Tithi display and special-Tithi metadata instead of deriving those cases manually.
  • If your app shows lunar phase visually, use the dedicated moon-phase output instead of inferring it from Tithi.

v7.0.2 Upgrade & Release Notes

A backward-compatible patch release that fixes a Brahma Muhurta calculation issue during daily Panchang generation.

Breaking Changes

None. v7.0.2 is a patch release and can be used as a direct replacement for v7.0.1.

Fixes

  • Fixed a Brahma Muhurta calculation issue that could cause daily Panchang generation to fail before sunrise.
  • The previous sunset is now matched to the actual sunrise being used, preventing invalid night-duration calculations during JSON regeneration.

v7.0.1 Upgrade & Release Notes

A backward-compatible update modifying 2 core PHP files (Localization.php and FestivalService.php) to refine regional translation formatting and consolidate festival calculation rules.

Breaking Changes

None. v7.0.1 is fully backward-compatible and serves as a direct drop-in replacement for v7.0.0. No calculation rules or API signatures were changed.

Core Updates

  • Localization Formatting (Localization.php):
    • Standardised Hindi standard names, descriptions, deities, and sources to use native Devanagri numerals (१, २, ३...) while keeping dynamic format parameters intact.
    • Standardised Gujarati translation names and descriptions to use native Gujarati numerals (૧, ૨, ૩...).
    • Added missing Hindi (पोंगल) and Gujarati (પોંગલ) translations for Pongal.
    • Ensured clean, unique translation key registration across all supported locales.
  • Festival Calculations (FestivalService.php):
    • Consolidated Shakambhari Purnima under Pausha Purnima.
    • Refactored Pradosh Vrat to resolve dynamically based on the weekday (e.g., calculating names like Shani Pradosh Vrat, weekday-specific descriptions, and deities dynamically) instead of hardcoding multiple redundant entries.
    • Clarified public observance totals as 326 unique festival identities and 90 unique vrat identities.

v7.0.0 Upgrade & Release Notes

Major release focused on improving Panchang clarity, Muhurta accuracy, festival coverage, eclipse handling, and overall timing precision. Several areas now follow more precise Panchang conventions, and many outputs have clearer meanings and improved consistency.

Breaking Changes

  • Brahma Muhurta now follows the dynamic night-muhurta convention by default instead of only using a fixed 48-minute calculation.
  • Lagna daily output now covers the complete sunrise-to-next-sunrise Panchang day, including partial Lagna periods at the beginning or end of the day.
  • Amrita Kaal is now calculated independently using Nakshatra-based rules instead of being derived from Varjyam.
  • Chandra Vaasa now represents Moon-rashi directional Chandra Vaasa. Older Nakshatra-pada abode information is still available separately.
  • Solar-noon related fields were renamed to avoid confusion between astronomical solar noon and the daylight midpoint used for Abhijit Muhurta.
  • Sunrise-based Panchanga values and current-time Panchanga values are now separated more clearly.
  • Eclipse outputs now distinguish between global eclipse type and locally visible eclipse type.
  • Festival output handling is now alias-aware and avoids duplicate regional festival entries.

Added Features & Improvements

  • Panchanga & Muhurta Improvements:
    • Clear sunrise-versus-current Panchanga values for Tithi, Karana, and Yoga.
    • Dedicated current-time transition information so it is easier to identify what is active at the calculation time.
    • Dynamic Brahma Muhurta output while still preserving the traditional fixed 48-minute reference.
    • Independent Varjyam and Amrita Kaal windows with clearer and more accurate timing boundaries.
    • Improved Lagna day coverage with partial interval handling.
    • Clearer Panchaka Rahita output separating sunrise calculations from current-time calculations.
    • Richer Panchanga transition details for Tithi, Nakshatra, Nakshatra Pada, Yoga, and Karana.
  • Eclipse Improvements:
    • Added separate global and local eclipse classifications.
    • Improved location-aware eclipse visibility handling.
    • Improved eclipse visibility consistency across different locations.
  • Festival Expansion:
    • Expanded built-in observance coverage to 326 unique festival identities and 90 unique vrat identities with broader regional and traditional observance support.
    • Added support for many regional festival naming conventions and aliases.
    • Improved handling for regional observances such as Uttarayan, Pongal, Maghi, Til Sankranti, Khichdi, Ghughuti, Sakraat, Thiruvadhirai, Arudra Darshanam, and many more.
    • Improved handling for weekday-specific Pradosh observances.
    • Added smarter festival deduplication so aliases no longer appear as separate duplicate festivals.
    • Expanded festival translations and localization coverage.
    • Added additional Mahavidya worship descriptions for Magha Gupt Navaratri observances.

Fixed Issues

  • Panchanga & Muhurta:
    • Corrected Amrita Kaal timing behavior.
    • Corrected Varjyam and Amrita Kaal output windows.
    • Corrected Brahma Muhurta convention handling.
    • Corrected Friday Dur Muhurta mapping.
    • Corrected Friday Rahu Vaasa direction.
    • Corrected Chandra Vaasa meaning to match directional Panchang convention.
    • Corrected Panchaka Rahita current-time behavior.
    • Corrected generated month output defaults so current month handling behaves correctly when no month is provided.
  • Eclipse Handling:
    • Corrected local eclipse visibility behavior.
    • Improved local eclipse-type handling for location-specific outputs.
    • Improved eclipse ordering and visibility consistency.
  • Festival Handling:
    • Improved festival alias handling and canonical naming behavior.
    • Removed duplicate regional festival outputs caused by overlapping aliases.
    • Improved festival name preference logic so more specific naming conventions are preserved when mutual aliases exist.
    • Refined festival descriptions and deity associations.
    • Merged overlapping or deprecated festival representations into cleaner canonical festival entries.

Migration & API Signature Changes

Applications should treat this as a major output-structure update. Please review the following API signature changes and guidelines:

  • MuhurtaService::calculateBrahmaMuhurta() now requires $previousSunset and $sunrise. This supports the dynamic night-muhurta convention.
  • DailyPeriodsCalculator::calculateBrahmaMuhurta() has the same signature change and now returns fixed_48_minute_convention as a nested compatibility payload.
  • LagnaTableCalculator::calculateLagnaTable() and MuhurtaService::calculateLagnaTable() require $nextSunrise and return partial visible intervals for the Panchang day.
  • MuhurtaService::calculateNakshatraPeriodWindows() is the public scoped API for independent varjyam and amrita_kaal Nakshatra windows.
  • calculateAmritaKaal() remains only as a legacy compatibility helper and no longer derives Amrita Kaal from Varjyam end time.
  • Chandra_Vaasa now uses Moon-rashi direction as the primary meaning and preserves the older nakshatra-pada Vaasa under nakshatra_pada_vaasa.
  • Current_Nakshatra_At_Input_Now and Nakshatra_At_Sunrise now make runtime versus sunrise Nakshatra semantics explicit.
  • Moon_Phase_At_Sunrise, Current_Moon_Phase_At_Input_Now, and month-level moon_phase are new additive payloads that represent visual lunar phase, not Tithi.
  • Month calendar output now includes tithi_display, tithi_windows, nakshatra_windows, nakshatra_padas, yoga_windows, and karana_windows for richer calendar cells and timing-aware UIs.
  • On kshaya/skip days, tithi_display exposes compact multi-value labels such as 30/1 and structured kshaya_tithi metadata instead of forcing consumers to derive skipped Tithis manually.
  • Runtime Nakshatra-derived outputs, including Anandadi Yoga, Amritadi Yoga, and nakshatra-pada Chandra Vaasa, now select the window active at the calculation instant.
  • Shiva Vaasa, Agni Vaasa, and Yogini Vaasa now use the input-time Tithi while preserving sunrise values under at_sunrise.
  • Eclipse output separates global catalog type from local visible type through global_eclipse_type and local_eclipse_type.
  • Abhijit_Muhurta.solar_noon is now Abhijit_Muhurta.daylight_midpoint; Day_Types.solar_noon is now Day_Types.apparent_solar_noon.
  • If your app stores generated JSON or cached Panchang output, regenerate the data after upgrading so stored output matches the updated v7.0.0 structure.

Documentation

  • README is now shorter and focused on practical usage.
  • HTML documentation includes updated v7.0.0 release and upgrade notes.
  • API documentation has been refreshed for the updated output behavior.
  • Documentation now explains sunrise-versus-current Panchanga semantics more clearly.
  • Documentation now explains global-versus-local eclipse classification behavior.

Summary: This release provides clearer Panchanga timing behavior, more accurate Muhurta calculations, better eclipse visibility handling, broader regional festival support, cleaner festival naming and deduplication, richer transition and timing information, improved localization coverage, and more consistent and predictable outputs. The package now delivers a more complete and region-aware Panchanga experience while maintaining compatibility with traditional Panchang conventions.

v6.x Upgrade Notes

  • Current_Tithi_At_Input_Now and Current_Karana_At_Input_Now should be used when the app needs the value active at the requested calculation time.
  • Tithi and Karana remain sunrise-based compatibility fields. Prefer Tithi_At_Sunrise and Karana_At_Sunrise when sunrise semantics must be explicit.
  • Moon_Phase_At_Sunrise, Current_Moon_Phase_At_Input_Now, and month-level moon_phase use exact Sun-Moon elongation and illuminated fraction. They are visual moon-phase outputs, not festival-resolution fields.
  • tithi_display is the month-cell helper for UI rendering. Use it when a date can legitimately display a compact double-Tithi form such as 30/1.
  • Brahma_Muhurta now exposes the dynamic night-muhurta convention by default and preserves the fixed 48-minute convention under fixed_48_minute_convention.
  • Amrita_Kaal is calculated independently from nakshatra-specific Amrita ghati offsets. It is not derived from Varjyam end time.
  • Day_Types.apparent_solar_noon and Abhijit_Muhurta.daylight_midpoint intentionally name two different concepts.

v5.x Upgrade Notes

  • Day output includes expanded Vaasa, Shoola, moon visibility, and special yoga structures.
  • Consumers should avoid strict allowlists that reject new top-level output keys.
  • Mobile and static-site exports should use the generated JSON files as versioned payloads, because new fields are intentionally additive.

v4.0.0 Compatibility Notes

These notes remain important when upgrading from v3.x or older integrations.

1. Default Configuration Changes

Setting v3.x Default v4.0.0 Default
defaults.locale 'hi' (Hindi) 'en' (English)
defaults.calendar_type 'purnimanta' 'amanta'

2. Method Signature Changes

All enum getName() methods now accept an optional $locale parameter:

// v3.x
$name = Nakshatra::Ashwini->getName(); // "Ashwini"

// v4.0.0
$name = Nakshatra::Ashwini->getName();              // Uses configured locale
$name = Nakshatra::Ashwini->getName('hi');         // "अश्विनी"
$name = Nakshatra::Ashwini->getName('gu');         // "અશ્વિની"

3. Time Field Structure Changes

Sunrise, Sunset, Moonrise, and Moonset in the Panchanga output now return objects instead of strings:

// v3.x (string)
$details['Panchanga']['Sunrise']; // "06:14:00 AM"

// v4.0.0 (object)
$details['Panchanga']['Sunrise']; // ['jd' => 2461234.5, 'iso' => '2026-04-16T06:14:00+05:30', 'display' => '06:14:00 AM', 'timestamp' => 1234567890]
$details['Panchanga']['Sunrise']['display'];  // "06:14:00 AM"
$details['Panchanga']['Sunrise']['jd'];        // Julian Day
$details['Panchanga']['Sunrise']['iso'];        // ISO timestamp
$details['Panchanga']['Sunrise']['timestamp'];  // Unix timestamp

4. Enum Value Changes

Enum Change
Paksha Values changed from string ('Shukla', 'Krishna') to int (0, 1)
Karana Index values changed from 1-11 to 0-10. Fixed typo: KimstughnaKintughna
Muhurta Expanded from 15 to 30 cases (15 day + 15 night muhurtas)
Yoga Fixed typo: VishkambhaVishkumbh, AindraIndra

5. Removed Methods

The following methods have been removed:

  • Masa::getEnglishApproximation() - removed
  • Masa::getRulingNakshatra() - removed
  • Ritu::getEnglishName() - removed
  • Ritu::getMonths() - removed
  • Karana::getType() - removed
  • Karana::isVishti() - removed

6. PHP 8.3+ Requirement

This package targets PHP 8.3+ and the current Composer platform config is pinned accordingly.

7. Calendar Type Parameter

Methods like getDayDetails() support an optional calendarType parameter. If omitted, the default remains CalendarType::Amanta:

// v3.x
$details = $panchang->getDayDetails($date, $lat, $lon, $tz);

// Explicit enum
$details = $panchang->getDayDetails($date, $lat, $lon, $tz, 0.0, null, CalendarType::Amanta);

// Or use string
$details = $panchang->getDayDetails($date, $lat, $lon, $tz, 0.0, null, 'amanta');
$details = $panchang->getDayDetails($date, $lat, $lon, $tz, 0.0, null, 'purnimanta');

License

MIT License

This project is licensed under the MIT License.

The core engine uses the project-owned JME native ephemeris through PHP FFI. JPL kernel files are optional runtime data for strict JPL mode and are distributed separately from this package.

For more details, see the full license text.

Complete Public API Surface (Live from src)

This section is a direct reflection snapshot of all public methods and public constants currently declared in src/.

Use this as the definitive signature reference when integrating the package.

## JayeshMepani\PanchangCore\Astronomy\AstronomyService
- __construct(JmeEph\FFI\JmeEphFFI $jme): void
- configure(string $ephePath = ""): void
- getAscendant(array $birth): float
- getAyanamsa(float $jd): float
- getPlanets(array $birth): array
- setAyanamsa(float $jd): void
- toJulianDayUtc(array $birth): float

## JayeshMepani\PanchangCore\Astronomy\EclipseService
- __construct(JmeEph\FFI\JmeEphFFI $jme): void
- configure(string $ephePath = ""): void
- getEclipsesForYear(int $year, float $lat, float $lon, string $tz): array

## JayeshMepani\PanchangCore\Astronomy\SunService
- __construct(JmeEph\FFI\JmeEphFFI $jme): void
- configure(string $ephePath = ""): void
- getBirthDatetime(array $birth): Carbon\CarbonImmutable
- getIntervalAndStart(array $birth): array
- getMoonriseMoonset(array $birth): array
- getSolarTransits(array $birth): array
- getSunriseSunset(array $birth): array
- getTwilightTimes(array $birth): array
- isDayBirth(array $birth): bool
- jdToCarbonPublic(float $jd, string $timezone): Carbon\CarbonImmutable

## JayeshMepani\PanchangCore\Core\AstroCore
- countSigns(int $targetSign, int $startSign, bool $forward = true): int
- formatAngle(float $angle): string|float
- formatCoordinate(float $coordinate): string|float
- formatDateTime(Carbon\CarbonImmutable $time): string
- formatDuration(float $minutes): string|float
- formatTime(Carbon\CarbonImmutable $time): string
- getAngularDistance(float $a, float $b): float
- getConfig(string $key, mixed $default = null): mixed
- getHouseNumFromLagna(int $signIdx, int $ascSignIdx): int
- getSign(float $lon): int
- getSignLon(float $lon): float
- getTimeDiffMinutesPrecise(DateTimeInterface $target, DateTimeInterface $reference): float
- normalize(float $x): float
- toDms(float $deg): string

## JayeshMepani\PanchangCore\Core\Constants\ClassicalTimeConstants
const SECONDS_PER_DAY
const MINUTES_PER_DAY
const SECONDS_PER_HOUR
const MINUTES_PER_HOUR
const SECONDS_PER_MINUTE
const GHATIKA_IN_MINUTES
const GHATIKA_PER_DAY
const PALA_IN_SECONDS
const MUHURTA_IN_MINUTES
const MUHURTA_PER_DAY
const ARUNODAYA_MINUTES
const ARUNODAYA_PER_DAY
const PRADOSHA_GHATIKAS
const PRADOSHA_MINUTES
const PRADOSHA_PER_DAY
const BRAHMA_MUHURTA_MINUTES
const BRAHMA_MUHURTA_OFFSET_MINUTES
const PRATAH_SANDHYA_BEFORE_SUNRISE_GHATIKAS
const PRATAH_SANDHYA_AFTER_SUNRISE_GHATIKAS
const MADHYAHNA_SANDHYA_HALF_GHATIKAS
const SAYAM_SANDHYA_BEFORE_SUNSET_GHATIKAS
const SAYAM_SANDHYA_AFTER_SUNSET_GHATIKAS
const DEGREES_PER_SIGN
const DEGREES_PER_NAKSHATRA
const DEGREES_PER_TITHI
const TITHIS_PER_PAKSHA
const NAKSHATRAS_TOTAL
const SIGNS_TOTAL
const CIRCLE_DEGREES
const JD_EPSILON
const BINARY_SEARCH_ITERATIONS
const DEGREE_EPSILON
const JUPITER_CYCLE_YEARS
const KALI_ERA_OFFSET
const VIKRAMA_ERA_OFFSET
const SHAKA_ERA_OFFSET
const BHADRA_TITHIS
const EKADASHI_TITHI
const CHATURDASHI_TITHI
const PURNIMA_TITHI
const SCORE_TITHI_AT_KARMAKALA
const SCORE_TITHI_AT_SUNRISE
const SCORE_TITHI_DURING_DAY
const SCORE_TITHI_DURING_NIGHT
const SCORE_WEEKDAY_MATCH
const SCORE_NAKSHATRA_MATCH
const SCORE_VRIDDHI_FIRST_DAY
const SCORE_KSHAYA_PENALTY

## JayeshMepani\PanchangCore\Core\Enums\CalendarType
const Amanta
const Purnimanta
- cases(): array
- from(string|int $value): static
- getLocalizedName(string $locale = null): string
- isAmanta(): bool
- isPurnimanta(): bool
- tryFrom(string|int $value): static

## JayeshMepani\PanchangCore\Core\Enums\Choghadiya
const Udveg
const Chal
const Labh
const Amrit
const Kaal
const Shubh
const Rog
- cases(): array
- from(string|int $value): static
- fromTime(float $jdSunrise, float $jdSunset, float $jdCurrent, JayeshMepani\PanchangCore\Core\Enums\Vara $vara): self
- getDaySequence(JayeshMepani\PanchangCore\Core\Enums\Vara $vara): array
- getName(string $locale = null): string
- getNature(): string
- getNightSequence(JayeshMepani\PanchangCore\Core\Enums\Vara $vara): array
- isAuspicious(): bool
- tryFrom(string|int $value): static

## JayeshMepani\PanchangCore\Core\Enums\Hora
const Sun
const Venus
const Mercury
const Moon
const Saturn
const Jupiter
const Mars
- cases(): array
- from(string|int $value): static
- getName(string $locale = null): string
- getSequence(JayeshMepani\PanchangCore\Core\Enums\Vara $vara): array
- tryFrom(string|int $value): static

## JayeshMepani\PanchangCore\Core\Enums\Karana
const Bava
const Balava
const Kaulava
const Taitila
const Gara
const Vanija
const Vishti
const Shakuni
const Chatushpada
const Naga
const Kintughna
- cases(): array
- from(string|int $value): static
- fromTithi(int $tithiIndex, float $fraction): self
- getFromLongitudes(float $sunLon, float $moonLon): array
- getName(string $locale = null): string
- tryFrom(string|int $value): static

## JayeshMepani\PanchangCore\Core\Enums\Masa
const Chaitra
const Vaishakha
const Jyeshtha
const Ashadha
const Shravana
const Bhadrapada
const Ashvina
const Kartika
const Margashirsha
const Pausha
const Magha
const Phalguna
- cases(): array
- from(string|int $value): static
- fromAmantaIndex(int $index): self
- fromIndex(int $index): self
- fromSunLongitude(float $sunLon): self
- getName(string $locale = null): string
- tryFrom(string|int $value): static

## JayeshMepani\PanchangCore\Core\Enums\Muhurta
const Rudra
const Ahi
const Mitra
const Pitri
const Vasu
const Udaka
const Vishvedeva
const Vidhatr
const Brahma
const Indra
const Indragni
const Nirriti
const Toyapa
const Aryaman
const Bhaga
const Isha
const Ajapada
const Ahirbudhnya
const Pusha
const Ashvini
const Yama
const Vahni
const Dhatr
const Chandra
const Aditi
const Ijya
const Vishnu
const Arka
const Tvashtr
const Vayu
- cases(): array
- from(string|int $value): static
- getDaySequence(): array
- getName(string $locale = null): string
- getNightSequence(): array
- tryFrom(string|int $value): static

## JayeshMepani\PanchangCore\Core\Enums\Nakshatra
const Ashwini
const Bharani
const Krittika
const Rohini
const Mrigashira
const Ardra
const Punarvasu
const Pushya
const Ashlesha
const Magha
const PurvaPhalguni
const UttaraPhalguni
const Hasta
const Chitra
const Swati
const Vishakha
const Anuradha
const Jyeshtha
const Mula
const PurvaAshadha
const UttaraAshadha
const Shravana
const Dhanishta
const Shatabhisha
const PurvaBhadrapada
const UttaraBhadrapada
const Revati
- cases(): array
- from(string|int $value): static
- fromLongitude(float $longitude): self
- getDeity(): string
- getLongitudeRange(): array
- getName(string $locale = null): string
- getPada(float $longitude): int
- getRulingPlanet(): string
- getSymbol(): string
- tryFrom(string|int $value): static

## JayeshMepani\PanchangCore\Core\Enums\Paksha
const Shukla
const Krishna
- cases(): array
- containsTithi(int $tithiIndex): bool
- from(string|int $value): static
- getDescription(): string
- getName(string $locale = null): string
- getRawName(): string
- getTithiRange(): array
- isKrishna(): bool
- isShukla(): bool
- normalizeTithi(int $tithiIndex): int
- opposite(): self
- toAbsoluteTithi(int $normalizedTithi): int
- tryFrom(string|int $value): static

## JayeshMepani\PanchangCore\Core\Enums\Rasi
const Mesha
const Vrishabha
const Mithuna
const Karka
const Simha
const Kanya
const Tula
const Vrischika
const Dhanu
const Makara
const Kumbha
const Meena
- cases(): array
- from(string|int $value): static
- fromLongitude(float $longitude): self
- getElement(): string
- getEnglishName(): string
- getLongitudeRange(): array
- getName(string $locale = null): string
- getRulingPlanet(): string
- getSymbol(): string
- tryFrom(string|int $value): static

## JayeshMepani\PanchangCore\Core\Enums\Ritu
const Vasanta
const Grishma
const Varsha
const Sharad
const Hemanta
const Shishira
- cases(): array
- from(string|int $value): static
- fromMonth(int $monthIndex): self
- fromSunLongitude(float $sunLon): self
- getName(string $locale = null): string
- tryFrom(string|int $value): static

## JayeshMepani\PanchangCore\Core\Enums\Samvatsara
const Prabhava
const Vibhava
const Shukla
const Pramoda
const Prajapati
const Angirasa
const Srimukha
const Bhava
const Yuva
const Dhata
const Ishvara
const Bahudhanya
const Pramathi
const Vikrama
const Vrisha
const Chitrabhanu
const Svabhanu
const Tarana
const Parthiva
const Vyaya
const Sarvajit
const Sarvadhari
const Virodhi
const Vikriti
const Khara
const Nandana
const Vijaya
const Jaya
const Manmatha
const Durmukhi
const Hevilambi
const Vilambi
const Vikari
const Sharvari
const Plava
const Shubhakritu
const Shobhakritu
const Krodhi
const Vishvavasu
const Parabhava
const Plavanga
const Kilaka
const Saumya
const Sadharana
const Virodhikritu
const Paritapi
const Pramadi
const Ananda
const Rakshasa
const Nala
const Pingala
const Kalayukti
const Siddharthi
const Raudri
const Durmati
const Dundubhi
const Rudhirodgari
const Raktakshi
const Krodhana
const Akshaya
- cases(): array
- from(string|int $value): static
- fromGregorianYear(int $gregorianYear): self
- fromYear(int $year): self
- getName(string $locale = null): string
- tryFrom(string|int $value): static

## JayeshMepani\PanchangCore\Core\Enums\Tithi
const ShuklaPratipada
const ShuklaDwitiya
const ShuklaTritiya
const ShuklaChaturthi
const ShuklaPanchami
const ShuklaShashthi
const ShuklaSaptami
const ShuklaAshtami
const ShuklaNavami
const ShuklaDashami
const ShuklaEkadashi
const ShuklaDwadashi
const ShuklaTrayodashi
const ShuklaChaturdashi
const Purnima
const KrishnaPratipada
const KrishnaDwitiya
const KrishnaTritiya
const KrishnaChaturthi
const KrishnaPanchami
const KrishnaShashthi
const KrishnaSaptami
const KrishnaAshtami
const KrishnaNavami
const KrishnaDashami
const KrishnaEkadashi
const KrishnaDwadashi
const KrishnaTrayodashi
const KrishnaChaturdashi
const Amavasya
- cases(): array
- from(string|int $value): static
- fromLongitudes(float $sunLon, float $moonLon): self
- getFractionRemaining(float $sunLon, float $moonLon): float
- getName(string $locale = null): string
- getNormalizedIndex(): int
- getPaksha(): JayeshMepani\PanchangCore\Core\Enums\Paksha
- isChaturdashi(): bool
- isEkadashi(): bool
- isPurnimaOrAmavasya(): bool
- tryFrom(string|int $value): static

## JayeshMepani\PanchangCore\Core\Enums\Vara
const Sunday
const Monday
const Tuesday
const Wednesday
const Thursday
const Friday
const Saturday
- cases(): array
- from(string|int $value): static
- fromDayOfWeek(int $dayOfWeek): self
- fromJulianDay(float $jd): self
- getEnglishName(): string
- getName(string $locale = null): string
- getRulingPlanet(): string
- tryFrom(string|int $value): static

## JayeshMepani\PanchangCore\Core\Enums\VimshottariDasha
const Sun
const Moon
const Mars
const Rahu
const Jupiter
const Saturn
const Mercury
const Ketu
const Venus
- cases(): array
- from(string|int $value): static
- fromNakshatra(JayeshMepani\PanchangCore\Core\Enums\Nakshatra $nakshatra): self
- getDashaYears(): int
- getName(string $locale = null): string
- tryFrom(string|int $value): static

## JayeshMepani\PanchangCore\Core\Enums\Yoga
const Vishkumbha
const Priti
const Ayushman
const Saubhagya
const Shobhana
const Atiganda
const Sukarma
const Dhriti
const Shula
const Ganda
const Vriddhi
const Dhruva
const Vyaghata
const Harshana
const Vajra
const Siddhi
const Vyatipata
const Variyana
const Parigha
const Shiva
const Siddha
const Sadhya
const Shubha
const Shukla
const Brahma
const Indra
const Vaidhriti
- cases(): array
- from(string|int $value): static
- fromLongitudes(float $sunLon, float $moonLon): self
- getFractionRemaining(float $sunLon, float $moonLon): float
- getName(string $locale = null): string
- tryFrom(string|int $value): static

## JayeshMepani\PanchangCore\Core\Localization
- translate(string $type, string|int $key, string $locale = null): string

## JayeshMepani\PanchangCore\Facades\Panchang

## JayeshMepani\PanchangCore\Festivals\FestivalFamilyOrchestrator
const FESTIVAL_FAMILIES
const EXCEPTION_LOGIC
- resolveFestivalFamily(string $familyName, array $baseDate, array $panchangData, string $tradition = null, string $region = null): array

## JayeshMepani\PanchangCore\Festivals\FestivalRuleEngine
- annotateMonthAnomalies(array $dateToDetails): array
- resolveMajorFestival(string $festivalName, array $rule, Carbon\CarbonImmutable $date, array $today, array $tomorrow): array
- resolveNakshatraBasedFestival(string $festivalName, array $rule, Carbon\CarbonImmutable $date, array $today, array $tomorrow): array

## JayeshMepani\PanchangCore\Festivals\FestivalService
const TITHI_VRATAS
const FESTIVALS
const MONTHS
- __construct(JayeshMepani\PanchangCore\Festivals\FestivalRuleEngine $ruleEngine): void
- buildFestivalPayload(string $name, array $rules, array $resolved = null): array
- getDailyObservances(array $panchangDetails): array
- getFestivalsForYear(int $year, string $pakshaSystem = "Amanta"): array
- resolveFestivalsForDate(Carbon\CarbonImmutable $date, array $todayDetails, array $tomorrowDetails, array $yesterdayDetails = null, callable $fetchHistoricalSnapshot = null, bool $includeExtraWinners = false): array
- usesClassicalResolver(array $rules): bool

## JayeshMepani\PanchangCore\Festivals\Utils\BhadraEngine
- calculateBhadra(float $sunriseJd, float $vishtiStartJd, float $vishtiEndJd, int $moonRasiIndex, int $tithiIndex, string $paksha): array

## JayeshMepani\PanchangCore\PanchangServiceProvider
- boot(): void
- register(): void

## JayeshMepani\PanchangCore\Panchanga\ElectionalEvaluator
- calculateAbhijitCancellation(float $sunrise, float $sunset, int $varaNumber, float $currentTime): array
- calculateAmritaKaal(int $varaNumber, float $sunrise, float $sunset, float $nextSunrise, float $currentTime): array
- calculateBhadra(int $moonSignIdx): array
- calculateDagdhaTithi(int $tithiNumber, int $moonSignIdx): array
- calculateDagdhaYoga(int $varaNumber, int $tithiNumber): array
- calculatePanchakaDosha(int $tithiNumber, int $varaNumber, int $nakshatraNumber, int $lagnaNumber): array
- calculateRiktaTithi(int $tithiNumber, bool $isKrishnaPaksha): array
- calculateTransitMoorthy(string $nakshatraName): array
- calculateVarjyam(int $nakshatraNumber, float $nakshatraStartTime, float $nakshatraDurationMinutes): array
- generateRejectionReport(array $evaluationResults): array

## JayeshMepani\PanchangCore\Panchanga\ElectionalRuleBook
const UNIVERSAL_BAD_TITHIS
const UNIVERSAL_BAD_CHOGADIYA
const UNIVERSAL_GOOD_CHOGADIYA
const UNIVERSAL_GOOD_HORAS
const UNIVERSAL_BAD_YOGAS
const UNIVERSAL_GOOD_KARANAS
const UNIVERSAL_BAD_KARANAS
const COMBUSTION_ORBS
const COMBUSTION_ORBS_RETRO
const VARA_TITHI_YOGAS

## JayeshMepani\PanchangCore\Panchanga\KalaNirnayaEngine
const GHATI_IN_MINUTES
const PALA_IN_SECONDS
const GHATIKA_PER_DAY
const ARUNODAYA_GHATIKAS
const ARUNODAYA_MINUTES
const SANKRANTI_PUNYA_KAAL
const TITHI_NAMES
const FESTIVAL_RULES
- __construct(float $latitude, float $longitude): void
- calculatePunyaKaal(string $sankrantiName, float $sankrantiJd, float $sunriseJd, float $sunsetJd, float $nextSunriseJd): array
- configure(string $ephePath = ""): void
- determineEkadashi(float $ekadashiStartJd, float $ekadashiEndJd, float $dashamiEndJd, float $dvadashiStartJd, float $sunriseJd, float $nextSunriseJd, string $tradition = "Vaishnava"): array
- determineViddhaTithi(int $tithiNumber, float $tithiStartJd, float $tithiEndJd, float $sunriseDay1Jd, float $sunriseDay2Jd, float $prevTithiEndJd): array
- generateKalaNirnayaReport(int $tithiNumber, float $tithiStartJd, float $tithiEndJd, float $prevTithiEndJd, float $sunriseJd, float $sunsetJd, float $nextSunriseJd): array
- resolveFestivalDate(string $festivalName, float $tithiStartJd, float $tithiEndJd, float $sunriseJd, float $sunsetJd, float $nextSunriseJd): array

## JayeshMepani\PanchangCore\Panchanga\MuhurtaService
- __construct(JayeshMepani\PanchangCore\Muhurta\Planetary\HoraCalculator $horaCalculator, JayeshMepani\PanchangCore\Muhurta\Planetary\ChogadiyaCalculator $chogadiyaCalculator, JayeshMepani\PanchangCore\Muhurta\Classical\DailyPeriodsCalculator $dailyPeriodsCalculator, JayeshMepani\PanchangCore\Muhurta\Classical\InauspiciousPeriodsCalculator $inauspiciousPeriodsCalculator, JayeshMepani\PanchangCore\Muhurta\Regional\GowriPanchangamCalculator $gowriPanchangamCalculator, JayeshMepani\PanchangCore\Muhurta\Lagna\LagnaTableCalculator $lagnaTableCalculator): void
- calculateAbhijitMuhurta(Carbon\CarbonImmutable $sunrise, Carbon\CarbonImmutable $sunset): array
- calculateAmritaKaal(Carbon\CarbonImmutable $sunrise, array $varjyam): array
- calculateBadTimes(Carbon\CarbonImmutable $sunrise, Carbon\CarbonImmutable $sunset, int $varaIdx): array
- calculateBrahmaMuhurta(Carbon\CarbonImmutable $previousSunset, Carbon\CarbonImmutable $sunrise): array
- calculateChogadiya(Carbon\CarbonImmutable $sunrise, Carbon\CarbonImmutable $sunset, Carbon\CarbonImmutable $nextSunrise, Carbon\CarbonImmutable $current, int $varaIdx): array
- calculateChogadiyaTable(Carbon\CarbonImmutable $sunrise, Carbon\CarbonImmutable $sunset, Carbon\CarbonImmutable $nextSunrise, int $varaIdx): array
- calculateDaylightFivefoldDivision(Carbon\CarbonImmutable $sunrise, Carbon\CarbonImmutable $sunset): array
- calculateDurMuhurta(Carbon\CarbonImmutable $sunrise, Carbon\CarbonImmutable $sunset, Carbon\CarbonImmutable $nextSunrise, int $varaIdx): array
- calculateGodhuliMuhurta(Carbon\CarbonImmutable $sunset, Carbon\CarbonImmutable $nextSunrise): array
- calculateGowriPanchangam(Carbon\CarbonImmutable $sunrise, Carbon\CarbonImmutable $sunset, Carbon\CarbonImmutable $nextSunrise, int $varaIdx): array
- calculateHora(Carbon\CarbonImmutable $sunrise, Carbon\CarbonImmutable $sunset, Carbon\CarbonImmutable $nextSunrise, Carbon\CarbonImmutable $current, int $varaIdx): array
- calculateHoraTable(Carbon\CarbonImmutable $sunrise, Carbon\CarbonImmutable $sunset, Carbon\CarbonImmutable $nextSunrise, int $varaIdx): array
- calculateKalaVela(Carbon\CarbonImmutable $sunrise, Carbon\CarbonImmutable $sunset, Carbon\CarbonImmutable $nextSunrise, int $varaIdx): array
- calculateLagna(Carbon\CarbonImmutable $current, Carbon\CarbonImmutable $sunrise, float $sunriseSunLongitude, float $ayanamsaDeg, float $lat, float $lon, JmeEph\FFI\JmeEphFFI $jme): array
- calculateLagnaTable(Carbon\CarbonImmutable $sunrise, Carbon\CarbonImmutable $sunset, Carbon\CarbonImmutable $nextSunrise, float $sunriseSunLongitude, float $ayanamsaDeg, float $lat, float $lon, JmeEph\FFI\JmeEphFFI $jme): array
- calculateMuhurtaTable(Carbon\CarbonImmutable $sunrise, Carbon\CarbonImmutable $sunset, Carbon\CarbonImmutable $nextSunrise): array
- calculateNakshatraPeriodWindows(string $type, Carbon\CarbonImmutable $timezoneReference, int $nakshatraIndex, float $nakshatraStartJd, float $nakshatraEndJd, float $scopeStartJd, float $scopeEndJd): array
- calculateNishitaMuhurta(Carbon\CarbonImmutable $sunset, Carbon\CarbonImmutable $nextSunrise): array
- calculatePradoshaKaal(Carbon\CarbonImmutable $sunset, int $tithiNum): array
- calculatePrahara(Carbon\CarbonImmutable $sunrise, Carbon\CarbonImmutable $sunset, Carbon\CarbonImmutable $nextSunrise): array
- calculateSandhya(Carbon\CarbonImmutable $sunrise, Carbon\CarbonImmutable $sunset, Carbon\CarbonImmutable $nextSunrise, Carbon\CarbonImmutable $solarNoon): array
- calculateVarjyam(Carbon\CarbonImmutable $sunrise, Carbon\CarbonImmutable $sunset, Carbon\CarbonImmutable $nextSunrise, int $nakshatraIndex, float $nakshatraStartJd, float $nakshatraEndJd): array
- calculateVijayaMuhurta(Carbon\CarbonImmutable $sunrise, Carbon\CarbonImmutable $sunset): array

## JayeshMepani\PanchangCore\Panchanga\OutputGeneratorService
- __construct(JayeshMepani\PanchangCore\Panchanga\PanchangService $panchangService, JayeshMepani\PanchangCore\Astronomy\EclipseService $eclipseService): void
- generateAll(int $festivalYear, int $eclipseStartYear, int $eclipseEndYear, float $lat, float $lon, string $tz, float $elevation = 0, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta): array
- generateEclipseByYear(int $startYear, int $endYear, float $lat, float $lon, string $tz): array
- generateEclipseFlat(int $startYear, int $endYear, float $lat, float $lon, string $tz): array
- generateEclipses(int $startYear, int $endYear, float $lat, float $lon, string $tz): array
- generateEclipsesSelected(int $startYear, int $endYear, float $lat, float $lon, string $tz, array $sections): array
- generateFestivalByDate(int $year, float $lat, float $lon, string $tz, float $elevation = 0, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta): array
- generateFestivalFlat(int $year, float $lat, float $lon, string $tz, float $elevation = 0, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta): array
- generateFestivals(int $year, float $lat, float $lon, string $tz, float $elevation = 0, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta): array
- generateFestivalsSelected(int $year, float $lat, float $lon, string $tz, array $sections, float $elevation = 0, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta): array
- generateMonthCalendarFields(int $year, int $month, float $lat, float $lon, string $tz, array $calendarFields, float $elevation = 0, array $options = [], Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta): array
- generateMonthSelected(int $year, int $month, float $lat, float $lon, string $tz, array $sections, array $calendarFields, float $elevation = 0, array $options = [], Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta): array
- generateTodayPanchang(float $lat, float $lon, string $tz, float $elevation = 0, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta): array
- generateTodaySelected(float $lat, float $lon, string $tz, array $sections, array $detailSections = ["Basic_Details"], float $elevation = 0, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta): array

## JayeshMepani\PanchangCore\Panchanga\PanchangService
- __construct(JmeEph\FFI\JmeEphFFI $jme, JayeshMepani\PanchangCore\Astronomy\SunService $sunService, JayeshMepani\PanchangCore\Astronomy\AstronomyService $astronomy, JayeshMepani\PanchangCore\Panchanga\PanchangaEngine $panchanga, JayeshMepani\PanchangCore\Panchanga\MuhurtaService $muhurta, JayeshMepani\PanchangCore\Festivals\FestivalService $festivalService, JayeshMepani\PanchangCore\Festivals\Utils\BhadraEngine $bhadraEngine, mixed $unusedTransitEngine = null, mixed $unusedIntervalTracker = null, JayeshMepani\PanchangCore\Panchanga\Residences\VaasaCalculator|null $vaasaCalculator = null, JayeshMepani\PanchangCore\Panchanga\Residences\ShoolaCalculator|null $shoolaCalculator = null, JayeshMepani\PanchangCore\Panchanga\Yogas\SpecialYogaCalculator|null $specialYogaCalculator = null, JayeshMepani\PanchangCore\Panchanga\Doshas\PanchakCalculator|null $panchakCalculator = null, JayeshMepani\PanchangCore\Panchanga\Doshas\BhadraCalculator|null $bhadraCalculator = null, mixed $unusedVarjyamWindowCalculator = null, JayeshMepani\PanchangCore\Panchanga\Vrata\EkadashiParanaCalculator|null $ekadashiParanaCalculator = null, mixed ...$unusedExtractedCalculators): void
- configure(string $ephePath = ""): void
- getAbhijitMuhurta(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, float $elevation = 0, Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta, array $options = []): array
- getBasicDetails(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, float $elevation = 0, Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta, array $options = []): array
- getCurrentKarana(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, Carbon\CarbonImmutable $calculationAt = null, float $elevation = 0, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta, array $options = []): array
- getCurrentNakshatra(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, Carbon\CarbonImmutable $calculationAt = null, float $elevation = 0, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta, array $options = []): array
- getCurrentTithi(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, Carbon\CarbonImmutable $calculationAt = null, float $elevation = 0, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta, array $options = []): array
- getCurrentYoga(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, Carbon\CarbonImmutable $calculationAt = null, float $elevation = 0, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta, array $options = []): array
- getDailyMuhurtaEvaluation(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, Carbon\CarbonImmutable $currentAt = null, float $elevation = 0, array $options = []): array
- getDayDetails(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, float $elevation = 0, Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta, array $options = []): array
- getDharmaSindhu(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, float $elevation = 0, Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta, array $options = []): array
- getElectionalSnapshot(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, float $elevation = 0, array $options = []): array
- getFestivalSnapshot(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, float $elevation = 0, Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta): array
- getFestivalYearCalendar(int $year, float $lat, float $lon, string $tz, float $elevation = 0, Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta): array
- getFields(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, array $fields, float $elevation = 0, Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta, array $options = []): array
- getKarana(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, float $elevation = 0, Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta, array $options = []): array
- getMonthFields(int $year, int $month, float $lat, float $lon, string $tz, array $fields, float $elevation = 0, array $options = [], Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta): array
- getMonthCalendar(int $year, int $month, float $lat, float $lon, string $tz, float $elevation = 0, array $options = [], Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta): array
- getMuhurtaFullDay(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, float $elevation = 0, Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta, array $options = []): array
- getNakshatra(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, float $elevation = 0, Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta, array $options = []): array
- getPanchanga(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, float $elevation = 0, Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta, array $options = []): array
- getSection(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, string $section, float $elevation = 0, Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta, array $options = []): array
- getSelectedDetails(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, array $sections, float $elevation = 0, Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta, array $options = []): array
- getSpecialYogas(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, float $elevation = 0, Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta, array $options = []): array
- getTithi(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, float $elevation = 0, Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta, array $options = []): array
- getVara(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, float $elevation = 0, Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta, array $options = []): array
- getVarjyam(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, float $elevation = 0, Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta, array $options = []): array
- getYoga(Carbon\CarbonImmutable $date, float $lat, float $lon, string $tz, float $elevation = 0, Carbon\CarbonImmutable $calculationAt = null, JayeshMepani\PanchangCore\Core\Enums\CalendarType|string $calendarType = JayeshMepani\PanchangCore\Core\Enums\CalendarType::Amanta, array $options = []): array

## JayeshMepani\PanchangCore\Panchanga\PanchangaEngine
- calculateKundaLagna(float $ascLon): array
- calculatePanchakaRahita(int $tithiNum, int $varaNum, int $nakNum, int $lagnaNum): array
- calculateTithi(float $sunLon, float $moonLon): array
- calculateVara(array $birth, JayeshMepani\PanchangCore\Astronomy\SunService $sunService): array
- calculateYoga(float $sunLon, float $moonLon): array
- getAyana(float $sunLon): string
- getGujaratiSamvat(int $vikramSamvat, int $monthIndex): int
- getHinduMonth(float $sunLon, float $moonLon, string $paksha = "Shukla"): array
- getKaliSamvat(int $vikramSamvat): int
- getKarana(float $sunLon, float $moonLon): array
- getNakshatraInfo(float $longitude): array
- getPanchanga(float $sunLon, float $moonLon, array $birth, JayeshMepani\PanchangCore\Astronomy\SunService $sunService, JayeshMepani\PanchangCore\Astronomy\AstronomyService $astronomy): array
- getRitu(float $sunLon): string
- getSamvat(int $year, int $month): array
- getSamvatsara(int $vikramSamvat): string
- getSamvatsaraNorth(int $vikramSamvat): string
- isVishtiKarana(float $sunLon, float $moonLon): bool

## JayeshMepani\PanchangCore\Traits\CliBootstrap
- init(string $baseDir): void
- makeEclipseService(): JayeshMepani\PanchangCore\Astronomy\EclipseService
- makeOutputGenerator(JayeshMepani\PanchangCore\Panchanga\PanchangService $panchang): JayeshMepani\PanchangCore\Panchanga\OutputGeneratorService
- makePanchangService(): JayeshMepani\PanchangCore\Panchanga\PanchangService

Quick Reference

What to Use When

Method selection guide
I want to… Use this method
Get complete panchanga for a day PanchangService::getDayDetails()
Get only festivals PanchangService::getFestivalSnapshot()
Build a month calendar grid PanchangService::getMonthCalendar()
Get transit-only muhurta evaluation for now PanchangService::getDailyMuhurtaEvaluation()
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($previousSunset, $sunrise)
Get Varjyam or Amrita Kaal windows MuhurtaService::calculateNakshatraPeriodWindows() or PanchangService::getDayDetails()
Get sunrise/current Tithi and Karana separately getDayDetails()Tithi_At_Sunrise, Current_Tithi_At_Input_Now, Karana_At_Sunrise, Current_Karana_At_Input_Now
Get named daily Karmakala windows PanchangService::getDayDetails()Karmakala_Windows
Get Gowri Panchangam MuhurtaService::calculateGowriPanchangam()
Get Kala Vela MuhurtaService::calculateKalaVela()
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()
Use Hindi or Gujarati output Set defaults.locale or PANCHANG_LOCALE
Use Amanta or Purnimanta month names Pass $calendarType or set PANCHANG_CALENDAR_TYPE

Classical Text References

The package references a mix of traditional texts, source families, living traditions, published almanac conventions, and modern calculation systems. See docs/TRADITIONAL_TEXT_SOURCES.md for complete source-integrity map with confidence tiers, and docs/FESTIVAL_VRAT_IDENTITIES.md for the canonical 324 festival and 122 vrat identity lists, docs/MUHURTA_TEXT_SOURCES.md for Muhurta source classification, and docs/FESTIVAL_VRAT_DUPLICATE_AUDIT.md for duplicate-name cleanup decisions.

  • Sūrya Siddhānta 1.29→ Tithi (30 lunar days, 12° each)
  • Sūrya Siddhānta 8.1→ Nakṣatra (27 lunar mansions, 13°20' each)
  • Sūrya Siddhānta 3.1-3→ Yoga (27 combinations, 13°20' Sun-Moon sum)
  • Muhūrta Chintāmaṇi Chapter 2→ Karana (11 half lunar days, 6° each)
  • Muhūrta Chintāmaṇi→ Muhūrta, Aruṇodaya, Pradoṣa
  • Bṛhat Saṃhitā→ Samvatsara, Ritu, Muhurta rules
  • Nirṇaya Sindhu→ Festival timing, Bhadra rules
  • Published Panchang convention→ Dynamic night-muhurta Brahma Muhūrta timing
  • Aṣṭāṅga Hṛdaya→ Brahma Muhūrta practice context
  • Hari Bhakti Vilāsa→ Vaishnava Ekadashi rules
  • Satsangi Jeevan / Swaminarayan tradition→ Nirnay Ekadashi and parana restrictions
  • Brahmagupta / Khaṇḍakhādyaka tradition→ Eclipse ritual magnitude thresholds
  • Dharma Sindhu / Dharma_Sindhu→ Sankranti and Punya Kala output attribution
  • Śrīmad Bhāgavatam 3.11.10 / Āryabhaṭīya commentary tradition→ Yama and Prahar duration basis
  • Vālmīki Rāmāyaṇa / Śrīmad Bhāgavatam→ Rama Navami, Vamana Jayanti, Govardhan Puja, and Annakuta context
  • Shikshapatri / Vitthalnathji tradition→ Vaishnava vrata-nirnaya and Ekadashi profile context
  • Utsava-Nirnaya, Bhakti-Hamsa, Seva-Shlokah Shringar-Rasamandanam→ Pushtimarg festival, vrata, grahana, and seva-calendar source families
  • Yājñavalkya Smṛti / Saṃskāra-ratnamālā→ Samavedi Shravani and Upakarma Hasta-nakshatra rule family
  • Popular travel-muhurta, Drik/Nivas-Shool, Gowri/Pambu conventions→ Published Panchang table systems
  • Published public timing references→ Ekadashi parana, Harivasara, Mahadvadashi, and festival timing comparisons
  • BAPS, Swaminarayan.org, ISKCON, Indica Today, Samskaaram.com→ Living/public observance summaries used only as modern reference context
  • Smarta, Vaishnava, ISKCON/Gaudiya, regional traditions→ Festival variants and observance notes