কেউ বলেন সূর্যের প্রথম কিনারা দেখা গেলেই sunrise; কেউ বলেন সূর্যের কেন্দ্র mathematical horizon অতিক্রম করলে sunrise। পৃথিবীর atmosphere আলো বাঁকিয়ে সূর্যকে তার geometric অবস্থানের চেয়ে ওপরে দেখায়। আবার পাহাড়, ভবন বা সমুদ্রের horizon-ও একই নয়। তাই sunrise/sunset comparison করার প্রথম প্রশ্ন হওয়া উচিত: দুই গণনায় event definition কি একই?
“সূর্য উঠেছে”—কিন্তু কোন instant?
সূর্য একটি দৃশ্যমান disk; point source নয়। ভোরে disk-এর অংশগুলো ধারাবাহিকভাবে horizon অতিক্রম করে:
- প্রথমে upper limb বা উপরের কিনারা দেখা যায়;
- তারপর center horizon-এ আসে;
- সবশেষে lower limb উঠলে পুরো disk দৃশ্যমান হয়।
সূর্যাস্তে sequence উল্টো: lower limb আগে horizon ছোঁয়, center পরে, upper limb অদৃশ্য হলে পুরো disk অস্ত যায়। কোনো software যদি “rise/set” বলে কিন্তু limb/refraction profile না জানায়, output পুরোপুরি reproducible নয়।
Upper limb, center ও lower limb
| Disc definition | Sunrise | Sunset | ব্যবহার |
|---|---|---|---|
| Upper limb | প্রথম কিনারা দৃশ্যমান | শেষ কিনারা অদৃশ্য | সাধারণ astronomical almanac ও public rise/set |
| Center | Center horizon অতিক্রম | Center horizon অতিক্রম | কিছু Hindu/Vedic calculation profile |
| Lower limb | পুরো disk horizon-এর ওপরে | Disk-এর প্রথম অংশ horizon-এর নিচে | বিশেষ observational definition |
সূর্যের apparent semidiameter গড়ে প্রায় ১৬ arcminute। তাই refraction বাদ দিলেও upper-limb sunrise center-at-horizon sunrise-এর আগে এবং upper-limb sunset পরে হবে। Earth–Sun distance বদলায় বলে solar semidiameter সারা বছর সামান্য পরিবর্তিত হয়; high-precision ephemeris library সেই পরিবর্তন নিজে সামলাতে পারে।
Atmospheric refraction কী করে?
বায়ুমণ্ডলের ঘনত্ব উচ্চতার সঙ্গে বদলায়। Horizon-এর কাছে সূর্যালোক দীর্ঘ পথ atmosphere-এর মধ্যে দিয়ে আসে এবং বাঁকে; ফলে apparent Sun geometric Sun-এর চেয়ে ওপরে দেখা যায়। তাই geometric center horizon-এর নিচে থাকলেও upper limb দৃশ্যমান হতে পারে।
Refraction স্থির physical constant নয়। Pressure, temperature, humidity এবং near-horizon atmospheric layering-এর কারণে প্রকৃত sunrise একেক দিনে conventional computed time থেকে কিছুটা সরে যেতে পারে। U.S. Naval Observatory তাই rise/set time-কে precise observation prediction নয়, standard-condition calculation হিসেবে বোঝায়।
৪৭′, ৫০′ এবং center-at-horizon—তিনটি আলাদা profile
| Profile | Center altitude at event | উপাদান |
|---|---|---|
| Rashtriya Panchang | −৪৭′ ≈ −০.৭৮৩৩° | ৩১′ horizontal refraction + ১৬′ solar semidiameter |
| USNO conventional sunrise/set | প্রায় −৫০′ = −০.৮৩৩৩° | Standard upper-limb/average atmosphere convention |
| Swiss Hindu rising preset | ০° center | Disc center + no refraction + geocentric/no solar ecliptic latitude |
Rashtriya Panchang-এর official explanation upper limb, ৩১′ refraction ও ১৬′ semidiameter ব্যবহার করে এবং ৪৭′-কে প্রায় ৩.৫ মিনিটের সমতুল্য বলে। USNO standard sea-level definition center zenith distance 90.8333°-এর কাছাকাছি convention ব্যবহার করে। দুই standard-এর ৩′ angular difference ছোট হলেও identical time আশা করা উচিত নয়।
Swiss Ephemeris documentation-এ default rise/set upper limb ও refraction-ভিত্তিক। একই documentation Hindu sunrise-এর জন্য SE_BIT_DISC_CENTER এবং SE_BIT_NO_REFRACTION নির্দেশ করে; version 2.06 থেকে SE_BIT_HINDU_RISING preset এই সঙ্গে geocentric/no-ecliptic-latitude flag-ও অন্তর্ভুক্ত করে।
Geometric horizon, astronomical horizon ও visible horizon
| Horizon | অর্থ | সীমাবদ্ধতা |
|---|---|---|
| Geometric horizon | Observer-এর gravity direction-এর perpendicular ideal plane | Terrain ও atmosphere নেই |
| Astronomical/apparent horizon | Standard refraction ও conventional limb সহ calculated crossing | Average atmosphere |
| Visible/local horizon | পাহাড়, গাছ, ভবন বা সমুদ্ররেখায় বাস্তব skyline | Azimuth অনুযায়ী horizon altitude বদলায় |
পূর্বদিকে ৩° উঁচু পাহাড় থাকলে theoretical sunrise-এর সময় Sun ideal horizon-এ উঠলেও চোখে দেখা যাবে না। আবার পশ্চিমে খোলা সমুদ্র থাকলে sunset বাধাহীন দেখা যেতে পারে। তাই local visible horizon ব্যবহার করতে হলে একটি single elevation নয়, azimuth-dependent horizon profile দরকার।
Observer elevation কেন sunrise এগিয়ে দেয়?
Observer sea level-এর ওপরে উঠলে geometric horizon নিচের দিকে dip করে; দূরের horizon দেখা যায়। সাধারণভাবে elevation বাড়লে:
- sunrise আগে দেখা যায়;
- sunset পরে দেখা যায়;
- daylight interval দীর্ঘ হয়।
তবে একটি পাহাড়ের summit elevation আর surrounding terrain একই নয়। GPS elevation দিয়ে open-sea dip correction করা local ridge বা city skyline-এর বাধা দূর করে না। Swiss Ephemeris-এর swe_rise_trans_true_hor() local horizon altitude নেওয়ার ব্যবস্থা দেয়; advanced refraction function observer height, pressure ও temperature-ও গ্রহণ করতে পারে।
Topocentric ও geocentric অবস্থান
Topocentric calculation পৃথিবীর কেন্দ্র নয়, observer-এর actual location থেকে object-এর direction ব্যবহার করে। Sun-এর ক্ষেত্রে parallax ছোট; Moon-এর ক্ষেত্রে অনেক বেশি। তবুও profile reproducibility-এর জন্য এটি স্পষ্ট করা দরকার।
| Reference | Viewpoint | Rise/set-এ ভূমিকা |
|---|---|---|
| Geocentric | Earth center | কিছু Hindu calendar convention |
| Topocentric | Latitude, longitude, elevation-এ observer | Physical local observation-এর natural model |
“Geocentric tithi” এবং “topocentric sunrise” একই daily report-এ থাকা contradiction নয়। Tithi Moon–Sun longitude difference-এর geocentric event; sunrise স্থানীয় horizon event। কেবল প্রতিটির profile আলাদা field-এ প্রকাশ করুন।
একই ৪৭′ correction সর্বত্র একই মিনিট নয়
Sun horizon-কে কত steep angle-এ অতিক্রম করছে তা latitude ও season-এর উপর নির্ভর করে। Equator-এর কাছে crossing তুলনামূলক steep; উচ্চ latitude-এ shallow। ফলে:
- একই angular threshold equator-এর কাছে কয়েক মিনিট;
- উচ্চ latitude-এ আরও বেশি clock-time difference;
- polar circle-এর কাছে ছোট refraction change-ও event আছে/নেই বদলাতে পারে।
তাই “upper limb সবসময় center-এর ঠিক ৩ মিনিট আগে”—এমন hard-coded rule সঠিক নয়। Exact local geometry solve করতে হবে।
Sunrise definition পঞ্জিকার কোন ফল বদলায়?
Sunrise কয়েক মিনিট বদলালে শুধু header-এর সূর্যোদয় নয়, sunrise-state নির্ভর rule-ও বদলাতে পারে:
- তিথি, নক্ষত্র, যোগ ও করণ কোনটি sunrise-এ present;
- তিথি sunrise-এর আগে না পরে শেষ হয়েছে;
- Ekādaśī viddha/śuddha classification;
- Aruṇodaya—sunrise-এর ৯৬ মিনিট আগে—এর anchor;
- sunrise-to-next-sunrise event list;
- বাংলা মাসের প্রথম দিনের sunrise assignment;
- festival ও fast day selection।
কিন্তু geocentric Saṅkrānti instant, তিথি boundary বা planetary longitude sunrise definition-এর কারণে নিজে বদলায় না। বদলাতে পারে কোন local day-এ eventটি assign হবে। Astronomy event time ও calendar assignment আলাদা layer রাখুন।
এই project-এ কোন profile ব্যবহার করা উচিত?
আপনার Surya Siddhanta app-এর বর্তমান research convention হলো Sun center/no-refraction। Historical continuity ও existing festival regression বজায় রাখতে এটিকে silently upper-limb profile-এ বদলানো উচিত নয়। বরং profile presets দিন:
| Preset key | Definition | প্রস্তাবিত ব্যবহার |
|---|---|---|
hindu-center-geometric | Center, no refraction, Hindu/geocentric flags | মূল Panchanga rule ও existing regression |
rashtriya-upper-limb-47 | Upper limb; ৩১′ + ১৬′ | Rashtriya Panchang comparison |
standard-upper-limb | Library default upper limb + standard refraction | Public astronomical sunrise/sunset |
observed-local-horizon | Terrain horizon + met data + elevation | Observational research |
Daily Details-এ primary profile-এর পাশে একটি short label দিন। Settings-এ অন্য profile তুলনার জন্য নির্বাচন করা যেতে পারে, কিন্তু profile পরিবর্তনে calendar results পুনর্গণনা এবং cache invalidation বাধ্যতামূলক।
C# 5-compatible profile model
public enum SolarDiscDefinition
{
UpperLimb,
Center,
LowerLimb
}
public enum SolarRefractionMode
{
Standard,
None,
MeasuredAtmosphere
}
public sealed class SolarRiseSetProfile
{
public string Key { get; set; }
public string Version { get; set; }
public SolarDiscDefinition Disc { get; set; }
public SolarRefractionMode Refraction { get; set; }
public bool UseGeocentricHinduMode { get; set; }
public double PressureHpa { get; set; }
public double TemperatureC { get; set; }
public double ObserverElevationMeters { get; set; }
public double HorizonAltitudeDegrees { get; set; }
}
public sealed class SolarDayEvents
{
public DateTime LocalDate { get; set; }
public DateTimeOffset SunriseUtc { get; set; }
public DateTimeOffset SunsetUtc { get; set; }
public string ProfileKey { get; set; }
public string ProfileVersion { get; set; }
public string TimeZoneId { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
}
Profile Key human-readable identity; Version algorithm/configuration change track করে। Pressure/temperature ব্যবহার না হলে misleading zero না রেখে profile অনুযায়ী default semantics document করুন।
Recommended project preset
static SolarRiseSetProfile HinduCenterGeometric()
{
return new SolarRiseSetProfile
{
Key = "hindu-center-geometric",
Version = "1.0",
Disc = SolarDiscDefinition.Center,
Refraction = SolarRefractionMode.None,
UseGeocentricHinduMode = true,
PressureHpa = 0.0,
TemperatureC = 15.0,
ObserverElevationMeters = 0.0,
HorizonAltitudeDegrees = 0.0
};
}
Swiss Ephemeris rise/set flags
নিচের code flag-selection logic দেখায়। আপনার C# wrapper-এ constant class বা method signature আলাদা হলে নাম adapt করুন:
static int BuildRiseSetMode(
bool isRise,
SolarRiseSetProfile profile)
{
int mode = isRise
? SweConst.SE_CALC_RISE
: SweConst.SE_CALC_SET;
if (profile.UseGeocentricHinduMode)
{
mode |= SweConst.SE_BIT_HINDU_RISING;
return mode;
}
if (profile.Disc == SolarDiscDefinition.Center)
mode |= SweConst.SE_BIT_DISC_CENTER;
else if (profile.Disc == SolarDiscDefinition.LowerLimb)
mode |= SweConst.SE_BIT_DISC_BOTTOM;
if (profile.Refraction == SolarRefractionMode.None)
mode |= SweConst.SE_BIT_NO_REFRACTION;
return mode;
}
Older Swiss Ephemeris wrapper-এ SE_BIT_HINDU_RISING না থাকলে equivalent flags:
mode |= SweConst.SE_BIT_DISC_CENTER;
mode |= SweConst.SE_BIT_NO_REFRACTION;
mode |= SweConst.SE_BIT_GEOCTR_NO_ECL_LAT;
Result validation
public sealed class SolarEventResult
{
public bool Found { get; set; }
public DateTimeOffset InstantUtc { get; set; }
public string Status { get; set; }
public int NativeReturnCode { get; set; }
public string NativeMessage { get; set; }
}
// Native return code indicates no event/error হলে
// DateTime.MinValue বানিয়ে success দেখাবেন না।
Custom altitude solver-এর মূল geometry
Library function ব্যবহার করাই নিরাপদ। Research/debugging-এর জন্য center altitude relation:
cos H₀ = (sin h₀ − sin φ sin δ) ÷ (cos φ cos δ)
যেখানে:
φ= observer latitude;δ= Sun declination;H= local hour angle;h₀= chosen event altitude—০°, −৪৭′, −৫০′ ইত্যাদি।
একবার formula বসিয়ে approximate hour angle পাওয়া যায়, কিন্তু high-accuracy result-এর জন্য Sun position, nutation/apparent coordinates, semidiameter ও refraction trial instant-এ পুনর্গণনা করে root solve করুন।
static double BisectAltitudeCrossing(
double leftJd,
double rightJd,
double targetAltitude,
Func<double, double> apparentAltitudeAt,
double toleranceDays)
{
double leftValue = apparentAltitudeAt(leftJd) - targetAltitude;
double rightValue = apparentAltitudeAt(rightJd) - targetAltitude;
if (leftValue == 0.0) return leftJd;
if (rightValue == 0.0) return rightJd;
if (leftValue * rightValue > 0.0)
throw new ArgumentException("Solar altitude root is not bracketed.");
while (rightJd - leftJd > toleranceDays)
{
double middleJd = (leftJd + rightJd) / 2.0;
double middleValue =
apparentAltitudeAt(middleJd) - targetAltitude;
if (leftValue * middleValue <= 0.0)
{
rightJd = middleJd;
rightValue = middleValue;
}
else
{
leftJd = middleJd;
leftValue = middleValue;
}
}
return (leftJd + rightJd) / 2.0;
}
Rise root-এ altitude increasing, set root-এ decreasing। Search bracket local noon-এর দুই পাশে আলাদা রাখলে wrong crossing এড়ানো যায়। One-day window-এ event না থাকলে polar status দিন; bracket জোর করে বড় করে unrelated date-এর root ধরবেন না।
Time zone ও DST sunrise geometry বদলায় না
Sunrise প্রথমে absolute UT/JD instant হিসেবে solve করুন, তারপর location-এর time-zone rule দিয়ে local time render করুন। DST:
- astronomical crossing বদলায় না;
- wall-clock label এক ঘণ্টা বদলাতে পারে;
- পরের sunrise
sunrise + 24 hoursনয়; - প্রতিটি local civil date-এর event independently solve করতে হবে।
DateTimeOffset localSunrise =
TimeZoneInfo.ConvertTime(sunriseUtc, zone);
DateTimeOffset localSunset =
TimeZoneInfo.ConvertTime(sunsetUtc, zone);
Historic local mean time, wartime DST বা zone-boundary change-এর জন্য modern Windows zone rules যথেষ্ট নাও হতে পারে। Historical profile আলাদা version করুন।
Historical sunrise কতটা নিশ্চিত?
Sun-এর astronomical position বহু পুরোনো date-এ যথেষ্ট নির্ভুলভাবে model করা গেলেও historical “দৃশ্যমান sunrise” পুনর্গঠন কঠিন:
- তৎকালীন pressure/temperature জানা নেই;
- local horizon ও শহরের terrain পরিবর্তিত হতে পারে;
- observer elevation/datum অনিশ্চিত;
- historical civil time/LMT convention আলাদা;
- Julian/Gregorian label আলাদা হলেও instant একই।
সুতরাং historical files-এ “computed conventional sunrise” বলুন; “বাস্তবে চোখে দেখা sunrise exact second” দাবি করবেন না। Profile key, coordinates, JD এবং Julian/Gregorian display policy সঙ্গে export করুন।
Polar day, polar night এবং shallow crossing
Hour-angle equation-এর right side [-1, +1]-এর বাইরে গেলে chosen altitude threshold-এ crossing নেই। এটি calculation failure নয়; ঐ date/location/profile-এ Sun rise বা set করে না।
High latitude-এ refraction variability event status-ও বদলাতে পারে। USNO উল্লেখ করে যে Sun horizon বরাবর shallow চললে refraction expected sunrise delay করতে বা কখনো apparent event তৈরি/বিলুপ্ত করতে পারে। UI-তে:
status = "NoSunrise";
status = "NoSunset";
status = "SunAboveThresholdAllDay";
status = "SunBelowThresholdAllDay";
Midnight fallback বা আগের দিনের time repeat করা উচিত নয়। Panchanga day-এর জন্য high-latitude policy প্রয়োজন হলে সেটি আলাদা ধর্মীয়/calendar policy—astronomy result নয়।
API ও XML-এ profile প্রকাশ
{
"date": "2026-10-09",
"location": {
"name": "Dhaka",
"latitude": 23.8103,
"longitude": 90.4125,
"elevationMeters": 4.0,
"timeZoneId": "Bangladesh Standard Time"
},
"sunrise": "2026-10-09T05:54:43+06:00",
"sunset": "2026-10-09T17:39:18+06:00",
"profile": {
"key": "hindu-center-geometric",
"version": "1.0",
"disc": "center",
"refraction": "none",
"horizonAltitudeDegrees": 0.0,
"engine": "Swiss Ephemeris"
}
}
উপরের সময়গুলো format example, certified test vector নয়। XML:
<solar-events date="2026-10-09"
timezone="Bangladesh Standard Time"
latitude="23.8103"
longitude="90.4125">
<profile key="hindu-center-geometric" version="1.0"
disc="center" refraction="none"
horizon-degrees="0" />
<sunrise local="2026-10-09T05:54:43+06:00" />
<sunset local="2026-10-09T17:39:18+06:00" />
</solar-events>
Print report-এ full metadata না চাইলে footnote যথেষ্ট: “সূর্যোদয়–সূর্যাস্ত: Sun center, geometric horizon, refraction excluded।” Machine-readable output-এ full profile রাখুন।
সাধারণ implementation error
| ভুল | ফল | সংশোধন |
|---|---|---|
| সব sunrise definition identical ধরা | কয়েক মিনিট mismatch | Disc/refraction profile compare |
| Upper limb কিন্তু semidiameter বাদ | Center time পাওয়া | Library default বা explicit threshold |
| No-refraction flag ভুলে যাওয়া | Hindu center result আগে/পরে সরে | Final flags diagnostic-এ রাখুন |
| Hindu preset + default limb mix | অসংজ্ঞায়িত hybrid | Atomic preset |
| Elevation মানেই terrain correction | Mountain/city skyline ভুল | Azimuth horizon profile |
| ৪৭′ = সর্বত্র ৩.৫ মিনিট hard-code | Latitude/season error | Exact crossing solve |
| Historical atmosphere exact দাবি | False precision | Conventional profile label |
| UTC offset sunrise solver-এ যোগ | Astronomy/time-zone mixing | UT solve, পরে local render |
| Next sunrise +24h | DST ও seasonal error | Next date independently solve |
| No event-এ DateTime.MinValue | Year 1/out-of-range exception | Explicit status result |
Validation checklist
- Same date/location-এ upper-limb sunrise center-এর আগে;
- Same date/location-এ upper-limb sunset center-এর পরে;
- Refraction-on sunrise no-refraction-এর আগে;
- Refraction-on sunset no-refraction-এর পরে;
- Rashtriya threshold −৪৭′;
- USNO conventional threshold প্রায় −৫০′;
- Hindu center threshold ০°;
SE_BIT_HINDU_RISINGpreset test;- Equivalent three-flag fallback test;
- Default Swiss upper-limb/refraction test;
- Disc-bottom flag separate test;
- Sea-level open horizon;
- Positive observer elevation;
- Positive eastern terrain horizon delays sunrise;
- Positive western terrain horizon advances sunset disappearance;
- Pressure change refraction path;
- Temperature change refraction path;
- Pressure zero/default semantics documented;
- Dhaka regression date;
- Kolkata regression date;
- New York summer date;
- New York winter date;
- Equator equinox test;
- Mid-latitude solstice test;
- High-latitude shallow crossing;
- Polar no-sunrise status;
- Polar no-sunset status;
- Rise root increasing;
- Set root decreasing;
- Morning/evening bracket isolation;
- Root tolerance one second বা configured precision;
- Native negative return code handled;
- No DateTime.MinValue fallback;
- UT result before zone conversion;
- DST spring transition;
- DST fall transition;
- Next sunrise independently solved;
- Sunrise profile cache key-তে;
- Profile version cache invalidation;
- Daily HTML/API/XML same instant;
- Printed report footnote matches profile;
- Near-sunrise tithi boundary regression;
- Ekādaśī decision profile regression;
- Arunodaya derived from chosen sunrise;
- Historical JD retained;
- Julian/Gregorian display same instant;
- Observed printed Panchanga uses matching definition;
- Seconds displayed with uncertainty note;
- Coordinate/elevation/zone mismatch rejected;
- Swiss Ephemeris version recorded।
উপসংহার
সূর্যোদয় ও সূর্যাস্তের সময় শুধু Sun-এর longitude থেকে আসে না; local horizon crossing-এর definition দরকার। Upper limb না center, refraction আছে কি না, observer height, terrain horizon, topocentric/geocentric choice এবং atmospheric assumptions—সবই ফল বদলাতে পারে।
Rashtriya Panchang upper limb-এর জন্য ৩১′ refraction ও ১৬′ semidiameter—মোট ৪৭′—ব্যবহার করে। Swiss Ephemeris Hindu preset center-at-horizon, no-refraction এবং geocentric convention ব্যবহার করে। তাই একই location-এ কয়েক মিনিটের difference expected; profile একই না হলে একটিকে অন্যটির error বলা যায় না।
এই project-এর existing hindu-center-geometric rule বজায় রেখে optional comparison profiles দিন। প্রতিটি report ও export-এ profile key/version প্রকাশ, event time UT-তে solve, local time পরে render, এবং near-boundary festival regression test করলে পঞ্জিকার ফল ব্যাখ্যাযোগ্য ও পুনরুৎপাদনযোগ্য থাকবে।
তথ্যসূত্র ও আরও পাঠ
- Positional Astronomy Centre—Rashtriya Panchang Explanation; upper limb, ৩১′ refraction, ১৬′ semidiameter ও sunrise-to-next-sunrise convention.
- Swiss Ephemeris Programmer’s Documentation;
swe_rise_trans, disc-center/no-refraction এবং Hindu rising flags. - Swiss Ephemeris Programming Interface; true-horizon এবং pressure/temperature-dependent refraction functions.
- U.S. Naval Observatory—Rise, Set and Twilight Definitions; upper-limb convention, standard atmosphere ও observational uncertainty.
- U.S. Naval Observatory—Computing Times of Rise, Set, and Twilight; rise/set algorithm background.
- U.S. Naval Observatory—First Sunrise of the New Year; high-latitude refraction ও elevation effects.
- সূর্য সিদ্ধান্ত পঞ্জিকা project specification; Sun center/no-refraction primary profile, location-specific sunrise এবং daily Panchanga assignment.
মন্তব্য, আলোচনা ও প্রশ্ন