সূর্যসিদ্ধান্তীয় গণনায় ব্যবহৃত গড় গতি ও যুগধ্রুবক একটি নির্দিষ্ট mathematical tradition অনুসরণ করে। কিন্তু শতাব্দীর পর শতাব্দী সামান্য পার্থক্য জমতে থাকলে সেই model-এর সংক্রান্তির সময় আধুনিক মুদ্রিত পঞ্জিকার সময় থেকে সরে যেতে পারে। সংক্রান্তি মধ্যরাত্রির কাছে ঘটলে কয়েক মিনিট বা কিছু বেশি ব্যবধানও বাংলা তারিখকে এক দিন এগিয়ে বা পিছিয়ে দিতে পারে।
সমস্যাটি কোথায়?
আমাদের পরীক্ষায় দেখা গেছে, অপরিবর্তিত traditional calculation ব্যবহার করলে কিছু আধুনিক বছরে বাংলা সৌরতারিখ মুদ্রিত পঞ্জিকার তুলনায় এক দিন অমিল হয়। উদাহরণস্বরূপ, কোনো দিনে মুদ্রিত পঞ্জিকা ৩১ ভাদ্র দেখালেও uncorrected result ৩২ ভাদ্র দেখাতে পারে।
এটি শুধু display formatting-এর সমস্যা নয়। বাংলা দিনের সংখ্যা নির্ভর করে আগের সিংহ সংক্রান্তি থেকে কতটি সূর্যোদয় অতিক্রান্ত হয়েছে তার ওপর। সংক্রান্তির সময় ভুল side of midnight-এ পড়লে মাসের প্রথম দিন এবং পরবর্তী সব দিনের সংখ্যা এক দিন সরে যায়।
↓ midnight বা sunrise rule-এর অন্য পাশে পড়া
↓ মাসারম্ভ এক দিন পরিবর্তন
↓ পুরো মাসের বাংলা তারিখ এক দিন পরিবর্তন
বীজ সংস্কারের ধারণা
ঐতিহ্যগত ভারতীয় জ্যোতির্বিদ্যায় দীর্ঘমেয়াদি পার্থক্য সামঞ্জস্য করতে কোনো মূল গতি, revolution count বা related parameter-এ ক্ষুদ্র সংশোধন ব্যবহারের ধারণা নতুন নয়। এই ধরনের সংশোধনকে সাধারণভাবে বীজ সংস্কারের সঙ্গে তুলনা করা যায়।
তবে আধুনিক সফটওয়্যারে “বীজ” শব্দ ব্যবহার করলেই যেকোনো সংখ্যা বৈধ হয়ে যায় না। একটি correction গ্রহণযোগ্য করতে হলে অন্তত চারটি বিষয় স্পষ্ট হতে হবে:
- কোন engine parameter পরিবর্তিত হচ্ছে;
- correction-এর unit ও mathematical effect কী;
- কোন সময়সীমা ও কোন outputs-এ এটি প্রযোজ্য;
- কোন মুদ্রিত বা পর্যবেক্ষণমূলক data দিয়ে মানগুলো পরীক্ষা করা হয়েছে।
আমাদের প্রকল্পে correction-টি yr["star"]-এর একটি scoped adjustment। এটিকে global permanent mutation হিসেবে ব্যবহার করা হয় না। মাসের সংক্রান্তি গণনা শেষ হলে অন্য সমস্ত traditional calculation তার original value-তেই চলে।
Sankranti Star Correction table
গবেষণায় পরীক্ষিত ১২টি correction value বাংলা সৌরমাস ও সংশ্লিষ্ট রাশি অনুযায়ী নিচে দেওয়া হলো:
| ক্রম | বাংলা মাস | সৌর রাশি | Star correction |
|---|---|---|---|
| ১ | বৈশাখ | মেষ | ৩১ |
| ২ | জ্যৈষ্ঠ | বৃষ | ২০ |
| ৩ | আষাঢ় | মিথুন | ২৩ |
| ৪ | শ্রাবণ | কর্কট | ৪৮ |
| ৫ | ভাদ্র | সিংহ | ৫১ |
| ৬ | আশ্বিন | কন্যা | ৩৯ |
| ৭ | কার্তিক | তুলা | ৩৩ |
| ৮ | অগ্রহায়ণ | বৃশ্চিক | ৩৯ |
| ৯ | পৌষ | ধনু | ৪৩ |
| ১০ | মাঘ | মকর | ৩২ |
| ১১ | ফাল্গুন | কুম্ভ | ৩০ |
| ১২ | চৈত্র | মীন | ৩৪ |
Array-এর index মেষ থেকে মীন পর্যন্ত ০–১১ অথবা table-এর মতো ১–১২—কোডে যে convention নেওয়া হবে তা একবার স্পষ্টভাবে নির্ধারণ করতে হবে। ভুল zero-based/one-based mapping হলে একটি মাসের correction অন্য মাসে প্রয়োগ হবে।
৩১ বা ৫১ মানে ৩১ বা ৫১ মিনিট নয়
এই table-এর integers হলো সংশ্লিষ্ট engine parameter-এর correction units। yr["star"] += 51 লেখা মানেই সংক্রান্তির সময়ে সরাসরি ৫১ মিনিট যোগ করা নয়। Parameter পরিবর্তনের পরে engine-কে সূর্যের অবস্থান ও রাশি-সীমা নতুন করে গণনা করতে হয়; resulting time shift সেই পুনর্গণনা থেকে পাওয়া যায়।
একই value বিভিন্ন engine implementation-এ একই সময়গত shift দেবে—এমন নিশ্চয়তাও নেই। তাই table-টি code version ও underlying formula-এর সঙ্গে versioned হওয়া উচিত।
Correction কোথায় প্রয়োগ হবে?
Modern Fit branch-এর সবচেয়ে গুরুত্বপূর্ণ নিয়ম হলো strict scope isolation। Correction কেবল নিচের তিনটি output-এ প্রভাব ফেলতে পারবে:
- সংক্রান্তির calibrated সময়;
- বাংলা সৌরমাসের প্রথম দিন;
- সেই মাসারম্ভ থেকে গণিত বাংলা সৌরতারিখ।
Correction কখনোই নিচের গণনাগুলোতে প্রবেশ করবে না:
- তিথি;
- নক্ষত্র ও নক্ষত্রপদ;
- করণ;
- যোগ;
- চন্দ্রের রাশি বা অবস্থান;
- অন্য গ্রহের longitude ও রাশি;
- লগ্ন, ভাব বা রাশি চক্রের সাধারণ planetary data;
- ঐতিহাসিক traditional-mode সংক্রান্তি।
| Output | Traditional branch | Modern Fit branch |
|---|---|---|
| সংক্রান্তি | মূল yr["star"] | মাসভিত্তিক correction সহ |
| বাংলা মাস/তারিখ | Traditional সংক্রান্তি থেকে | Calibrated সংক্রান্তি থেকে |
| তিথি–নক্ষত্র–করণ–যোগ | মূল engine | একই মূল engine; কোনো correction নয় |
| গ্রহস্ফুট | মূল engine | একই মূল engine; কোনো correction নয় |
১৯৪৭ cutoff-এর অর্থ
প্রকল্পে Modern Printed-Panjika Fit স্বয়ংক্রিয়ভাবে প্রয়োগের নীতিগত cutoff হিসেবে Gregorian year 1947 নির্বাচিত হয়েছে। এর অর্থ:
Gregorian year ≥ 1947 → Modern Fit mode, যদি option চালু থাকে
১৯৪৭ সালে সূর্যের গতি হঠাৎ পরিবর্তিত হয়েছে—এমন কোনো দাবি এখানে করা হচ্ছে না। এটি একটি model-policy boundary: পুরোনো historical reconstruction এবং আধুনিক মুদ্রিত পঞ্জিকা-তুলনাকে আলাদা রাখার জন্য নির্বাচিত সীমা।
Historical research page-এ প্রয়োজনে কোনো পুরোনো বছরের ওপর correction manually পরীক্ষা করা যেতে পারে। কিন্তু সেই research override-কে production historical calendar-এর default result হিসেবে প্রকাশ করা উচিত নয়।
গবেষণার দুটি উদাহরণ
১৮১৮ সালের মেষ সংক্রান্তি
মেষের correction value ৩১ দিয়ে একটি পুরোনো মুদ্রিত পঞ্জিকার সঙ্গে গবেষণামূলক comparison করা হয়েছিল। পরীক্ষায় calibrated application result ছিল ১১ এপ্রিল ১৮১৮, বিকেল ৪:২১:০১-এর কাছাকাছি এবং পরবর্তী দিনকে ১ বৈশাখ হিসেবে দেখানো হয়।
এই ফল table-এর সম্ভাব্য কার্যকারিতা দেখায়, কিন্তু ১৮১৮ সাল production cutoff-এর আগে। তাই এটি research comparison, স্বয়ংক্রিয় Modern Fit output নয়। আরও বহু independent historical edition ছাড়া একটি উদাহরণ থেকে সমগ্র শতাব্দীর correction policy নির্ধারণ করা উচিত নয়।
১৪৩৩ বঙ্গাব্দের ভাদ্র
সিংহ/ভাদ্রের correction value ৫১ ব্যবহার করে modern test-এ এক দিনের অমিল দূর হয়েছিল: uncorrected result ৩২ ভাদ্র দেখালেও মুদ্রিত পঞ্জিকার সঙ্গে calibrated result ৩১ ভাদ্রে মিলে যায়। সংশ্লিষ্ট সংক্রান্তির সময়ও printed reference-এর কাছাকাছি আসে।
এই উদাহরণটি দেখায় কেন সংক্রান্তি midnight boundary-এর কাছে থাকলে ছোট model correction বাংলা তারিখে দৃশ্যমান এক দিনের পরিবর্তন আনতে পারে।
নিরাপদ software architecture
শুধু ApplyBijaCorrection()-এর মধ্যে global dictionary পরিবর্তন করলে daily Panchanga, parallel requests অথবা পরবর্তী historical calculation অনিচ্ছাকৃতভাবে corrected state ব্যবহার করতে পারে। তাই correction-টি isolated calculation context-এ প্রয়োগ করা উচিত।
ধারণাগত নিরাপদ flow:
↓ target solar month-এর correction নির্বাচন
↓ শুধু Sankranti calculation-এ cloned star পরিবর্তন
↓ calibrated Sankranti result ফেরত দেওয়া
↓ Bengali month-start service result ব্যবহার করা
Original Panchanga engine অপরিবর্তিত রাখা
ধারণাগত C# নকশা:
static readonly int[] SankrantiStarCorrection =
{ 31, 20, 23, 48, 51, 39, 33, 39, 43, 32, 30, 34 };
bool UseModernFit(int gregorianYear, bool enabled)
{
return enabled && gregorianYear >= 1947;
}
// Clone parameters. Never mutate the shared classical state.
var sankrantiParameters = CloneYearParameters(classicalParameters);
sankrantiParameters["star"] += SankrantiStarCorrection[solarMonthIndex];
// Use only for Sankranti and Bengali solar-date decisions.
var fittedSankranti = CalculateSankranti(sankrantiParameters);
একই request-এ দুটি result field রাখা আরও স্বচ্ছ:
SankrantiTraditionalLocal;SankrantiModernFitLocal;SankrantiCalculationMode;SankrantiCorrectionValue;SankrantiCorrectionTableVersion।
এতে Daily Details ও “ঐতিহাসিক সংক্রান্তি যাচাই” page একই data source ব্যবহার করতে পারে এবং কোন সময়টি কোন mode-এর তা স্পষ্ট থাকে।
Correction table কীভাবে আরও নির্ভরযোগ্য করা যায়?
একটি ভালো calibration dataset-এ প্রতিটি printed reference-এর সঙ্গে নিচের তথ্য রাখা উচিত:
- পঞ্জিকার নাম, প্রকাশক, সংস্করণ ও পৃষ্ঠা;
- বাংলা ও খ্রিস্টীয় বছর;
- শহর বা গণনার স্থান;
- মুদ্রিত সংক্রান্তির ঘড়ির সময় অথবা দণ্ড–পল;
- মুদ্রিত ১ তারিখ এবং weekday;
- পঞ্জিকায় ব্যবহৃত সময়পদ্ধতি জানা থাকলে তার বিবরণ;
- scan/image এবং transcription confidence।
Calibration-এর সময় একই data দিয়ে value নির্বাচন ও accuracy দাবি করা উচিত নয়। কিছু বছর fitting-এর জন্য এবং অন্য বছর validation-এর জন্য আলাদা রাখতে হবে। সম্ভাব্য পরিমাপ:
- প্রতি মাসে median absolute time error;
- maximum error;
- মাসারম্ভের দিন সঠিক হওয়ার হার;
- midnight-boundary cases-এ সঠিক rule outcome;
- অন্য location-এ correction অযথা drift তৈরি করছে কি না।
কোন regression test বাধ্যতামূলক?
Modern Fit চালু করার পরে automated test-এ অন্তত নিচের invariants নিশ্চিত করা উচিত:
| পরীক্ষা | প্রত্যাশিত ফল |
|---|---|
| একই দিন, mode off বনাম on—তিথি | সম্পূর্ণ একই |
| নক্ষত্র, করণ ও যোগ | সম্পূর্ণ একই |
| গ্রহের longitude ও রাশি | সম্পূর্ণ একই |
| সংক্রান্তির সময় | Mode অনুযায়ী পরিবর্তিত হতে পারে |
| বাংলা তারিখ | সংক্রান্তি rule-এর কারণে পরিবর্তিত হতে পারে |
| ১৯৪৬ সালের default | Historical Traditional |
| ১৯৪৭ সালের default, option on | Modern Fit |
| একাধিক parallel calculation | এক request-এর correction অন্য request-এ leak করবে না |
ব্যবহারকারীকে কীভাবে ফল দেখাব?
Correction নীরবে প্রয়োগ না করে calculation mode প্রকাশ করা উচিত। উদাহরণ:
Mode: Modern Printed-Panjika Fit
Solar month: সিংহ · Star correction: ৫১
Tithi/Nakshatra/Karana/Yoga: Classical calculation, unmodified
ঐতিহাসিক export-এ লিখতে হবে Historical Traditional; modern daily page-এ লিখতে হবে Modern Printed-Panjika Fit। Research page-এ দুই সময় পাশাপাশি দেখানো সবচেয়ে কার্যকর:
- Traditional Sankranti;
- Modern Fit Sankranti;
- পার্থক্য মিনিট/সেকেন্ডে;
- প্রয়োগ করা table value;
- দুই mode-এ বাংলা মাসারম্ভের ফল।
উপসংহার
Sankranti Star Correction table একটি আলাদা calibrated model layer। এটি সূর্যসিদ্ধান্তের মূল সূত্রকে গোপনে বদলে দেওয়ার অনুমতি নয়। এর বৈধ ব্যবহার হলো modern printed-panjika comparison-এর জন্য সংক্রান্তি ও বাংলা সৌরতারিখের সীমিত adjustment।
১২টি value—৩১, ২০, ২৩, ৪৮, ৫১, ৩৯, ৩৩, ৩৯, ৪৩, ৩২, ৩০ ও ৩৪—মেষ থেকে মীন পর্যন্ত engine-specific correction। এগুলো সরাসরি মিনিট নয় এবং code version ছাড়া স্বাধীন physical constant হিসেবেও ব্যবহারযোগ্য নয়।
আমাদের নীতি তাই স্পষ্ট: ১৯৪৭-এর আগের historical calculation অপরিবর্তিত traditional branch-এ থাকবে; ১৯৪৭ থেকে option চালু থাকলে Modern Fit branch সংক্রান্তি ও বাংলা তারিখে কাজ করবে; আর তিথি, নক্ষত্র, করণ, যোগ ও গ্রহস্ফুট সর্বদা তাদের মূল calculation path-এ থাকবে।
তথ্যসূত্র ও আরও পাঠ
- Ebenezer Burgess, Translation of the Sûrya-Siddhânta: A Text-book of Hindu Astronomy, 1860.
- প্রকল্পে ব্যবহৃত pancanga3.14
add_bija()পদ্ধতি ও SuryaSiddhantaEngine implementation notes. - সূর্য সিদ্ধান্ত পঞ্জিকা প্রকল্পের SankrantiResearch data এবং scanned printed-panjika comparisons.
- আধুনিক বাংলা মুদ্রিত পঞ্জিকার সংক্রান্তি ও মাসারম্ভ সারণি।
মন্তব্য, আলোচনা ও প্রশ্ন