সূর্য সিদ্ধান্ত পঞ্জিকা সকল প্রবন্ধ

পক্ষ, পূর্ণিমা ও অমাবস্যা: চান্দ্রচক্রের boundary কীভাবে নির্ণীত হয়?

সূর্য-চন্দ্রের geocentric longitude difference থেকে তিথি, শুক্লপক্ষ, কৃষ্ণপক্ষ, পূর্ণিমা ও অমাবস্যার exact boundary, sunrise assignment এবং C# calculation।

একটি civil date-কে “পূর্ণিমা” বলা, astronomical Full Moon instant বের করা এবং পূর্ণিমা তিথির শুরু–শেষ নির্ণয়—তিনটি related কিন্তু আলাদা কাজ। একইভাবে New Moon instant অমাবস্যা তিথির মাঝখানে নয়; এটি অমাবস্যার শেষ boundary। এই distinction না রাখলে daily page, festival rule, XML export ও historical report-এ এক দিনের ভুল খুব সহজে তৈরি হয়।

মূল রাশি: সূর্য–চন্দ্রের elongation

একটি সময়ে geocentric ecliptic longitude ধরা যাক:

E হলো চন্দ্র সূর্যের তুলনায় zodiac বরাবর কত degree এগিয়ে। এটি ০° থেকে ৩৬০° পর্যন্ত চলে, তারপর আবার ০°-এ wrap করে।

ElongationAstronomical relationPanchanga significance
০°Conjunction / astronomical New Moonঅমাবস্যা শেষ; শুক্ল প্রতিপদ শুরু
৯০°First Quarterশুক্ল অষ্টমীর ভিতরের একটি instant
১৮০°Opposition / astronomical Full Moonপূর্ণিমা শেষ; কৃষ্ণ প্রতিপদ শুরু
২৭০°Last Quarterকৃষ্ণ অষ্টমীর ভিতরের একটি instant
৩৬০° = ০°পরবর্তী conjunctionপরবর্তী lunar cycle শুরু

৩৬০° ভাগে ৩০ তিথি

একটি পূর্ণ phase cycle ৩৬০°। ত্রিশটি তিথির প্রতিটি ১২° elongation interval:

TithiIndex ১ থেকে ৩০। প্রথম ১৫টি শুক্লপক্ষ; পরের ১৫টি কৃষ্ণপক্ষ। একটি তিথি ১২° angular interval—২৪ ঘণ্টার civil day নয়। সূর্য ও চন্দ্রের relative speed পরিবর্তিত হওয়ায় তিথির সময়কালও পরিবর্তিত হয়।

Global indexElongation intervalপক্ষ ও তিথি
১[০°, ১২°)শুক্ল প্রতিপদ
২[১২°, ২৪°)শুক্ল দ্বিতীয়া
৮[৮৪°, ৯৬°)শুক্ল অষ্টমী
১৫[১৬৮°, ১৮০°)পূর্ণিমা
১৬[১৮০°, ১৯২°)কৃষ্ণ প্রতিপদ
২৩[২৬৪°, ২৭৬°)কৃষ্ণ অষ্টমী
৩০[৩৪৮°, ৩৬০°)অমাবস্যা

Half-open interval ব্যবহারে exact boundary একবারই count হয়। যেমন E = 180° হলে পূর্ণিমা শেষ—state হবে কৃষ্ণ প্রতিপদ।

শুক্লপক্ষ ও কৃষ্ণপক্ষের exact boundary

পক্ষ হলো পনেরো তিথির group:

শুক্লপক্ষে Moon–Sun elongation ০° থেকে ১৮০°-এর দিকে বাড়ে; সাধারণভাবে চাঁদের illuminated portion বাড়তে দেখা যায়। কৃষ্ণপক্ষে elongation ১৮০° থেকে ৩৬০°/০°-এর দিকে যায়; illuminated portion কমে। কিন্তু panchanga classification দৃশ্যমান আকার দেখে নয়—longitude calculation দেখে।

Astronomical Full Moon আর পূর্ণিমা তিথি এক নয়

