Multi-location Panjika-র সবচেয়ে নিরাপদ নীতি হলো “calculate an instant, then display it locally”—কিন্তু সব বিষয় geocentric instant নয়। Tithi boundary বা saṅkrānti-র মূল astronomical root UTC/JD-তে এক হতে পারে; local sunrise, lagna ও horizon event আবার latitude–longitude দিয়ে নতুন করে গণনা করতে হয়। Timezone শুধু ফলের ঘড়ির label ও civil-date context দেয়।
সময়ের তিনটি স্তর আলাদা রাখুন
| স্তর | উদাহরণ | ব্যবহার |
|---|---|---|
| Astronomical instant | Julian Day UT বা UTC | Root solving, event ordering, cache identity |
| Geographic location | Latitude, longitude, elevation | Sunrise, sunset, lagna, moonrise, visibility |
| Civil time rule | Time Zone ID, offset, DST | Local clock, date, weekday ও display |
শুধু UTC+05:30 দিলে কলকাতার coordinates জানা যায় না; তাই sunrise বের করা যায় না। আবার শুধু ২২°৩৫′N, ৮৮°২১′E দিলে ২০২৬ সালের civil clock IST না অন্য convention—তা জানা যায় না। Location profile-এ দুটোই থাকতে হবে।
একই instant, কলকাতা–ঢাকা–নিউ ইয়র্কে তিন সময়
একটি unambiguous instant ধরা যাক:
| স্থান | Zone rule | Local time | Offset |
|---|---|---|---|
| কলকাতা | India Standard Time | ১ জুলাই, ৫:৩০ PM | +05:30 |
| ঢাকা | Bangladesh Standard Time | ১ জুলাই, ৬:০০ PM | +06:00 |
| নিউ ইয়র্ক | Eastern Daylight Time | ১ জুলাই, ৮:০০ AM | −04:00 |
একই New York zone-এ ১ জানুয়ারি ২০২৬, 12:00 UTC হলে local time ৭:০০ AM এবং offset −05:00, কারণ তখন standard time। তাই “New York = UTC−5” hard-code করলে গ্রীষ্মের ফল এক ঘণ্টা ভুল হবে।
আরেকটি instant UTC midnight-এর কাছে হলে local civil date ভিন্ন হতে পারে। উদাহরণস্বরূপ 18:30 UTC কলকাতায় পরদিন 00:00, ঢাকায় 00:30, কিন্তু New York-এ তখনও আগের বিকেল। Event instant এক, date label তিন রকম।
Longitude ও দেশান্তর: প্রতি ডিগ্রিতে চার মিনিট
পৃথিবী ২৪ ঘণ্টায় প্রায় ৩৬০° ঘোরে। তাই mean solar time-এর সরল longitude relation:
১° longitude = ৪ মিনিট
Local Mean Time ≈ UTC + longitude ÷ ১৫
পূর্ব longitude positive এবং পশ্চিম negative ধরলে illustrative মান:
| স্থান | প্রায় longitude | Longitude-derived mean offset | Modern civil offset |
|---|---|---|---|
| কলকাতা | ৮৮°২১′ E | প্রায় +05:53:24 | +05:30 |
| ঢাকা | ৯০.৪১২৫° E | প্রায় +06:01:39 | +06:00 |
| নিউ ইয়র্ক | ৭৪.০০৬° W | প্রায় −04:56:01 | −05:00 বা −04:00 |
এগুলো local mean solar offset-এর গাণিতিক illustration; বর্তমান আইনগত timezone নয়। দেশান্তর correction বলতে reference meridian থেকে longitude difference-এর সময়সমতুল্য বোঝানো হয়:
স্থান reference-এর পূর্বে হলে correction positive, পশ্চিমে হলে negative—যদি reference mean time থেকে local mean time-এ যান। বিপরীত conversion-এ sign উল্টো হবে। Code-এ method name-এই direction লিখুন, যেমন ReferenceMeanToLocalMean।
Local mean solar time, apparent solar time ও civil time এক নয়
| সময় | ভিত্তি | পঞ্জিকায় ভূমিকা |
|---|---|---|
| Local Mean Solar Time | Longitude-এর uniform mean Sun | Historical longitude correction ও research |
| Local Apparent Solar Time | প্রকৃত apparent Sun; equation of time যুক্ত | Sun-dial ধরনের সময়; civil clock নয় |
| Standard Civil Time | আইনগত zone meridian ও DST rules | User-facing clock ও date |
| UTC/UT | Global reference timescale | Astronomical instant ও data exchange |
Longitude/১৫ যোগ করলেই apparent solar time পাওয়া যায় না; equation of time দরকার। আবার apparent noon সবসময় wall-clock ১২টা নয়। Sunrise engine যখন latitude, longitude, altitude/refraction ও solar coordinates ব্যবহার করছে, তখন তার ওপর আরেকবার hand-written দেশান্তর যোগ করলে double correction হতে পারে।
কোন গণনা স্থাননির্ভর?
| বিষয় | মূল event | Location-এর প্রভাব |
|---|---|---|
| তিথি/নক্ষত্র/যোগ/করণ boundary | সাধারণত geocentric longitude root | Local clock ও sunrise assignment বদলায় |
| সংক্রান্তি | সূর্যের নির্দিষ্ট rāśi ingress | Local time/date এবং Bengali month-start rule বদলাতে পারে |
| Sunrise/sunset | Horizon event | Latitude, longitude, elevation ও atmospheric convention অপরিহার্য |
| Moonrise/moonset | Horizon event | Coordinates ও lunar parallax-এর বড় প্রভাব |
| Lagna/Bhava | Local horizon ও meridian | Time, latitude ও longitude অপরিহার্য |
| Eclipse | Global astronomical event | Visibility, contact time ও altitude location-specific |
| Festival/fast | Rule evaluation | Local sunrise, aruṇodaya, midnight বা pradoṣa দরকার |
| Dynamic Hijri | Crescent/visibility rule | Local sunset, coordinates ও atmosphere দরকার |
Planetary geocentric longitude একই UTC instant-এ location বদলালে সাধারণত বদলায় না; topocentric mode চাইলে observer coordinates লাগে, বিশেষত চন্দ্রের ক্ষেত্রে পার্থক্য গুরুত্বপূর্ণ হতে পারে। Result metadata-তে geocentric না topocentric তা লিখুন।
সংক্রান্তি একই instant, বাংলা মাসের প্রথম দিন ভিন্ন হতে পারে
ধরা যাক Mesha Saṅkrānti একটি UTC instant-এ ঘটল। তিন city-তে:
- Local clock time আলাদা;
- কোথাও midnight-এর আগে, কোথাও পরে পড়তে পারে;
- প্রতিটি স্থানের sunrise ও next sunrise আলাদা;
- Bagchi/Traditional month-start rule local sunrise–midnight relation দেখে;
- ফলে Bengali month-এর civil starting date location অনুযায়ী এক দিন আলাদা হতে পারে।
এ কারণে saṅkrānti table-এ একটিই authoritative instantUtc রাখা যায়, কিন্তু Bengali date assignment location profile অনুযায়ী পুনর্গণনা করতে হবে। Kolkata-র generated calendar-কে শুধু clock offset বদলে Dhaka বা New York calendar বানানো যাবে না।
UTC offset আর Time Zone এক নয়
+05:30 একটি offset—নির্দিষ্ট instant-এ UTC থেকে পার্থক্য। India Standard Time একটি zone rule set। New York-এর ক্ষেত্রে একটি zone বছরের ভেতর −05:00 ও −04:00 দুটো offset ব্যবহার করে। একই offset আবার পৃথিবীর বহু zone share করতে পারে।
তাই event record-এ রাখুন:
- UTC instant;
- Local offset at that instant;
- Time Zone ID;
- Location ID ও coordinates;
- Timezone-data version বা platform;
- Historical override policy, যদি থাকে।
DateTimeOffset instant + offset unambiguously ধরে, কিন্তু zone-এর identity ও future/historical transition rules নিজে ধরে না। তাই recurring বা পুনর্গণনাযোগ্য data-তে zone ID আলাদাভাবে সংরক্ষণ করুন।
Windows ও IANA Time Zone ID
ASP.NET Web Forms/.NET Framework Windows server-এ Windows ID ব্যবহার করে। Cross-platform API বা JavaScript ecosystem সাধারণত IANA ID ব্যবহার করে। Location profile-এ দুটো mapping রাখা যায়:
| স্থান | Windows ID | IANA ID |
|---|---|---|
| কলকাতা | India Standard Time | Asia/Kolkata |
| ঢাকা | Bangladesh Standard Time | Asia/Dhaka |
| নিউ ইয়র্ক | Eastern Standard Time | America/New_York |
Windows ID-এর “Standard” শব্দ দেখে ভাববেন না যে DST বন্ধ থাকবে। Eastern Standard Time zone-এর adjustment rules summer-এ daylight offset প্রয়োগ করে। Fixed UTC−05:00 zone চাইলে সেটি আলাদা policy।
Server deployment-এর আগে TimeZoneInfo.GetSystemTimeZones() দিয়ে target machine-এ ID আছে কি না test করুন। Windows update ও tzdb update রাজনৈতিক rule change বহন করতে পারে; long-lived cache-এ timezone-data version রাখা ভালো।
DST: invalid এবং ambiguous local input
New York spring-forward-এ কিছু local time কখনো ঘটে না। Fall-back-এ কিছু local time দুবার ঘটে।
| অবস্থা | কি ঘটে | Application response |
|---|---|---|
| Invalid time | Clock forward jump-এর gap; যেমন ২:৩০ নেই | Input reject করে নিকটবর্তী valid time বুঝিয়ে দিন |
| Ambiguous time | Clock backward jump; যেমন ১:৩০ দুইবার | User-কে −04:00/−05:00 offset বেছে নিতে দিন |
| Unambiguous time | একটি UTC instant | Zone offset নিয়ে UTC-তে convert করুন |
বর্তমান U.S. rule-এ DST March-এর দ্বিতীয় Sunday ২ AM-এ শুরু এবং November-এর প্রথম Sunday ২ AM-এ শেষ। কিন্তু future আইন বদলাতে পারে; hard-coded Sunday rule নয়, installed timezone database ব্যবহার করুন।
৫৯৪ খ্রিস্টাব্দে কোন Time Zone?
Modern standardized zone ও DST প্রাচীন যুগে ছিল না। Bengali Year 1 বা ৫৯৪ খ্রিস্টাব্দের জন্য “India Standard Time” retroactively বসালে তা একটি modern display convention, historical clock fact নয়। তিনটি policy আলাদা:
| Policy | অর্থ | কখন ব্যবহার |
|---|---|---|
| Modern-zone projection | বর্তমান standard offset অতীতে প্রয়োগ | Modern reader-এর সহজ comparison; স্পষ্ট label দরকার |
| Local Mean Time | Longitude/১৫ দ্বারা mean solar offset | Historical astronomical reconstruction |
| Declared fixed research offset | Project-defined offset | Reproducible batch export ও legacy comparison |
IANA tz database pre-standard time-কে প্রায়ই local mean time হিসেবে model করে, কিন্তু তার documentation-ও সতর্ক করে যে historical societies অন্য calendar ও timescale ব্যবহার করেছে। Windows TimeZoneInfo-র ancient-year behavior platform data অনুযায়ী হতে পারে; ৫৯৪ সালের সত্য ধরে নেবেন না।
Historical HTML-এ লিখুন:
Time convention: Kolkata Local Mean Time (longitude 88°21′E)
Civil date display: Julian / proleptic Gregorian dual label
Astronomical scale: Julian Day UT
Modern-zone clock: not asserted
Timezone policy বদলালে astronomical JD root বদলাবে না, কিন্তু local clock, midnight boundary এবং কখনো sunrise-date label বদলাতে পারে। Research files-এ policy version তাই calculation profile-এর অংশ।
একটি নিরাপদ calculation architecture
- User-এর location profile resolve করুন;
- Input civil date/time selected zone-এ validate করুন;
- Unambiguous UTC/Julian Day তৈরি করুন;
- Geocentric transitions UTC/JD-তে solve করুন;
- Sunrise, moonrise, lagna ও visibility coordinates দিয়ে solve করুন;
- সব event UTC instant অনুযায়ী sort করুন;
- প্রতিটি event selected zone-এ localize করুন;
- Local sunrise-window-এ event assign করুন;
- Bengali date ও festival rules location অনুযায়ী চালান;
- একই structured result থেকে HTML, print, API ও XML render করুন।
Cache layers আলাদা হতে পারে। Geocentric saṅkrānti root calculation profile ও year দিয়ে cache; local presentation city/timezone দিয়ে cache; final Bengali calendar location, rule profile ও timezone policy দিয়ে cache। Location বাদ দিলে cross-city cache pollution হবে।
C# 5/.NET Framework-compatible code
public sealed class LocationProfile
{
public string Id { get; set; }
public string BengaliName { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public string WindowsTimeZoneId { get; set; }
public string IanaTimeZoneId { get; set; }
}
static readonly LocationProfile Kolkata = new LocationProfile
{
Id = "kolkata",
BengaliName = "কলকাতা (ভারত)",
Latitude = 22.5833,
Longitude = 88.3500,
WindowsTimeZoneId = "India Standard Time",
IanaTimeZoneId = "Asia/Kolkata"
};
static readonly LocationProfile Dhaka = new LocationProfile
{
Id = "dhaka",
BengaliName = "ঢাকা (বাংলাদেশ)",
Latitude = 23.8103,
Longitude = 90.4125,
WindowsTimeZoneId = "Bangladesh Standard Time",
IanaTimeZoneId = "Asia/Dhaka"
};
static readonly LocationProfile NewYork = new LocationProfile
{
Id = "new-york",
BengaliName = "নিউ ইয়র্ক (যুক্তরাষ্ট্র)",
Latitude = 40.7128,
Longitude = -74.0060,
WindowsTimeZoneId = "Eastern Standard Time",
IanaTimeZoneId = "America/New_York"
};
UTC instant থেকে local display:
public static DateTimeOffset ToLocal(
DateTimeOffset instantUtc,
LocationProfile location)
{
TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById(
location.WindowsTimeZoneId);
return TimeZoneInfo.ConvertTime(
instantUtc.ToUniversalTime(), zone);
}
User-এর local input থেকে UTC করার আগে DST validation:
public static DateTimeOffset LocalInputToUtc(
DateTime localInput,
LocationProfile location,
TimeSpan? chosenAmbiguousOffset)
{
TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById(
location.WindowsTimeZoneId);
DateTime wall = DateTime.SpecifyKind(
localInput, DateTimeKind.Unspecified);
if (zone.IsInvalidTime(wall))
throw new ArgumentException(
"এই স্থানীয় সময়টি DST clock-change-এর কারণে বিদ্যমান নয়।");
if (zone.IsAmbiguousTime(wall))
{
TimeSpan[] offsets = zone.GetAmbiguousTimeOffsets(wall);
if (!chosenAmbiguousOffset.HasValue
|| Array.IndexOf(offsets, chosenAmbiguousOffset.Value) < 0)
throw new ArgumentException(
"সময়টি দুইবার ঘটে; UTC offset নির্বাচন করুন।");
return new DateTimeOffset(
wall, chosenAmbiguousOffset.Value).ToUniversalTime();
}
TimeSpan offset = zone.GetUtcOffset(wall);
return new DateTimeOffset(wall, offset).ToUniversalTime();
}
Longitude-derived mean offset research helper:
public static TimeSpan LongitudeMeanOffset(double longitudeEast)
{
if (longitudeEast < -180.0 || longitudeEast > 180.0)
throw new ArgumentOutOfRangeException("longitudeEast");
double seconds = longitudeEast * 240.0; // 4 minutes per degree
return TimeSpan.FromSeconds(seconds);
}
এই helper modern timezone conversion-এর বিকল্প নয়। Historical policy explicitভাবে LocalMeanTime নির্বাচন করলেই এটি ব্যবহার করুন।
Production routes: /, /bd ও /ny
তিনটি route redirect না করে location-aware landing page হিসেবে রাখা smooth transition-এর জন্য ভালো:
| Route | Default location | Default zone |
|---|---|---|
ponjika.com/ | কলকাতা | India Standard Time |
ponjika.com/bd | ঢাকা | Bangladesh Standard Time |
ponjika.com/ny | নিউ ইয়র্ক | Eastern Standard Time |
সব route একই calculation service, page template ও URL parameter ব্যবহার করবে; পার্থক্য শুধু initial LocationProfile। User location বদলালে cookie/local preference route default-কে override করতে পারে, কিন্তু page header-এ সক্রিয় city ও timezone সবসময় দেখান।
Search indexing-এর জন্য প্রতিটি regional landing page-এ unique introductory content ও সঠিক self-canonical রাখা যায়। Calculation result URL-এ explicit location=dhaka বা stable location ID থাকলে shared link reproducible হবে।
API response-এ location ও time metadata
{
"location": {
"id": "new-york",
"name": "New York, USA",
"latitude": 40.7128,
"longitude": -74.0060,
"timeZone": {
"windowsId": "Eastern Standard Time",
"ianaId": "America/New_York"
}
},
"event": {
"kind": "sankranti",
"julianDayUt": 2460000.123456,
"instantUtc": "2026-07-01T12:00:00Z",
"localTime": "2026-07-01T08:00:00-04:00",
"offset": "-04:00",
"isDaylightSavingTime": true
},
"calculation": {
"positionFrame": "geocentric",
"historicalTimePolicy": "system-time-zone",
"calendarLabel": "Gregorian"
}
}
উদাহরণের JD placeholder; production serializer instant-এর actual JD লিখবে। API consumer যেন localTime থেকে zone identity অনুমান না করে—zone IDs আলাদা fields-এ আছে। Historical output-এ historicalTimePolicy হবে local-mean-time, fixed-research-offset বা declared projection।
Validation checklist
- এক UTC instant তিন city-তে তিন local time;
- Kolkata offset +05:30;
- Dhaka offset +06:00;
- New York summer offset −04:00;
- New York winter offset −05:00;
- UTC round-trip original instant ফেরায়;
- Offset এবং zone ID আলাদা fields;
- Coordinates ছাড়া sunrise calculation reject;
- Timezone ছাড়া local clock display reject;
- East longitude positive, west negative;
- ১° longitude = ২৪০ seconds;
- Kolkata 88°21′E mean offset প্রায় +05:53:24;
- Dhaka 90.4125°E mean offset প্রায় +06:01:39;
- New York −74.006° mean offset প্রায় −04:56:01;
- Modern zone ও local mean time mix হয় না;
- Engine-applied longitude-এর পরে double correction নেই;
- Spring-forward invalid input rejected;
- Fall-back ambiguous input offset choice চায়;
- Saṅkrānti UTC root shared হলেও local date পুনর্গণিত;
- Bengali month-start local sunrise দিয়ে;
- Moonrise/moonset প্রতি location-এ পুনর্গণিত;
- Lagna coordinates ও local instant ব্যবহার করে;
- Eclipse global event ও local visibility পৃথক;
- Hijri dynamic method local sunset ব্যবহার করে;
- ৫৯৪ AD result-এ historical time policy declared;
- Julian/Gregorian label timezone policy থেকে পৃথক;
- Windows server-এ তিন zone ID পাওয়া যায়;
- Cache key-তে location, zone ও calculation profile;
/,/bd,/nyসঠিক defaults;- User-selected city route default override করে;
- Page header সক্রিয় city/timezone দেখায়;
- HTML, API, XML একই localized instant ব্যবহার করে।
উপসংহার
একই astronomical event-এর তিনটি আলাদা প্রশ্ন আছে: ঘটনাটি বিশ্বসময়ে কখন, observer কোথায়, এবং সেই স্থানে civil clock কী দেখায়। UTC/JD প্রথমটির উত্তর, latitude–longitude দ্বিতীয়টির, আর timezone rule তৃতীয়টির। তিনটি একসঙ্গে না রাখলে multi-location Panjika নির্ভরযোগ্য হয় না।
তিথি বা saṅkrānti boundary geocentric root হিসেবে shared হতে পারে, কিন্তু local clock, sunrise-day assignment, Bengali month start ও festival date পুনর্গণনা করতে হবে। Sunrise, moonrise, lagna, eclipse visibility এবং crescent visibility সরাসরি location-dependent। তাই কলকাতার HTML-এ শুধু offset বদলে ঢাকা বা New York calendar তৈরি করা যাবে না।
বর্তমান ব্যবহারে authoritative instant UTC-তে, display TimeZoneInfo-তে এবং location একটি stable profile-এ থাকবে। প্রাচীন বছরে modern timezone-কে historical fact হিসেবে না দেখিয়ে local mean time বা declared research offset ব্যবহার করুন। এই separation বজায় রাখলে /, /bd ও /ny একই engine ভাগ করেও প্রত্যেক user-কে সঠিক স্থানীয় পঞ্জিকা দিতে পারবে।
তথ্যসূত্র ও আরও পাঠ
- IANA Time Zone Database; local time-এর historical offset ও daylight-saving rules.
- IANA—Theory and pragmatics of the tz code and data; pre-standard local mean time, proleptic Gregorian model ও historical limitations.
- Microsoft Learn—TimeZoneInfo Class; timezone conversion, ambiguous ও invalid local times.
- Microsoft Learn—DateTimeOffset Struct; instant ও offset representation এবং zone identity-এর সীমা.
- Microsoft—Default Time Zones; India, Bangladesh ও Eastern Windows zone IDs.
- NIST—Daylight Saving Time Rules; current U.S. DST transition rules.
- Astrodienst—Swiss Ephemeris Programmer’s Documentation; geocentric/topocentric calculation ও geographic position.
- সূর্য সিদ্ধান্ত পঞ্জিকা project; Kolkata, Dhaka ও New York profiles, Traditional Fit, sunrise-window এবং production route conventions.
মন্তব্য, আলোচনা ও প্রশ্ন