Daily details-এ “করণ: গর সকাল ১০:৫৩ পর্যন্ত পরে বণিজ; পরে বণিজ রাত ১০:১৪ পর্যন্ত পরে বিষ্টি”—এমন output একটি single field নয়। Sunrise-to-next-sunrise interval-এ ৬° elongation boundary যতবার পড়ে, সব transition chronological order-এ রাখতে হয়। করণের গড় সময় প্রায় অর্ধদিন বলে এক Vedic day-এ একাধিক করণ দেখাই স্বাভাবিক।
করণ কী?
তিথির মতো করণও সূর্য–চন্দ্রের geocentric longitude difference বা elongation থেকে আসে:
১ তিথি = ১২° elongation
১ করণ = ৬° elongation = অর্ধতিথি
একটি lunar phase cycle ৩৬০°; তাই:
৩০ তিথি × ২ = ৬০ half-tithi
Position ১ থেকে ৬০ unique angular intervals। কিন্তু প্রতিটির unique নাম নেই; নামকরণ একটি fixed + repeating sequence অনুসরণ করে।
৬০ position, কিন্তু নাম ১১টি
| শ্রেণি | নাম | কতবার |
|---|---|---|
| চল/চর | বব, বালব, কৌলব, তৈতিল, গর, বণিজ, বিষ্টি | প্রতিটি ৮ বার; মোট ৫৬ position |
| স্থির | কিমস্তুঘ্ন, শকুনি, চতুষ্পদ, নাগ | প্রতিটি ১ বার; মোট ৪ position |
৫৬ + ৪ = ৬০। তাই “এক মাসে ৬০ করণ” মানে ৬০ নাম নয়; ৬০ interval occurrence। API-তে HalfTithiIndex এবং KaranaKey দুটোই রাখা দরকার।
সাতটি চল করণের পুনরাবৃত্তি
চল করণের order অপরিবর্তিত:
এই সাতটি আট cycle-এ মোট ৫৬ half-tithi cover করে। শুরু হয় শুক্ল প্রতিপদের দ্বিতীয়ার্ধে এবং শেষ হয় কৃষ্ণ চতুর্দশীর প্রথমার্ধে।
চারটি স্থির করণের নির্দিষ্ট স্থান
| Half index | তিথির অংশ | স্থির করণ |
|---|---|---|
| ১ | শুক্ল প্রতিপদ—প্রথমার্ধ | কিমস্তুঘ্ন |
| ৫৮ | কৃষ্ণ চতুর্দশী—দ্বিতীয়ার্ধ | শকুনি |
| ৫৯ | অমাবস্যা—প্রথমার্ধ | চতুষ্পদ |
| ৬০ | অমাবস্যা—দ্বিতীয়ার্ধ | নাগ |
New Moon/conjunction boundary-তে নাগ শেষ এবং পরের cycle-এর কিমস্তুঘ্ন শুরু। এটি half-open interval rule-এর একটি গুরুত্বপূর্ণ regression test।
Exact ১–৬০ mapping rule
| Global half index | নামকরণের rule | উদাহরণ |
|---|---|---|
| ১ | স্থির | কিমস্তুঘ্ন |
| ২–৫৭ | (index−2) mod 7 দিয়ে চল cycle | ২=বব, ৩=বালব … ৮=বিষ্টি, ৯=বব |
| ৫৮ | স্থির | শকুনি |
| ৫৯ | স্থির | চতুষ্পদ |
| ৬০ | স্থির | নাগ |
Boundary cases:
- শুক্ল প্রতিপদ প্রথমার্ধ—কিমস্তুঘ্ন;
- শুক্ল প্রতিপদ দ্বিতীয়ার্ধ—বব;
- শুক্ল দ্বিতীয়া প্রথমার্ধ—বালব;
- শুক্ল দ্বিতীয়া দ্বিতীয়ার্ধ—কৌলব;
- কৃষ্ণ চতুর্দশী প্রথমার্ধ—বিষ্টি;
- কৃষ্ণ চতুর্দশী দ্বিতীয়ার্ধ—শকুনি;
- অমাবস্যা—চতুষ্পদ তারপর নাগ।
Global half-tithi index
HalfTithiIndex = floor(E ÷ ৬°) + ১
TithiIndex = floor(E ÷ ১২°) + ১
Range:
Half 1 = [ 0°, 6°)
Half 2 = [ 6°, 12°)
...
Half 59 = [348°, 354°)
Half 60 = [354°, 360°)
Exact ৬°-এ half ১ শেষ, half ২ শুরু। Exact ৩৬০° normalize হয়ে ০°—নতুন cycle-এর half ১।
প্রতিটি তিথির প্রথম ও দ্বিতীয় করণ
Global half index H থেকে:
H odd → তিথির প্রথমার্ধ
H even → তিথির দ্বিতীয়ার্ধ
প্রথমার্ধ/দ্বিতীয়ার্ধ মানে civil সকাল/বিকেল নয়। এটি তিথির ১২° angular span-এর প্রথম ৬° ও পরের ৬°; clock time Moon-এর variable speed অনুযায়ী বদলায়।
Ayanāṃśa ও longitude frame
করণ তিথির মতো Moon–Sun difference ব্যবহার করে। একই ayanāṃśa দুই nirayana longitude থেকে বিয়োগ হলে cancel করে:
তাই compatible tropical অথবা compatible sidereal longitude থেকে একই elongation পাওয়া উচিত। কিন্তু geocentric/topocentric, apparent/mean, time scale বা ephemeris version mix করলে cancellation আপনাকে রক্ষা করবে না।
করণের শেষ সময়
Current half index H হলে next target:
H = ৬০ হলে target = ৩৬০°/০°
Solve: Normalize360(Moon(t) − Sun(t)) crosses target
এটি একই root family যা তিথির end time-এ ব্যবহৃত হয়; পার্থক্য target spacing ১২°-এর বদলে ৬°। প্রতিটি even-numbered karana boundary একই সঙ্গে একটি তিথির boundary। Odd-numbered boundary শুধু করণ বদলায়, তিথি নয়।
Daily details-এ একাধিক করণ কেন?
একটি করণ প্রায় অর্ধতিথি; sunrise-to-next-sunrise interval-এ সাধারণত দুই বা কখনও তার বেশি transition পড়তে পারে। Output data একটিমাত্র KaranaEnd field হলে পরের event হারাবে।
| Sunrise state | Day-এর transition | Display |
|---|---|---|
| গর | ১০:৫৩-এ বণিজ | করণ: গর … পর্যন্ত পরে বণিজ |
| তারপর বণিজ | ২২:১৪-এ বিষ্টি | পরে: বণিজ … পর্যন্ত পরে বিষ্টি |
| তারপর বিষ্টি | Next sunrise-এর পরে শেষ | আর line দরকার নেই; state next day-এ চলবে |
এই সময়গুলো illustration; production ephemeris values নয়। Renderer boundary list iterate করবে—hard-coded সর্বোচ্চ দুই line নয়।
বিষ্টি ও “ভদ্র” alias
বিষ্টি করণকে অনেক regional tradition-এ “ভদ্র” বলা হয়। Calculation model-এ canonical key vishti; language/tradition resource alternate label দিতে পারে:
key = "vishti"
nameBn = "বিষ্টি"
aliasesBn = ["ভদ্র"]
কোন কাজে কোন করণ গ্রহণযোগ্য—এটি muhurta policy, astronomical calculation নয়। কোনো practice universal ধরে hard-code না করে authority/version সহ আলাদা rule layer রাখুন।
Production calculation pipeline
- Compatible geocentric Sun/Moon longitude profile স্থির করুন;
- Requested instant-এ
E = Normalize360(Moon − Sun); floor(E/6)+1থেকে half index;- Fixed/repeating naming function প্রয়োগ;
- Next multiple of ৬° target;
- Short-step forward scan দিয়ে crossing bracket;
- Unwrapped elongation দিয়ে exact root;
- Sunrise-to-next-sunrise সব ৬° boundary collect;
- Local time, নিশা ও দণ্ড-পল render;
- Half index, তিথি index, name, JD ও profile export।
C# 5-compatible data model
public enum KaranaClass
{
Chara,
Sthira
}
public sealed class KaranaState
{
public int HalfTithiIndex { get; set; } // 1..60
public int TithiIndex { get; set; } // 1..30
public bool IsFirstHalf { get; set; }
public string Key { get; set; }
public string NameBn { get; set; }
public KaranaClass Class { get; set; }
public double Elongation { get; set; }
public double StartDegrees { get; set; }
public double EndDegrees { get; set; }
}
public sealed class KaranaBoundary
{
public int EndingHalfIndex { get; set; }
public int StartingHalfIndex { get; set; }
public string EndingKey { get; set; }
public string StartingKey { get; set; }
public double JulianDayUt { get; set; }
public DateTimeOffset InstantUtc { get; set; }
}
C# naming function
static readonly string[] CharaKeys =
{
"bava", "balava", "kaulava", "taitila",
"gara", "vanija", "vishti"
};
static readonly string[] CharaNamesBn =
{
"বব", "বালব", "কৌলব", "তৈতিল",
"গর", "বণিজ", "বিষ্টি"
};
static KaranaState KaranaAt(double moonLongitude, double sunLongitude)
{
double elongation = Normalize360(moonLongitude - sunLongitude);
int half = (int)Math.Floor(elongation / 6.0) + 1;
if (half < 1) half = 1;
if (half > 60) half = 60;
string key;
string name;
KaranaClass kind;
if (half == 1)
{
key = "kimstughna";
name = "কিমস্তুঘ্ন";
kind = KaranaClass.Sthira;
}
else if (half <= 57)
{
int movable = (half - 2) % 7;
key = CharaKeys[movable];
name = CharaNamesBn[movable];
kind = KaranaClass.Chara;
}
else if (half == 58)
{
key = "shakuni";
name = "শকুনি";
kind = KaranaClass.Sthira;
}
else if (half == 59)
{
key = "chatushpada";
name = "চতুষ্পদ";
kind = KaranaClass.Sthira;
}
else
{
key = "naga";
name = "নাগ";
kind = KaranaClass.Sthira;
}
return new KaranaState
{
HalfTithiIndex = half,
TithiIndex = ((half - 1) / 2) + 1,
IsFirstHalf = (half % 2) == 1,
Key = key,
NameBn = name,
Class = kind,
Elongation = elongation,
StartDegrees = (half - 1) * 6.0,
EndDegrees = half * 6.0
};
}
এই mapping formula আলাদা test করুন; astronomy ঠিক হলেও off-by-one naming bug হলে পুরো মাসের করণ ভুল দেখাবে।
C# ৬° boundary solver
static double Normalize360(double value)
{
value %= 360.0;
if (value < 0.0) value += 360.0;
return value;
}
static double ForwardArc(double value, double anchor)
{
return Normalize360(value - anchor);
}
static double SolveKaranaBoundary(
double leftJd,
double rightJd,
double anchorElongation,
double targetForwardArc,
Func<double, double> elongationAt,
double toleranceDays)
{
Func<double, double> f = delegate(double jd)
{
return ForwardArc(elongationAt(jd), anchorElongation) -
targetForwardArc;
};
if (f(leftJd) > 0.0 || f(rightJd) < 0.0)
throw new ArgumentException("Karana boundary is not bracketed.");
while (rightJd - leftJd > toleranceDays)
{
double middleJd = (leftJd + rightJd) / 2.0;
if (f(middleJd) < 0.0)
leftJd = middleJd;
else
rightJd = middleJd;
}
return (leftJd + rightJd) / 2.0;
}
Elongation average-speed দিয়ে extrapolate না করে প্রতিটি trial JD-তে Sun ও Moon longitude পুনর্গণনা করুন। ৩৬০° conjunction wrap ForwardArc সামলাবে, যদি bracket একটি cycle-এর চেয়ে ছোট থাকে।
Sunrise থেকে পরের sunrise সব boundary scan
public sealed class VedicDayKaranaReport
{
public DateTimeOffset Sunrise { get; set; }
public DateTimeOffset NextSunrise { get; set; }
public KaranaState AtSunrise { get; set; }
public IList<KaranaBoundary> Boundaries { get; set; }
public string AstronomyProfile { get; set; }
}
// Half-open assignment:
// sunriseJd <= boundaryJd && boundaryJd < nextSunriseJd
Scanner প্রথম target solve করার পর half index increment করে next ৬° target নেবে। ৬০-এর পরে ১ wrap হবে। Event list length hard-code না করে root next sunrise-এর আগে থাকা পর্যন্ত iterate করুন, সঙ্গে safety limit রাখুন।
API ও XML output
{
"karanaAtSunrise": {
"halfTithiIndex": 40,
"tithiIndex": 20,
"tithiHalf": 2,
"key": "gara",
"nameBn": "গর",
"class": "chara",
"elongation": 235.442718
},
"boundaries": [
{
"ending": "gara",
"starting": "vanija",
"julianDayUt": 2461321.703981,
"localTime": "2026-10-08T10:53:44+06:00"
},
{
"ending": "vanija",
"starting": "vishti",
"julianDayUt": 2461322.176968,
"localTime": "2026-10-08T22:14:50+06:00"
}
],
"astronomyProfile": "surya-siddhanta-v3"
}
XML:
<karana-day astronomy-profile="surya-siddhanta-v3">
<at-sunrise half-index="40" tithi-index="20"
half="2" key="gara" class="chara">গর</at-sunrise>
<boundary ending="gara" starting="vanija"
jd-ut="2461321.703981"
local="2026-10-08T10:53:44+06:00" />
<boundary ending="vanija" starting="vishti"
jd-ut="2461322.176968"
local="2026-10-08T22:14:50+06:00" />
</karana-day>
Example numbers output-format demonstration; ephemeris test vector নয়।
ঐতিহাসিক calculation
করণ boundary তিথির অর্ধেক interval, তাই historical Sun/Moon model discrepancy একই angular error-কে আরও fine-grained label-এ প্রকাশ করতে পারে। Compare করার সময় রাখুন:
- Sun ও Moon theory/ephemeris version;
- true/mean/apparent longitude convention;
- geocentric/topocentric reference;
- UT–TT ও ΔT;
- root tolerance;
- local sunrise/time zone;
- Julian/Gregorian display calendar।
Internal chronology Julian Day রাখলে early historical years-এ .NET DateTime limitation এবং ১৫৮২ civil-calendar gap core calculation-কে প্রভাবিত করবে না।
সাধারণ implementation error
| ভুল | ফল | সংশোধন |
|---|---|---|
| ১২° দিয়ে divide | করণ নয়, তিথি index | প্রতি ৬° half-tithi |
| ১১ নাম সরল repeat | স্থির করণের অবস্থান ভুল | ১, ২–৫৭, ৫৮, ৫৯, ৬০ mapping |
| চল cycle half ১ থেকে | সব নাম এক position shift | Half ২ থেকে বব |
| Half ৫৭-এর পরে বব | স্থির sequence হারায় | ৫৮ শকুনি, ৫৯ চতুষ্পদ, ৬০ নাগ |
| First/second half = AM/PM | ভুল civil interpretation | Angular half of tithi |
| একটি end field | দ্বিতীয় transition হারায় | Boundary list |
| Conjunction wrap ignore | নাগ→কিমস্তুঘ্ন failure | Forward unwrapped elongation |
| Average speed end time | Printed time mismatch | Root solver |
| Vishti rule astronomy-তে hard-code | Tradition ও calculation মিশে যায় | Separate muhurta policy |
| Modern-fit Saṅkrānti correction leak | Tithi/Karana inconsistency | Profile isolation |
Validation checklist
- ০° → half ১ কিমস্তুঘ্ন;
- ৫.৯৯৯° → কিমস্তুঘ্ন;
- ৬° → half ২ বব;
- ১২° → half ৩ বালব ও তিথি ২;
- ১৮° → half ৪ কৌলব;
- ২৪° → half ৫ তৈতিল;
- ৩০° → half ৬ গর;
- ৩৬° → half ৭ বণিজ;
- ৪২° → half ৮ বিষ্টি;
- ৪৮° → half ৯ বব cycle restart;
- Half ১ fixed;
- Half ২–৫৭ chara;
- Half ৫৭ বিষ্টি;
- Half ৫৮ শকুনি;
- Half ৫৯ চতুষ্পদ;
- Half ৬০ নাগ;
- ৩৪২° → half ৫৮;
- ৩৪৮° → half ৫৯;
- ৩৫৪° → half ৬০;
- ৩৬০° normalized → half ১;
- ৭ chara × ৮ = ৫৬ occurrences;
- ৪ sthira × ১ = ৪ occurrences;
- Total ৬০ positions;
- Odd half = first half;
- Even half = second half;
- Tithi index ১–৩০;
- Half index ১–৬০;
- Every second boundary tithi boundary;
- Ayanāṃśa same-frame cancellation;
- Sun/Moon compatible profile;
- Modern-fit correction isolated;
- Conjunction 360° wrap;
- Naga→Kimstughna root;
- Boundary bracket verified;
- One-second tolerance test;
- Exact next sunrise boundary next day-এ;
- এক Vedic day-এ one-boundary case;
- two-boundary case;
- three-boundary edge case;
- Boundary list chronological;
- No duplicate shared-boundary event;
- Post-midnight “নিশা” rendering;
- Clock time ও দণ্ড-পল same root;
- Vishti alias “ভদ্র” localization-only;
- Surya Siddhanta regression case;
- Drik/Swiss regression case;
- Printed Panchanga two-Karana comparison;
- Historical Julian/Gregorian label same JD;
- API ও XML same half-index/name/root;
- Cache key-তে astronomy profile version।
উপসংহার
করণ হলো Moon–Sun elongation-এর ৬° interval—এক তিথির অর্ধেক। এক phase cycle-এ ৬০ position হলেও নাম ১১টি। Half ১ কিমস্তুঘ্ন; half ২–৫৭-এ সাত চল করণ আটবার repeat; half ৫৮ শকুনি, ৫৯ চতুষ্পদ এবং ৬০ নাগ।
Calculation-এ floor(E/6)+1 half index এবং exact naming function আলাদা রাখুন। Ending time average-duration নয়; next ৬° boundary-এর root। Sunrise-to-next-sunrise সব boundary list করলে গর→বণিজ→বিষ্টির মতো multi-transition output সম্পূর্ণ থাকে।
তিথির সঙ্গে একই Sun–Moon profile ব্যবহার করুন এবং Saṅkrānti modern-fit correction থেকে Karana engine বিচ্ছিন্ন রাখুন। Astronomy, local-day rendering এবং muhurta interpretation পৃথক layer হলে daily details, printed report, API ও XML নির্ভরযোগ্য থাকবে।
তথ্যসূত্র ও আরও পাঠ
- Positional Astronomy Centre—Rashtriya Panchang Explanation; ৬° Karana definition, ৭ recurring ও ৪ fixed Karana-এর official outline.
- Rashtriya Panchang—Daily Panchanga; sunrise Karana এবং পরবর্তী Karana ending-time presentation-এর live example.
- Hindu Calendars—Kanchi Kamakoti resource; Kimstughna opening half, ৫৬ repeating positions ও closing fixed sequence.
- Nachum Dershowitz ও Edward M. Reingold—Indian Calendrical Calculations; Indian lunisolar event, longitude ও sunrise framework.
- Astrodienst—Swiss Ephemeris Programmer’s Documentation; Sun/Moon longitude ও event-time implementation reference.
- Vinod K. Mishra—Calendars of India; Panchanga elements-এর astronomical terminology.
- সূর্য সিদ্ধান্ত পঞ্জিকা project specification; classical tithi/Karana profile, sunrise event list, নিশা ও দণ্ড-পল formatting.
মন্তব্য, আলোচনা ও প্রশ্ন