পূর্ণিমা তিথি শুরু হয় elongation ১৬৮° অতিক্রম করলে এবং শেষ হয় ১৮০°-এ। Astronomical Full Moon হলো ১৮০°-এর exact instant। তাই:

কথ্য ভাষায় “আজ পূর্ণিমা” বলতে পূর্ণিমা তিথিযুক্ত দিন বোঝানো হয়। Astronomy table-এ “Full Moon 22:14 UTC” মানে exact opposition instant। দুইটি একই field-এ রাখবেন না।

Astronomical New Moon আর অমাবস্যা তিথি এক নয়

অমাবস্যা তিথি elongation ৩৪৮° থেকে ৩৬০° পর্যন্ত। Exact conjunction বা New Moon instant ৩৬০°/০°-এ, যেখানে অমাবস্যা শেষ এবং শুক্ল প্রতিপদ শুরু:

এ কারণে astronomical New Moon-এর civil date এবং sunrise-based “অমাবস্যা দিন” কখনও আলাদা date-এ পড়তে পারে। এটি error নয়; একদিকে exact instant, অন্যদিকে local calendrical day assignment।

First/Last Quarter কেন তিথির boundary নয়?

Western principal lunar phases ০°, ৯০°, ১৮০° ও ২৭০° elongation-এ সংজ্ঞায়িত। কিন্তু তিথির boundary প্রতি ১২°। ৯০° বা ২৭০° সংখ্যা ১২ দিয়ে নিঃশেষে বিভাজ্য নয়; তাই:

  • ৯০° পড়ে শুক্ল অষ্টমীর [৮৪°, ৯৬°) interval-এর মাঝামাঝি;
  • ২৭০° পড়ে কৃষ্ণ অষ্টমীর [২৬৪°, ২৭৬°) interval-এর মাঝামাঝি;
  • শুধু ০° ও ১৮০° একই সঙ্গে principal phase এবং pakṣa boundary।

সুতরাং quarter-phase API ব্যবহার করে সরাসরি অষ্টমীর শুরু/শেষ বের করা যাবে না। ৮৪° ও ৯৬° roots আলাদাভাবে solve করতে হবে।

দৃশ্যমান চাঁদ, conjunction এবং পঞ্জিকার তিথি

Astronomical New Moon-এর সময় সূর্য ও চন্দ্রের ecliptic longitude সমান। কিন্তু first crescent visibility পরে ঘটে এবং atmosphere, horizon, latitude, elongation, Moon altitude ও observer condition-এর উপর নির্ভর করে। Hindu tithi calculation সাধারণত crescent sighting-এর অপেক্ষা করে না; mathematical elongation ব্যবহার করে।

এই distinction Hijri calculation-এর ক্ষেত্রেও গুরুত্বপূর্ণ। Islamic observational month-start model-এ conjunction-এর পর crescent visibility বিবেচিত হতে পারে; Hindu তিথি boundary প্রতি ১২° mathematical phase interval। একই “চাঁদের মাস” শব্দ ব্যবহার হলেও algorithm এক নয়।

তিথিতে নিরয়ণ না সায়ন longitude?

তিথি হলো সূর্য ও চন্দ্রের longitude difference। একই ayanāṃśa দুই longitude থেকে বিয়োগ করলে difference-এ তা algebraically cancel করে:

তাই একই coordinate convention-এ নেওয়া tropical বা sidereal longitude থেকে elongation সাধারণত একই হয়। কিন্তু এক body-তে apparent, অন্যটিতে mean; একটিতে geocentric, অন্যটিতে topocentric; অথবা দুই epoch/model mix করলে cancel হবে না।

Project profile-এ অন্তত এই metadata রাখুন:

  • Solar/lunar engine ও version;
  • geocentric না topocentric;
  • true/apparent/mean longitude convention;
  • time scale—UT, TT এবং ΔT policy;
  • root-solver tolerance।

তিথির interval global, পঞ্জিকার দিন local

