একটি daily Panjika page-কে midnight-to-midnight report হিসেবে তৈরি করলে রাতের শেষ ভাগের ঘটনা ভুল দিনে চলে যায়। সঠিক model হলো local sunrise থেকে পরদিন local sunrise পর্যন্ত একটি continuous instant window। পঞ্জিকার তিথি, নক্ষত্র, যোগ, করণ, moonrise, saṅkrānti, eclipse এবং festival-rule evaluation এই একই window বা ঘোষিত sub-moment-এর সঙ্গে যুক্ত হবে।
Civil date ও Panjika day এক নয়
| বিষয় | Civil calendar | Traditional Panjika |
|---|---|---|
| দিনের শুরু | Local 00:00 | Local sunrise |
| দিনের শেষ | পরের 00:00 | পরের sunrise |
| তারিখের পরিচয় | Year–month–day | Sunrise-এ গৃহীত weekday, tithi ও Bengali date |
| রাত ১টার event | পরের civil date | আগের sunrise-এ শুরু হওয়া Panjika day |
| দৈর্ঘ্য | DST-এ ২৩/২৫ ঘণ্টা হতে পারে | দুটি actual sunrise-এর interval; fixed ২৪ ঘণ্টা নয় |
ধরা যাক ৮ অক্টোবর sunrise ৬:০৩ AM এবং ৯ অক্টোবর sunrise ৬:০৪ AM। Panjika day হলো ৮ অক্টোবর ৬:০৩ AM থেকে ৯ অক্টোবর ৬:০৪ AM-এর ঠিক আগে পর্যন্ত। ৯ অক্টোবর ২:০০ AM-এর তিথি-শেষ এই Panjika day-এর অংশ, যদিও তার civil date ৯ অক্টোবর।
Half-open interval: শুরু অন্তর্ভুক্ত, শেষ বাদ
Boundary duplication এড়াতে window-কে half-open interval হিসেবে সংজ্ঞায়িত করুন:
= [Sunrise(D), Sunrise(D + 1))
এর অর্থ:
- Current sunrise-এ exact event থাকলে current day-এ অন্তর্ভুক্ত;
- Next sunrise-এর ঠিক আগে event current day-এ;
- Next sunrise-এর exact instant next Panjika day-এ;
- একই event দুই daily page বা দুই XML record-এ duplicate হবে না।
Floating-point Julian Day compare-এ exact equality ঝুঁকিপূর্ণ। Root solver tolerance ও ownership policy আলাদা রাখুন: event time store হবে high precision-এ; assignment হবে startUtc <= eventUtc && eventUtc < endUtc অথবা agreed epsilon-aware equivalent-এ।
Daily date block কী বোঝায়?
Daily header-এ Gregorian date সাধারণত starting sunrise-এর civil label। Bengali date, weekday ও sunrise-based Panchanga state একই starting instant-এ নির্ণীত হবে। Report-এ window-টিও প্রকাশ করা ভালো:
পঞ্জিকা দিনের সীমা:
৮ অক্টোবর ২০২৬, sunrise → ৯ অক্টোবর ২০২৬, next sunrise
“আজ” page-এর দুটি সম্ভাব্য UX আছে:
- Civil-date mode: আজকের civil date-এর sunrise দিয়ে report শুরু;
- Currently-active mode: এখনকার instant-এর আগে সর্বশেষ sunrise থেকে report শুরু—ভোরে sunrise-এর আগে এটি আগের civil date-এর Panjika day।
Default.aspx-এ কোন mode ব্যবহার হচ্ছে তা label করুন। URL-এ explicit date=2026-10-08 দিলে civil-date mode deterministic; “বর্তমান পঞ্জিকা দিন” আলাদা shortcut হতে পারে।
“নিশা” কখন লিখবেন?
Project convention-এ current Panjika window-এর event local midnight-এর পরে কিন্তু next sunrise-এর আগে হলে clock time-এর আগে “নিশা” লেখা হবে। এতে user বুঝবেন event পঞ্জিকা দিনের রাতের পরবর্তী civil-date অংশে পড়েছে।
| Local event time | Display | Machine value |
|---|---|---|
| 8 Oct, 10:14:50 PM | রাত্র ঘ ১০:১৪:৫০ | 2026-10-08T22:14:50+... |
| 9 Oct, 2:59:12 AM | নিশা ঘ ২:৫৯:১২ | 2026-10-09T02:59:12+... |
| 9 Oct, exact next sunrise | পরের দিনের boundary | Next record owns event |
কিছু ephemeris post-midnight time-কে ২৫h, ২৬h ইত্যাদি extended-hour format-এ দেখায়। Project UI Bengali reader-এর জন্য “নিশা ১টা/২টা” ব্যবহার করতে পারে; research/API output-এ full ISO date-time রাখবে। শুধু “২:৫৯” দিলে civil date হারিয়ে যায়।
“অহোরাত্র” label-এর project meaning
Project convention-এ কোনো tithi current sunrise-এ চলমান এবং next sunrise পর্যন্ত শেষ না হলে daily report-এ তার end-time-এর স্থলে “অহোরাত্র” দেখানো হয়। অর্থাৎ current Panjika window-এর মধ্যে ঐ tithi-এর boundary নেই।
and no tithi boundary lies inside [sunrise, next sunrise)
→ display “অহোরাত্র”
“অহোরাত্র” মানে tithi ঠিক ২৪ ঘণ্টা দীর্ঘ—এমন নয়। Tithi current sunrise-এর আগেই শুরু হয়ে থাকতে পারে এবং next sunrise-এর পর শেষ হতে পারে। Label শুধু জানায় current sunrise window-এ tithi change ঘটেনি।
তিথি ক্ষয় ও বৃদ্ধি
একটি tithi সূর্য–চন্দ্রের elongation-এর প্রতি ১২° interval। এর duration fixed ২৪ ঘণ্টা নয়। Sunrise assignment-এর ফলে দুটি বিশেষ অবস্থা দেখা যায়:
| অবস্থা | কি ঘটে | Daily scanner-এর লক্ষণ |
|---|---|---|
| তিথি বৃদ্ধি | একই tithi পরপর দুই sunrise-এ বর্তমান | প্রথম day-এ boundary না থাকলে “অহোরাত্র”; পরের day-এ end event |
| তিথি ক্ষয় | একটি short tithi দুই sunrise-এর মাঝেই শুরু ও শেষ; কোনো sunrise ছোঁয় না | এক window-এ একাধিক tithi transition |
শুধু “sunrise tithi-এর end time” বের করলে ক্ষয় তিথির পরবর্তী transition হারিয়ে যেতে পারে। তাই scanner-কে next sunrise পর্যন্ত loop করে সব boundary সংগ্রহ করতে হবে।
তিথি, নক্ষত্র, করণ ও যোগ—সব transition scan
Daily details-এর “তিথি · নক্ষত্র · করণ · যোগ” block-এ প্রতিটি anga-এর sunrise state এবং window-এর ভেতরের sequential changes দেখাতে হবে:
- Sunrise instant-এ current anga index নির্ণয় করুন;
- তার next boundary exact instant solve করুন;
- Boundary next sunrise-এর আগে হলে event list-এ যোগ করুন;
- Boundary-এর ঠিক পরে নতুন state নিয়ে পরের boundary খুঁজুন;
- Next sunrise পৌঁছানো পর্যন্ত loop করুন;
- কোনো boundary না থাকলে applicable “অহোরাত্র” বা “পরদিন পর্যন্ত” label দিন।
| Aṅga | Angular unit | Scanner expectation |
|---|---|---|
| তিথি | Moon−Sun প্রতি ১২° | ০, ১ বা বিরল ক্ষেত্রে একাধিক boundary |
| নক্ষত্র | Moon longitude প্রতি ১৩°২০′ | সব boundary loop করে সংগ্রহ |
| যোগ | Sun+Moon প্রতি ১৩°২০′ | Wrap-aware sum ও sequential boundary |
| করণ | Moon−Sun প্রতি ৬° | সাধারণত tithi-এর তুলনায় বেশি transition |
প্রতিটি boundary event-এ রাখুন: previous name/index, next name/index, UTC/JD, local DateTimeOffset, Panjika-time label, ghaṭikā/pala এবং calculation profile। Renderer “পরে” শব্দ যোগ করবে; calculation layer নয়।
সূর্য, চন্দ্র, লগ্ন ও অন্যান্য events
একই window-এ astronomical events সংগ্রহ করতে হবে:
- Starting sunrise—window boundary হিসেবে;
- Sunset;
- Moonrise ও moonset—যেটি আগে ঘটুক chronological order-এ;
- Next sunrise—end boundary হিসেবে, event list-এর owner নয়;
- Lagna changes বা lagna-end times;
- Saṅkrānti;
- Solar/lunar eclipse contacts ও visibility;
- Planetary rāśi/pada changes, যদি daily report-এ চাওয়া হয়।
Moonrise সব date-এ sunrise-এর পরে হবে—এমন assumption ভুল। Search interval শুরু হওয়ার আগে/পরে event না থাকতেও পারে। Swiss Ephemeris rise/set call-কে window-এর শুরু থেকে repeatedly query করে candidate events filter করুন এবং globally sort করুন।
Rise/set definition metadata-ও প্রকাশযোগ্য: project setting অনুযায়ী Sun center/no-refraction এবং Moon edge/apparent হলে সেই flags API ও research report-এ রাখুন। অন্য library default ব্যবহার করলে কয়েক মিনিট difference হতে পারে।
উৎসবের observance rule ও display event আলাদা
Festival শুধু daily window-এ কোনো tithi আছে কি না দেখে নির্ধারিত হয় না। প্রত্যেক observance-এর rule-moment আলাদা হতে পারে:
| Observance | প্রধান rule-moment |
|---|---|
| সাধারণ sunrise festival | Sunrise tithi |
| একাদশী | Aruṇodaya, sunrise ও school-specific viddhi |
| জন্মাষ্টমী | Local midnight এবং Rohiṇī/tithi relation |
| রামনবমী | Declared madhyāhna/midpoint rule |
| নিশিপালন অমাবস্যা/পূর্ণিমা | Night interval বা midnight |
| পারণ | পরের day sunrise, tithi end ও allowed window |
Event scanner raw tithi transitions দেয়; FestivalRuleEngine সেই timeline-এর ওপর rule চালায়। Festival result-এ evaluated moments ও applied rule code রাখলে একই transition data Smārta, Nimbārka বা Gosvāmī school-এর জন্য আলাদাভাবে ব্যবহার করা যায়।
সব event কীভাবে সাজাবেন?
Category অনুযায়ী section আলাদা হলেও একটি canonical master list UTC instant অনুযায়ী sort করা উচিত। Local display string sort করলে “নিশা ২টা” ভুল করে afternoon-এর আগে বা পরে যেতে পারে।
| Sort key | Purpose |
|---|---|
InstantUtc | Primary chronological order |
EventPriority | একই instant-এর deterministic order |
Sequence | Stable final tie-break |
Recommended same-instant priority: boundary marker → tithi/nakṣatra/yoga/karana transition → rise/set → festival annotation। Priority astronomical truth নয়; stable presentation policy।
Timezone ও DST: Panjika day সবসময় ২৪ ঘণ্টা নয়
New York-এর DST transition-এ দুটি local sunrise-এর UTC difference প্রায় ২৩ বা ২৫ ঘণ্টা হতে পারে। তাই:
nextSunrise = sunrise.AddHours(24)ব্যবহার করবেন না;- পরের civil date-এর astronomical sunrise নতুন করে calculate করুন;
- সব event internally UTC/JD-তে compare করুন;
- Local display-এ
DateTimeOffsetও actual UTC offset রাখুন; - Ambiguous local clock hour-এ offset দেখান;
- Timezone database version research metadata-তে রাখুন।
Dhaka বা Kolkata-তে modern DST না থাকলেও shared architecture একই রাখুন। Fixed +05:30 ancient date-এর historical proof নয়; time convention declare করুন।
C# data model ও event scanner
public sealed class PanjikaDayWindow
{
public DateTimeOffset Sunrise { get; init; }
public DateTimeOffset NextSunrise { get; init; }
public string LocationId { get; init; }
public string TimeZoneId { get; init; }
public bool Contains(DateTimeOffset instant)
=> Sunrise.ToUniversalTime() <= instant.ToUniversalTime()
&& instant.ToUniversalTime() < NextSunrise.ToUniversalTime();
}
public sealed class PanjikaEvent
{
public string Kind { get; init; }
public string PreviousValue { get; init; }
public string NextValue { get; init; }
public DateTimeOffset LocalTime { get; init; }
public double JulianDayUt { get; init; }
public int Priority { get; init; }
public string CalculationProfileId { get; init; }
}
Generic transition scanner:
IReadOnlyList<PanjikaEvent> ScanTransitions(
PanjikaDayWindow window,
IAngaBoundarySolver solver)
{
var events = new List<PanjikaEvent>();
DateTimeOffset cursor = window.Sunrise;
int state = solver.StateAt(cursor);
for (int guard = 0; guard < 8; guard++)
{
Boundary next = solver.FindNextBoundary(cursor, state);
if (next.InstantUtc >= window.NextSunrise.ToUniversalTime())
break;
events.Add(ToEvent(next, state));
state = next.NextState;
cursor = next.LocalTime.AddTicks(1);
}
return events;
}
AddTicks(1) এখানে conceptual progress marker; solver tolerance-এর তুলনায় এক tick খুব ছোট হলে একই root পুনরায় আসতে পারে। Production code-এ boundary-এর পরে safe angular/time epsilon ব্যবহার করুন এবং next state explicitly pass করুন। Loop guard failure হলে silent truncation নয়—diagnostic exception দিন।
City ও Date API response
User যদি URL-এ City ও Date পাঠান, response-এ display-ready block এবং machine-readable timeline উভয় রাখা যায়:
{
"request": {
"city": "Kolkata",
"date": "2026-10-08",
"mode": "civil-date"
},
"window": {
"sunrise": "2026-10-08T05:31:00+05:30",
"nextSunrise": "2026-10-09T05:31:30+05:30",
"boundary": "[sunrise,nextSunrise)"
},
"dateBlockHtml": "...",
"panchangaBlockHtml": "...",
"events": [
{
"kind": "tithi-end",
"localTime": "2026-10-08T22:14:50+05:30",
"displayPeriod": "রাত্র",
"from": "ত্রয়োদশী",
"to": "চতুর্দশী"
},
{
"kind": "yoga-end",
"localTime": "2026-10-09T02:59:12+05:30",
"displayPeriod": "নিশা",
"from": "শুক্ল",
"to": "ব্রহ্ম"
}
]
}
HTML strings convenience field; authoritative values structured JSON। API client চাইলে নিজের language renderer ব্যবহার করতে পারবে। Cache key-তে city coordinates, timezone, date, calculation profile ও language/version রাখুন।
Yearly Printed Panjika XML
<tithi> section-এ শুধু sunrise snapshot নয়, sunrise-to-next-sunrise সব relevant events দিতে হবে—project-এর yearly XML requirement অনুযায়ী:
<panji date="৮ অক্টোবর ২০২৬"
bangla_date="২০ আশ্বিন ১৪৩৩ বঙ্গাব্দ"
sunrise="2026-10-08T05:31:00+05:30"
next_sunrise="2026-10-09T05:31:30+05:30">
<din><![CDATA[...printed-date block...]]></din>
<graha><![CDATA[...summary and grahasphuta...]]></graha>
<tithi><![CDATA[
সূর্যোদয় ও সূর্যাস্ত...
চন্দ্রোদয় ও চন্দ্রাস্ত...
তিথি, নক্ষত্র, করণ ও যোগের সব পরিবর্তন...
উৎসব, উপবাস ও eclipse information...
]]></tithi>
<hoba><![CDATA[...অমৃত-মহেন্দ্রাদি, শুদ্ধি ও যাত্রা...]]></hoba>
<lagna><![CDATA[...লগ্নের শেষ সময়...]]></lagna>
</panji>
CDATA publication text-এর পাশাপাশি optional structured <events> child রাখলে data পুনরায় parse করতে হবে না। HTML, API ও XML একই PanjikaDayResult model থেকে render হবে—page scraping করে XML বানানো কম নির্ভরযোগ্য।
Validation checklist
- Window start sunrise inclusive;
- Next sunrise exclusive;
- Exact next-sunrise event শুধু next record-এ;
- Midnight-এর এক second আগে “রাত্র”;
- Midnight-এর exact instant policy;
- Midnight-এর এক second পরে “নিশা”;
- Next sunrise-এর এক second আগে current day;
- Boundary-হীন tithi-তে “অহোরাত্র”;
- Same tithi at two sunrises—vṛddhi case;
- এক window-এ two tithi transitions—kṣaya case;
- Karana scanner multiple boundaries হারায় না;
- Nakṣatra ও yoga ৩৬০° wrap;
- Moonset before moonrise chronological order;
- No moonrise/moonset result cleanভাবে handled;
- Saṅkrānti at midnight এবং sunrise boundaries;
- Eclipse contacts window-filtered ও visibility-labeled;
- Aruṇodaya event window-এর আগে হলেও festival engine access পায়;
- Janmāṣṭamī midnight rule selected location-এ;
- Parāṇa next-day window correct record-এ;
- New York spring-forward day;
- New York fall-back ambiguous hour with offset;
- Kolkata, Dhaka ও New York same UTC event ordering;
- Traditional ও Drik profiles mix হয় না;
- Daily HTML, API এবং XML event IDs identical;
- Scanner loop guard diagnostic;
- No duplicate events across consecutive days।
উপসংহার
Traditional daily Panjika midnight-to-midnight document নয়। এটি current local sunrise inclusive থেকে next local sunrise exclusive পর্যন্ত একটি astronomical ও ritual timeline। Post-midnight event-এর civil date বদলালেও event চলমান Panjika day-এর অংশ; user-facing Bengali label “নিশা” সেই সম্পর্ক স্পষ্ট করে।
Sunrise-এ চলমান tithi next sunrise পর্যন্ত অপরিবর্তিত থাকলে project “অহোরাত্র” দেখায়। Short tithi দুই sunrise-এর মাঝেই শুরু ও শেষ হলে tithi kṣaya দেখা যায়; তাই শুধু প্রথম end-time নয়, window-এর সব transition scan করা অপরিহার্য। একই নীতি nakṣatra, yoga ও karana-তেও প্রযোজ্য।
Daily page, print report, API ও yearly XML একই half-open window এবং একই event model ব্যবহার করলে রাতের ঘটনা হারায় না, next-day duplication হয় না এবং festival rules raw timeline-এর ওপর reproducibly চালানো যায়। Internal ordering UTC/JD-তে, display selected timezone ও language-এ—এই separation multi-location Panjika-র সবচেয়ে নিরাপদ architecture।
তথ্যসূত্র ও আরও পাঠ
- Positional Astronomy Centre, Kolkata—Rashtriya Panchang explanation; post-midnight events, extended-hour notation এবং Panchanga timing conventions.
- Government of India—Report of the Calendar Reform Committee, 1955; Indian civil-day, tithi ও calendar conventions.
- Robert Sewell ও Śaṅkara Bālakṛṣṇa Dīkṣita—The Indian Calendar, 1896.
- M. Yano ও M. Fushimi—Pancanga 3.14 program notes; location-specific sunrise ও traditional computation.
- Astrodienst—Swiss Ephemeris Programmer’s Documentation; rise/set calculations, time scales ও flags.
- সূর্য সিদ্ধান্ত পঞ্জিকা project; daily details renderer, festival rule engine, API date block এবং Yearly Printed Panjika XML specification.
মন্তব্য, আলোচনা ও প্রশ্ন