Chosen geocentric model-এ একটি তিথির start/end absolute instant পৃথিবীর সব স্থানের জন্য একই। কিন্তু সেই interval কোন local sunrise-কে স্পর্শ করছে তা শহরভেদে বদলে যায়। ফলে ঢাকা ও নিউ ইয়র্কে:

  • একই তিথির UTC start/end একই থাকবে;
  • local clock time ও civil date আলাদা হবে;
  • sunrise-এ বর্তমান তিথি আলাদা হতে পারে;
  • festival civil day-ও rule অনুযায়ী আলাদা হতে পারে।

তাই তিথিকে timezone দিয়ে পুনর্গণনা নয়; absolute event localize করুন, তারপর sunrise/ritual-moment rule প্রয়োগ করুন।

সূর্যোদয়-ভিত্তিক daily assignment

একটি traditional Panchanga day সাধারণত local sunrise থেকে পরের local sunrise পর্যন্ত। Daily heading-এ যে তিথি দেখানো হয়, তা অধিকাংশ ক্ষেত্রে প্রথম sunrise-এ বর্তমান তিথি। কিন্তু day-এর ভিতরে এক বা একাধিক transition ঘটতে পারে।

পরিস্থিতিDaily result
একই তিথি sunrise থেকে next sunrise পর্যন্ত“অহোরাত্র” বা full-day indication
তিথি day-এর ভিতরে শেষবর্তমান তিথি + end time + পরে পরবর্তী তিথি
দুই boundary sunrise interval-এর ভিতরেমধ্যবর্তী তিথি কোনো sunrise-এ না থাকলে তিথিক্ষয় display
এক তিথি দুই consecutive sunrise-এতিথিবৃদ্ধি; দুই civil day-এ একই sunrise tithi

Calendar grid-এ শুধু sunrise tithi দেখালেও daily details ও XML-এ sunrise-to-next-sunrise সব transition রাখা উচিত। এতে “পরে” line এবং festival interval ঠিক থাকে।

পূর্ণিমা–অমাবস্যার observance date কীভাবে বাছবেন?

পূর্ণিমা বা অমাবস্যা তিথি যে civil day-এ আছে, সব observance স্বয়ংক্রিয়ভাবে সেই দিনেই হবে—এমন নয়। Rule-এর reference moment ভিন্ন হতে পারে:

  • sunrise prevalence;
  • প্রদোষ/সন্ধ্যা prevalence;
  • midnight prevalence;
  • পূর্ণ তিথি interval-এর overlap;
  • দুই দিনে থাকলে pūrvaviddha/paraviddha preference;
  • স্থানীয় বা sampradāya-specific rule।

Engine architecture-এ প্রথমে pure interval calculate করুন। আলাদা ObservanceRule সেই intervalকে sunrise, sunset, midnight বা অন্য ritual window-এর সঙ্গে intersect করবে। Daily label-কে festival decision হিসেবে reuse করবেন না।

Calculation pipeline

  1. Requested date-এর আগে–পরে পর্যাপ্ত Julian Day window নিন;
  2. একই astronomical profile-এ সূর্য ও চন্দ্র longitude calculate করুন;
  3. E = Normalize360(Moon − Sun);
  4. Current global tithi index নির্ণয় করুন;
  5. Next multiple of ১২° target করুন;
  6. Coarse stepping দিয়ে target crossing bracket করুন;
  7. Bisection/Brent method দিয়ে exact boundary solve করুন;
  8. Sunrise-to-next-sunrise interval-এর সব boundary collect করুন;
  9. Absolute instants requested time zone-এ convert করুন;
  10. Daily label ও observance policy আলাদা ধাপে প্রয়োগ করুন।

Midnight-এ state sample করে ২৪ ঘণ্টা যোগ দিয়ে end time অনুমান করলে চলবে না। Relative angular speed constant নয়; interpolation কেবল safe bracket তৈরিতে সাহায্য করতে পারে, final result root solver থেকে আসবে।

৩৬০° wrap-এর মধ্যেও exact boundary solve

Raw normalized elongation 359.9° থেকে 0.1° হলে সংখ্যা কমেছে মনে হয়, যদিও phase এগিয়েছে 0.2°। তাই scan-এর সময় phase unwrap করুন। Anchor instant-এর elongation থেকে continuous progress:

static double Normalize360(double value)
{
    value %= 360.0;
    if (value < 0.0) value += 360.0;
    return value;
}

static double ForwardDifference(double later, double earlier)
{
    return Normalize360(later - earlier);
}

একটি ছোট bracket—যেমন কয়েক ঘণ্টা—এর মধ্যে Moon–Sun relative motion forward থাকে। Bracket-এর start phase basePhase ধরে target পর্যন্ত continuous distance compare করা যায়। খুব বড় interval এক ধাপে নেবেন না; coarse scan ৩–৬ ঘণ্টার step ব্যবহার করতে পারে।

C# 5-compatible তিথি state

public enum PakshaKind
{
    Shukla,
    Krishna
}

public sealed class TithiState
{
    public int GlobalIndex { get; set; }     // 1..30
    public int PakshaIndex { get; set; }     // 1..15
    public PakshaKind Paksha { get; set; }
    public double ElongationDegrees { get; set; }
    public double StartBoundaryDegrees { get; set; }
    public double EndBoundaryDegrees { get; set; }
}

static TithiState StateAt(double moonLongitude, double sunLongitude)
{
    double e = Normalize360(moonLongitude - sunLongitude);
    int global = (int)Math.Floor(e / 12.0) + 1;

    // Floating-point protection at the upper wrap.
    if (global > 30) global = 30;

    bool shukla = global <= 15;
    int pakshaIndex = shukla ? global : global - 15;

    return new TithiState
    {
        GlobalIndex = global,
        PakshaIndex = pakshaIndex,
        Paksha = shukla ? PakshaKind.Shukla : PakshaKind.Krishna,
        ElongationDegrees = e,
        StartBoundaryDegrees = (global - 1) * 12.0,
        EndBoundaryDegrees = global == 30 ? 360.0 : global * 12.0
    };
}

Exact boundary-তে floating-point value 179.999999999 বা 180.000000001 হতে পারে। State display-এর আগে arbitrary rounding না করে solver tolerance এবং a consistent boundary policy ব্যবহার করুন।

C# bisection boundary solver

নিচের code ধরে নিচ্ছে PhaseProgress(jd, anchorJd) anchor-এর পর continuous, unwrapped elongation progress ফেরত দেয় এবং targetProgress bracket-এর মধ্যে আছে:

public sealed class TithiBoundary
{
    public int EndingGlobalTithi { get; set; }
    public int StartingGlobalTithi { get; set; }
    public double JulianDayUt { get; set; }
    public DateTimeOffset InstantUtc { get; set; }
}

static double SolveByBisection(
    double leftJd,
    double rightJd,
    double targetProgress,
    Func<double, double> phaseProgress,
    double toleranceDays)
{
    double leftValue = phaseProgress(leftJd) - targetProgress;
    double rightValue = phaseProgress(rightJd) - targetProgress;

    if (leftValue > 0.0 || rightValue < 0.0)
        throw new ArgumentException("Boundary is not bracketed.");

    while (rightJd - leftJd > toleranceDays)
    {
        double middleJd = (leftJd + rightJd) / 2.0;
        double middleValue = phaseProgress(middleJd) - targetProgress;

        if (middleValue < 0.0)
            leftJd = middleJd;
        else
            rightJd = middleJd;
    }

    return (leftJd + rightJd) / 2.0;
}

এক সেকেন্ড tolerance চাইলে day unit-এ 1.0 / 86400.0 ব্যবহার করা যায়। Ephemeris input/output precision কম হলে solver tolerance ছোট করলেই accuracy বাড়বে না—source model-এর বাস্তব precision report করুন।

এক sunrise থেকে পরের sunrise: সব event সংগ্রহ

Daily report-এর জন্য algorithm:

public sealed class VedicDayTithiReport
{
    public DateTimeOffset Sunrise { get; set; }
    public DateTimeOffset NextSunrise { get; set; }
    public TithiState TithiAtSunrise { get; set; }
    public IList<TithiBoundary> Boundaries { get; set; }
}

// Pseudocode-shaped C# 5 flow:
// 1. sunriseUtc এবং nextSunriseUtc -> JD
// 2. StateAt(sunrise) calculate
// 3. current tithi-এর end target থেকে শুরু
// 4. যতক্ষণ solved boundary < nextSunrise:
//       report.Boundaries.Add(boundary)
//       target += 12 degrees
// 5. local time zone-এ render

Boundary list count:

  • ০ হলে sunrise tithi next sunrise পর্যন্ত—“অহোরাত্র”;
  • ১ হলে একটি end time;
  • ২ হলে day-এর ভিতরে একটি সম্পূর্ণ intermediate tithi এসেছে ও শেষ হয়েছে;
  • unexpected বেশি হলে input window, solver বা ephemeris যাচাই করুন।

API ও XML output

API-তে label-এর পাশাপাশি interval evidence দিন:

{
  "vedicDay": {
    "sunrise": "2026-10-08T05:54:10+06:00",
    "nextSunrise": "2026-10-09T05:54:32+06:00"
  },
  "tithiAtSunrise": {
    "globalIndex": 28,
    "paksha": "krishna",
    "pakshaIndex": 13,
    "nameBn": "ত্রয়োদশী",
    "elongationDegrees": 329.4172
  },
  "boundaries": [
    {
      "endingTithi": 28,
      "startingTithi": 29,
      "julianDayUt": 2461322.198765,
      "localTime": "2026-10-08T22:14:13+06:00"
    }
  ],
  "profile": "surya-siddhanta-v3"
}

XML:

<tithi-day sunrise="2026-10-08T05:54:10+06:00"
           next-sunrise="2026-10-09T05:54:32+06:00"
           profile="surya-siddhanta-v3">
  <at-sunrise global-index="28"
              paksha="krishna"
              paksha-index="13"
              elongation="329.4172">ত্রয়োদশী</at-sunrise>
  <boundary ending="28" starting="29"
            jd-ut="2461322.198765"
            local="2026-10-08T22:14:13+06:00" />
</tithi-day>

সংখ্যাগুলো output-format illustration; production ephemeris result নয়। API consumer যেন example-কে test vector হিসেবে ব্যবহার না করে।

সাধারণ calculation error

ভুলফলসংশোধন
Moon phase image দেখে তিথি ধরাBoundary time ভুলLongitude difference ব্যবহার
Full Moon instant-কে পূর্ণিমার শুরু ধরাতিথি প্রায় এক interval সরে যায়পূর্ণিমা [১৬৮°,১৮০°)
New Moon instant-কে অমাবস্যার শুরু ধরাঅমাবস্যা/প্রতিপদ উল্টে যায়অমাবস্যা [৩৪৮°,৩৬০°)
359°→0° raw subtractionPhase পিছিয়েছে মনে হয়Unwrap/Normalize360
Midnight-only sampleEnd time ও skipped tithi হারায়Root solve + sunrise interval scan
UTC date-কে local festival date ধরাLocation অনুযায়ী এক দিন ভুলAbsolute instant localize, তারপর rule
Daily tithi = observance decisionপ্রদোষ/মধ্যরাত্রির উৎসব ভুলSeparate ObservanceRule
Surya Siddhanta Moon + Swiss Sun mixUnversioned hybrid resultExplicit compatible calculation profile

Validation checklist

  1. Normalize360(-1) = 359;
  2. Normalize360(361) = 1;
  3. Elongation 0° → শুক্ল প্রতিপদ;
  4. 11.999° → শুক্ল প্রতিপদ;
  5. 12° → শুক্ল দ্বিতীয়া;
  6. 167.999° → শুক্ল চতুর্দশী;
  7. 168° → পূর্ণিমা;
  8. 179.999° → পূর্ণিমা;
  9. 180° → কৃষ্ণ প্রতিপদ;
  10. 347.999° → কৃষ্ণ চতুর্দশী;
  11. 348° → অমাবস্যা;
  12. 359.999° → অমাবস্যা;
  13. 360° normalized → শুক্ল প্রতিপদ;
  14. 90° → শুক্ল অষ্টমী, boundary নয়;
  15. 270° → কৃষ্ণ অষ্টমী, boundary নয়;
  16. পূর্ণিমা interval [168°,180°);
  17. অমাবস্যা interval [348°,360°);
  18. NewMoonInstant = AmavasyaEnd;
  19. FullMoonInstant = PurnimaEnd;
  20. 359°→1° unwrap forward;
  21. Root bracket sign/progress verified;
  22. Bisection result requested tolerance-এর মধ্যে;
  23. Boundary start inclusive, end exclusive;
  24. Exact boundary duplicate event নয়;
  25. Consecutive tithi boundary gap positive;
  26. Sunrise state direct longitude থেকে;
  27. Sunrise-to-next-sunrise zero-boundary case;
  28. এক-boundary case;
  29. দুই-boundary বা tithikshaya case;
  30. Same tithi at consecutive sunrise বা vriddhi case;
  31. “অহোরাত্র” only when next sunrise পর্যন্ত boundary নেই;
  32. Post-midnight local time “নিশা” formatting;
  33. UTC instant ঢাকা/কলকাতা/নিউ ইয়র্কে correct conversion;
  34. Time zone বদলালে absolute JD বদলায় না;
  35. Festival rule sunrise state থেকে আলাদা;
  36. Pradosha rule sunset window test;
  37. Midnight observance test;
  38. Same engine/profile for Sun and Moon;
  39. Apparent/true convention metadata;
  40. UT/TT ও ΔT policy versioned;
  41. Surya Siddhanta regression case;
  42. Drik/Swiss Ephemeris regression case;
  43. Printed Panchanga end-time comparison;
  44. API ও XML একই boundary list দেয়;
  45. Example values production test data হিসেবে marked নয়।

উপসংহার

পক্ষ ও তিথির ভিত্তি হলো সূর্য–চন্দ্রের geocentric longitude difference। ৩৬০° phase cycle-এর প্রতি ১২° একটি তিথি; ০°–১৮০° শুক্লপক্ষ এবং ১৮০°–৩৬০° কৃষ্ণপক্ষ। পূর্ণিমা তিথি [১৬৮°,১৮০°), অমাবস্যা [৩৪৮°,৩৬০°)। Exact Full Moon ১৮০°-এ পূর্ণিমার শেষ, আর exact New Moon ০°-এ অমাবস্যার শেষ।

Astronomical interval location-independent হলেও কোন local sunrise-এ কোন তিথি চলছে তা location ও time zone অনুযায়ী বদলে যায়। তাই event calculation এবং civil-day assignment আলাদা layer হওয়া উচিত। একইভাবে পূর্ণিমা/অমাবস্যার observance selection-কে daily label-এর সঙ্গে এক করে ফেলবেন না।

Production engine-এ consistent longitude profile, 360° unwrap, exact root solver, half-open boundary এবং sunrise-to-next-sunrise event scan ব্যবহার করলে daily details, festival rules, print report, API ও XML একই auditable result দিতে পারে।

তথ্যসূত্র ও আরও পাঠ

  1. U.S. Naval Observatory—Phases of the Moon and Percent Illuminated; principal phase-এর ০°, ৯০°, ১৮০° ও ২৭০° apparent ecliptic-longitude definition.
  2. U.S. Naval Observatory—Astronomical Glossary; conjunction, principal lunar phases ও synodic period terminology.
  3. U.S. Naval Observatory—Crescent Moon Visibility; astronomical New Moon এবং first visible crescent-এর distinction.
  4. Nachum Dershowitz ও Edward M. Reingold—Indian Calendrical Calculations; tithi, sunrise assignment, lunisolar calendar এবং observance-time framework.
  5. Vinod K. Mishra—Calendars of India; ভারতীয় calendrical elements-এর astronomical terminology.
  6. Positional Astronomy Centre—Rashtriya Panchang; tithi, nirayana longitude, solar/lunar events ও official almanac context.
  7. সূর্য সিদ্ধান্ত পঞ্জিকা project specification; sunrise-based Vedic day, Surya Siddhanta/Drik profile separation এবং Bengali rendering rules.

মন্তব্য, আলোচনা ও প্রশ্ন