Skip to content
Documentation · all sections

Upgrading 5.3 → 5.4

panchang · v5.4.0 · MIT

No signature changes and nothing removed, but many values move: festival days that follow the reference almanac, the new holika_dahan and karthigai_deepam keys, the five-level Yoni koota, the new Brahma Muhurta window, day values west of UTC and the Odisha new year. Plus one new call, computeVimshottariPratyantarIn.

This page covers the npm package and the Go module. They move together: the Go module carries every change below with the same instants, days, festivals and labels.

Nothing breaks at compile time. 5.4.0 removes, renames and retypes no exports, and no signature changes. One export and two festival keys are added, and the Go module adds a few more calls (listed under Go, below). What changes is output. Festival days follow the reference almanac's day rules, holi moves to the day after the new holika_dahan, the Yoni koota scores on a corrected table, Brahma Muhurta gets a new window, day-valued dates west of UTC stop reading a day early, and a long list of edge cases in the daily panchang and the Jyotish layer now return the right value.

So there is no type diff to walk, and the compiler will flag none of this. Most of what follows is a stored-value problem: re-run anything you cached, and re-pin anything you snapshotted. The exception is input that 5.3 accepted and 5.4 now rejects with an error: a two-digit year (see Listings and the calendar), an Invalid Date, a fractional UTC offset and the other cases under Input validation.

Festival days follow the reference almanac

Every festival rule below was checked against published dates: the reference almanac first, then other almanacs, with the classical rule (Nirnaya Sindhu, Dharma Sindhu) as the tie-breaker. The dates relied on are pinned in the library's test data. Before, most once-a-year festivals were listed on two consecutive days in some years. Now, over five cities and 1900 to 2100, no once-a-year festival is listed twice in a year, and each monthly one fires at most once per paksha or month. The one exception is phagli, whose rule is deferred (below). A few years still list a festival on no day, as 5.3 did. At Delhi these are Krishna Janmashtami in 1963 and 2088, and Maha Shivaratri and Vasant Panchami in 1983.

Festival or ruleNowExample, 5.3.0 → 5.4.0 (Delhi unless named)
A tithi current at two sunrises (vriddhi)The first day, as the reference publishes. The Tritiya vratas (Hariyali, Kajari and Hartalika Teej, Gangaur) and Jagannath Rath Yatra take the second. Ugadi, Gudi Padwa, Hanuman Jayanti, Navaratri, Durga Ashtami, Guru, Sharad, Kartika and Vat Savitri Purnima, Mahalaya Amavasya and others lose their second-day duplicate.Anant Chaturdashi 2018: 23 and 24 Sep → 23 Sep. Navaratri (Ghatasthapana) 2015: 13 and 14 Oct → 13 Oct. Hanuman Jayanti 1962: 19 and 20 Apr → 19 Apr. Hartalika Teej 2006: 26 and 27 Aug → 27 Aug.
Festivals chosen by a kalaChosen from the tithi's exact span against the reference's windows, described below the table.Vinayaka Chaturthi, December 2025: 23 and 24 → 24. Dussehra 2019: 7 Oct → 8 Oct.
Raksha Bandhan, Yajur Upakarma, Nag Panchami, Akshaya TritiyaThe first sunrise day on which the tithi lasts at least 3 muhurtas, else the day it begins.Akshaya Tritiya 2020: 25 and 26 Apr → 26 Apr. Raksha Bandhan 2023: 31 Aug → 30 Aug.
Pradosh vratThe day whose pradosha window (sunset to sunset plus a fifth of the night) overlaps Trayodashi most. At Delhi it reproduces every reference date for 2025 and 2027.2025: 23 dates → 24. Ravi Pradosh on 9 Feb was missing. 2027: 4 and 5 Jan → 5 Jan, and 3 May was missing.
ChhathAnchored on the Shashthi sunrise day. Nahay Khay, Kharna and Usha Arghya fall two days before, one day before and one day after it.Usha Arghya 2025: 29 Oct → 28 Oct.
Maha NavamiThe first day whose sunset less two muhurtas follows the start of Navami. It can now share a day with Durga Ashtami.2015: 22 Oct → 21 Oct. 2027: 9 Oct → 8 Oct.
Saddula BathukammaMoves to Durgashtami.2025: 1 Oct → 30 Sep.
VaramahalakshmiThe Friday in the 7 days ending on the Shravana Purnima sunrise day.2025: 1 and 8 Aug → 8 Aug.
Masik KarthigaiOne day per Krittika transit: the first day Krittika holds at sunset, else at sunrise.Chennai 2025: 22 dates → 13, plus Karthigai Deepam on 4 Dec. In 5.3 about three transits in four fired on two consecutive days.
OnamExactly one day a year: the Thiruvonam of Chingam, the first of two Chingam sunrises, the day holding it when it holds no sunrise, and the later of two Thiruvonams in one Chingam.Kochi 2024: 19 Aug and 15 Sep → 15 Sep. Kochi 2013: 20 Aug and 16 Sep → 16 Sep.
Shravan Somvar, Mangala Gauri, Kartik Somvar, Magha ShanivarCount their month in your masaSystem. See the note below.Shravan Somvar 2025: 28 Jul, 4, 11 and 18 Aug → 14, 21 and 28 Jul, 4 Aug.

The kala windows are the reference's. Madhyahna is the third fifth of the daytime and aparahna the fourth. Pradosha runs from sunset to sunset plus a fifth of the night. Nishita is the 8th of the 15 night muhurtas. The day whose window the tithi covers most decides Ganesh and Vinayaka Chaturthi (madhyahna), Dhanteras, Diwali and Parashurama Jayanti (pradosha) and Govardhan Puja (the whole daytime), the earlier day winning a tie or when both days' windows are full. Masik and Maha Shivaratri follow the reference's nishita ladder, and Dussehra its aparahna ladder with the Shravana rule. Rama Navami (madhyahna), Bhai Dooj and Vat Savitri Amavasya (aparahna) take the last day whose window the tithi touches. Narak Chaturdashi takes the first day whose arunodaya it touches, and Vasant Panchami the first day on which Panchami has begun by two fifths of the daytime.

Three of the four festivals that 5.2 left keyed on sunrise now have anchors of their own: holi (below), narak_chaturdashi at arunodaya, and chhath_usha_arghya one day after the Shashthi day. Only phagli still takes every day whose sunrise holds Purnima: two days in 2033 at Delhi, and none in 2018. That rule is deferred for lack of a reference capture, together with a Pradosh fallback (a paksha whose Trayodashi touches no pradosha window has no Pradosh) and the Guru Purnima short-udaya refinement.

The net effect on one listing: computeFestivalsForYear(2026, delhi, { timezone: 330 }) returns 253 entries, against 260 on 5.3.0.

Two new festival keys

KeyenhiRegionsMarks
holika_dahanHolika Dahanहोलिका दहनevery regionThe Holika Dahan evening, chosen by the reference's Bhadra ladder on Phalguna Purnima.
karthigai_deepamKarthigai Deepamकार्तिकै दीपम्all, tamil-naduThe Karthigai-month Krittika day nearest the full moon.

Both are type 'major'. FestivalInfo.key is typed string, so these are new values, not new type members. No key is removed or renamed. Tables you build with buildFestivalsTable pick up holika_dahan, and karthigai_deepam when built for all or tamil-nadu.

karthigai_deepam takes over a Masik Karthigai day. On that day, regions all and tamil-nadu list karthigai_deepam in place of masik_karthigai, and every other region still lists masik_karthigai. At Chennai on 4 December 2025, region 'tamil-nadu' gives karthigai_deepam and region 'kerala' gives masik_karthigai. So a table built for 'all' and filtered by region afterwards loses that month's Masik Karthigai outside Tamil Nadu. Build one table per region if you filter.

Holi is now the day after Holika Dahan

holi keeps its key and its name, but it now means Rangwali Holi, the day of colours. It is always the civil day after holika_dahan, which is how the reference publishes it. In 5.3 holi was the Purnima sunrise day: both days when Purnima held two sunrises, and none when it held no sunrise.

computeFestivalsForYear(2026, delhi, { timezone: 330 })
- 2026-03-03  holi
+ 2026-03-03  holika_dahan
+ 2026-03-04  holi

In a year when Purnima holds the Rangwali sunrise, holi keeps its date: in 2025 holika_dahan is 13 March and holi is 14 March, as before. In 2018, a kshaya Purnima year, 5.3 had no holi at all. 5.4 gives holika_dahan on 1 March and holi on 2 March.

If you read the Purnima evening, the bonfire, from holi, read it from holika_dahan now. No other key's date is tied to holi, and phagli is unchanged.

Yoni koota and Pathu Porutham Yoni

computeAshtakoot now scores the Yoni koota on the published five-level table. The old table had four levels (4, 2, 1 and 0), never awarded 3, and matched no published chakra. The new one is the Yoni chakra of Mahidhar Sharma's tika on Muhurta Chintamani, as carried by Frawley and by PyJHora, the Python port of Jagannatha Hora. Muhurta Chintamani itself fixes only the seven enemy pairs.

ScoreRelationAnimal pairs
4Same animal14, one for each animal
3Friendly15, for example horse ↔ snake, elephant ↔ sheep, cow ↔ buffalo
2Neutral44, for example rat ↔ elephant
1Unfriendly25, for example horse ↔ tiger
0Enemy7: horse ↔ buffalo, elephant ↔ lion, sheep ↔ monkey, snake ↔ mongoose, dog ↔ deer, cat ↔ rat, cow ↔ tiger
computeAshtakoot({ rashi: 0, nakshatra: 0 }, { rashi: 1, nakshatra: 3 })   // Ashwini boy, Rohini girl
- Yoni 1 'horse ↔ snake', totalScore 21.5
+ Yoni 3 'horse ↔ snake', totalScore 23.5

  computeAshtakoot({ rashi: 0, nakshatra: 0 }, { rashi: 6, nakshatra: 15 })  // Ashwini boy, Vishakha girl
- Yoni 2 'horse ↔ tiger', totalScore 23.5
+ Yoni 1 'horse ↔ tiger', totalScore 22.5

The nakshatra-to-animal map, the Yoni maximum of 4, the total of 36 and the other seven koots are unchanged, and ganaCancellation moves by the same amount. Over all 1,296 valid pairs of natal Moons, 550 change their total: 372 lose a point, 166 gain one and 12 gain two. 27 of them cross the 18-point line.

Pathu Porutham Yoni is the enemy-pair test

The Yoni porutham in computePathuPorutham is now the Tamil pass/fail test. It fails, with veto: true, only on the seven enemy pairs above, and it no longer reads the Ashtakoot score. In 5.3 it passed on an Ashtakoot Yoni score of 2 or more, so every 1-point pair failed.

computePathuPorutham(ashwiniBoy, rohiniGirl)   // the Yoni entry of poruthams
- { name: 'Yoni', passes: false, description: 'horse ↔ snake (Ashtakoot Yoni score 1/4)' }
+ { name: 'Yoni', passes: true,  description: 'horse ↔ snake, not enemies' }

  computePathuPorutham(anuradhaBoy, mulaGirl)
- { name: 'Yoni', passes: false, description: 'deer ↔ dog (Ashtakoot Yoni score 0/4)', veto: true }
+ { name: 'Yoni', passes: false, description: 'deer ↔ dog, enemies', veto: true }

The description is now <boy> ↔ <girl>, not enemies or <boy> ↔ <girl>, enemies, so every Pathu Yoni description string changes and a snapshot of it will break. Over the 1,296 pairs the Yoni verdict flips on 52, all from fail to pass, no veto flips, and recommended turns true on 5. Snake ↔ rat is deliberately not an enemy pair: some Tamil lists add it, and the narrower classical list was kept.

Brahma Muhurta is the 14th night muhurta

muhurtas.brahma is now the 14th of the 15 muhurtas of the night, the night being the span from sunset to the next sunrise. It runs from two night muhurtas before sunrise to one night muhurta before sunrise. In 5.3 it was a daylight/30 window, about 24 minutes wide, ending another daylight/30 before sunrise.

Pune, 20 March 2025 (sunrise 06:38:43 IST)StartEndWidth
5.3.005:50:1606:14:3024.2 min
5.4.005:03:4405:51:1447.5 min

That is 95 to 47.5 minutes before sunrise. The daily panchang measures the night from the day's sunset to the next sunrise, the same night Pratah Sandhya uses, so the window's midpoint is exactly muhurtas.pratahSandhya.start (05:27:29 here). The reference-almanac captures in the library's test data confirm that Pratah Sandhya start. They hold no Brahma Muhurta value of their own.

The standalone computeBrahmaMuhurta(sunrise, sunset) keeps its signature and applies the same rule. With only those two instants it takes the night as 24 hours less the daylight, so its window can differ from muhurtas.brahma by a few seconds: 6.6 s and 3.3 s earlier at Pune on the same day.

Day-valued dates read in the location's zone

Some results name a day rather than a moment. Every one of them now reads as the right day when you format it in the location's zone. They come in two forms.

FormReturned byExample
The local midnight itselfcomputeFestivalsForYear and computeFestivalsInRange (FestivalDay.date). The range form keeps the range start's local time of day.Delhi, Akshaya Tritiya 2020: 2020-04-25T18:30Z, which is 26 April 00:00 IST.
The UTC midnight that falls within the local daycomputeEkadashiDatesForYear, computeSankrantisForYear (SankrantiEvent.date), getHinduNewYear and convertHinduToGregorianNew York, Mesha Sankranti 2025: 2025-04-14T00:00Z, which is 13 April 20:00 EDT.

What changed is that SankrantiEvent.date and the solar branch of getHinduNewYear (Tamil Nadu, Kerala, Punjab, West Bengal and Assam) moved onto the second form. In 5.3 they were the date's own UTC midnight, which west of UTC reads one day early in the zone: Mesha Sankranti and Puthandu 2025 in New York read as 12 April. At UTC and east of it, IST included, every value is byte-identical. SankrantiEvent.moment, the exact transit, did not change.

import { computeFestivalsForYear, computeSankrantisForYear, getHinduNewYear } from 'panchang-ts';

// A day value, formatted as YYYY-MM-DD in the location's zone.
const day = (d: Date, timeZone: string) =>
  new Intl.DateTimeFormat('en-CA', { timeZone }).format(d);

// (a) A festival listing: the local midnight itself.
const delhi = { latitude: 28.6139, longitude: 77.2090 };
const at = computeFestivalsForYear(2020, delhi, { timezone: 330 })
  .find((f) => f.festival.key === 'akshaya_tritiya')!;
day(at.date, 'Asia/Kolkata');          // '2020-04-26'

// (b) A Sankranti or a new year: the UTC midnight inside the local day.
const ny = { latitude: 40.7128, longitude: -74.0060 };
const mesha = computeSankrantisForYear(2025, ny, { timezone: 'America/New_York' })
  .find((e) => e.rashi === 0)!;
day(mesha.date, 'America/New_York');   // '2025-04-13'   (5.3.0: '2025-04-12')

const puthandu = getHinduNewYear(2025, 'tamil-nadu', ny, { timezone: 'America/New_York' })!;
day(puthandu, 'America/New_York');     // '2025-04-13'   (5.3.0: '2025-04-12')

The Odisha new year is Pana Sankranti

getHinduNewYear(year, 'odisha', location, options) now returns Pana Sankranti, the Mesha Sankranti day, instead of Chaitra Shukla Pratipada. The day is the transit's civil date, or, when the transit falls later than 0.315 of the way through the night after sunset, the date of the sunrise that ends that night. That cutoff is fitted to the reference almanac's Bhubaneswar dates. No textbook Odia rule reproduces them.

Place and yearMesha transit (IST)5.3.05.4.0
Bhubaneswar 202421:16 on 13 April9 April13 April
Bhubaneswar 202821:48 on 13 April27 March14 April
Delhi 202821:48 on 13 April27 March13 April

The cutoff is a fraction of the local night, so the date depends on the location: the same 21:48 transit is past the cutoff at Bhubaneswar and before it at Delhi. The new year can also fall a day before SankrantiEvent.date, which moves every transit after sunset to the date of the next sunrise. At Bhubaneswar in 2024 the new year is 13 April and the Mesha SankrantiEvent.date is 14 April. There is no pana_sankranti festival key: for region 'odisha' the daily list shows the Mesha sankranti entry on 14 April and nothing on 13 April.

Other values that move

Listings and the calendar

WhatWasNow
Year and range listings in zones with daylight saving: computeFestivalsForYear, computeFestivalsInRange, computeAuspiciousDatesForYear, computeAuspiciousDatesInRange, computeMoonPhasesForYear, computeEclipsesForYearA fixed 24-hour step from an offset taken on 1 July. In New York that skipped the spring-forward day, listed the fall-back day twice, began on the previous 31 December and dropped the requested one. Winter days were stamped at 23:00 rather than midnight: Diwali 2026 came back as 2026-11-09T04:00Z, which is 23:00 on 8 November in the zone and 9 November at the July offset.Steps civil days in the zone. Diwali 2026 is 2026-11-08T05:00Z, the local midnight of 8 November. Numeric offsets and zones without daylight saving, IST included, are byte-identical.
Festivals that went missingNo entry for Sankashti Chaturthi when Chaturthi touches no moonrise (about 7% of Krishna pakshas), for Ugadi, Gudi Padwa and Navaratri when a kshaya Pratipada follows an adhika month, for the Smarta Ekadashi of a vriddha Ekadashi followed by a kshaya Dwadashi, or for Onam in an adhika Bhadrapada year (2012, 2096).Listed: Sankashti at Delhi on 10 October 2025, Ugadi at New York on 12 April 1964, Navaratri at Sydney on 17 October 2020, the Smarta Ekadashi at Chennai on 15 March 2030, Onam at Kochi on 29 August 2012 and 31 August 2096. Across 9 cities over 1900 to 2100 these four fixes add 1,677 entries and remove or move none.
getHinduNewYear on a kshaya Chaitra Shukla PratipadaThe first sunrise day of Chaitra: Delhi 2026 was 20 March.The day that contains the Pratipada, which is the day Ugadi falls on and the day the reference publishes: 19 March.
convertHinduToGregorian, Adhika Chaitra, purnimantaMissed the Krishna-paksha dates of an Adhika Chaitra, which open the Vikram year. VS 2086 Chaitra Krishna 7 at Delhi gave only 25 March 2030, and nothing with adhikaOnly.Finds them: 5 April 2029 and 25 March 2030, and 5 April 2029 with adhikaOnly.
computeEclipsesInRange and computeEclipsesForYearSelected by syzygy. At Pune the range 1976-04-29T11:00Z to 1976-04-30T00:00Z found nothing. At Darwin the lunar eclipse peaking at 23:58 local on 31 December 2066 was listed in both 2066 and 2067.Selected by peak: the Pune range returns the solar eclipse peaking at 12:22:11Z, and the Darwin eclipse is listed in 2066 only.
computeEkadashiDatesForYearA fast on local 31 December landed in the next year's list. Pune 1911 ended on 16 December, and 1912 began with 1 January, which is the fast of 31 December 1911.1911 ends with 31 December and 1912 starts on 14 January. The values keep the second form above.
Years 1900 and 2100INVALID_DATE at some offsets: the festival, auspicious-date, moon-phase and eclipse year listings and buildMuhurtaTable for 1900 east of UTC and for 2100 west of it (computeFestivalsForYear for 1900 at +330, for 2100 at -300), and buildMoonPhasesTable and buildEclipsesTable for either year at any offset.Work at every offset: 250 entries for Pune in 1900, 255 for New York in 2100 at -300.
Years 0 to 99Silently read as 1900 to 1999: computeFestivalsForYear(50) returned 267 entries for 1950. convertHinduToGregorian instead returned [].The festival, moon-phase, eclipse and auspicious-date listings, the lunar getHinduNewYear, convertHinduToGregorian and the table builders throw INVALID_DATE. computeEkadashiDatesForYear and computeSankrantisForYear take any year, so 99 now means the year 99: 25 Ekadashis from 0099-01-03 (5.3 returned the 1999 dates) and 12 Sankrantis (5.3 returned none). The solar getHinduNewYear returns null for such a year (5.3 returned the 1999 date).

The daily panchang

WhatWasNow
A civil day with no sunriseReturned the next day's panchang, so one Hindu day appeared on two dates. Longyearbyen on 14 February 2025 came back with the 15th's sunrise.null (Go: ok false). This covers the day a polar night or midnight sun ends, and a fixed offset far from the location's solar time. getInstantPanchang likewise returns null for an instant whose Hindu day has no sunrise to start it: Longyearbyen at 08:00 UTC on 15 February 2025.
moon.set on a day with no moonriseTaken from the next civil day: Reykjavik on 21 December 2025 gave 2025-12-22T17:26Z.That day's own first moonset, or null. Null there.
An eclipse around sunriseCould show on two consecutive days. New York listed the 29 March 2025 partial solar eclipse, and surya_grahan, on both the 28th and the 29th.Exactly one day: the 29th.
A solar eclipse whose peak is below the horizonDescribed at the peak: 'Partial solar eclipse: 78% obscuration, not visible from location.' (New York, 29 March 2025).Described by its deepest visible phase: 'Partial solar eclipse: 24% obscuration, visible from location.' obscuration stays the at-peak 0.775, and visibleFromLocation, which is about the peak, stays false.
computeEndTimes: falseCould drop special yogas: Pune on 2 January 2025 gave none, against Ravi Yoga by default.The same specialYogas as the default call.
Bhadra boundaryAbout a minute late on a handful of days: Urumqi on 6 January 2024 ended at 01:13:17.Ends at 01:12:14, 63.26 s earlier. The start did not move.

Dashas and the Jyotish layer

WhatWasNow
Ashtottari and Yogini antardashas of the birth mahadashaAll of them squeezed into the remaining balance, starting with the mahadasha's own lord. Birth 1990-05-15T10:30Z, Moon at 123.4°: Yogini listed 8, starting Bhadrika, Ulka, Siddha.The full mahadasha's antardashas, clipped at birth, as Vimshottari already did: 7, starting Ulka, Siddha, Sankata. Mahadasha dates and lords do not move.
Narayan dasha, { duration: 'variable' }A sign whose lord occupies it got 0 years (1 for Mercury in Virgo). Pune, 1990-05-15T06:30Z: Capricorn 0 years.12 years, and every later period shifts. Capricorn 12 years.
Sub-period endsCould fall short of the parent's end by up to 8 ms.End exactly at the parent's end, in every antardasha and pratyantar list.
Shadbala: Nathonatha BalaJumped by 60 virupas at sunrise and sunset. At Pune on 20 March 2025 the Sun's Kala Bala went from 80.91 one second before sunrise to 20.92 one second after.Continuous: 5 virupas an hour from apparent midnight to apparent noon (BPHS). 50.61 to 50.63 across the same sunrise.
Sade Sati nextArcStartSkipped a retrograde re-entry and could report the next full arc, about 21 years late. Kumbha as of 1 August 2027 gave 2049-03-07.2027-10-20T12:00Z, the retrograde return into the arc.
KemadrumaA Sun conjunct the Moon, or in the 2nd or 12th from it, broke it.The Sun does not break it, as in Sunapha and Anapha. Delhi, 1950-02-21T02:24Z, now carries Kemadruma.
computeVarjyamA meaningless window for an index that is not the nakshatra at sunrise, usually a few seconds and occasionally a plausible-looking hour or more. Index 21 at Pune on 20 March 2025, an Anuradha (16) sunrise, gave a 7.0 s window; index 3 on 10 January 2025, a Krittika (2) sunrise, gave 117 minutes.null. For every spell of the day, use computeVarjyamWindows.
Placidus-KP between about 66.3° and 66.56° of latitudePLACIDUS_DIVERGED: computeBhava with houseSystem 'placidus-kp' at 66.3° N, 18° E, 2025-03-20T08:00Z.Cusps, the first at 86.32°. Beyond the polar circles every error keeps its code.

The Shadbala change moves kala and total in computeShadbala, and bhavadhipati and total in computeBhavaBala. Totals in the library's pinned charts move by up to about 34 virupas, and more for a birth just after sunrise in a long night: at Oslo one minute after sunrise on 21 December 2025 the Sun's total goes from 357.29 to 402.29. The Varshaphala year lord, which reads Shadbala, can change with them.

New: computeVimshottariPratyantarIn

computeVimshottariPratyantarIn(mahaDasha, antardasha) returns the pratyantardashas of an antardasha split over its full length and then clipped, which is what the birth antardasha needs. The antardasha running at birth is clipped to start at birth, so its list begins with the pratyantar running at birth and can hold fewer than nine. Only mahaDasha.lord is read.

import {
  computeVimshottariDashaFromBirth, computeVimshottariPratyantar, computeVimshottariPratyantarIn,
} from 'panchang-ts';

const birth = new Date('1995-08-15T05:30:00Z');
const vim = computeVimshottariDashaFromBirth(birth, 'lahiri');
const maha = vim.mahaDashas[0]!;      // Mercury, from birth
const antar = maha.antarDashas[0]!;   // Rahu, clipped to start at birth

// The birth antardasha, split over its full length, then clipped.
const pra = computeVimshottariPratyantarIn(maha, antar);
console.log(pra.length, pra[0]!.lord, pra[0]!.startDate.toISOString());
// 6 Mercury 1995-08-15T05:30:00.000Z

// The older call treats the clipped span as a whole antardasha.
const squeezed = computeVimshottariPratyantar(antar);
console.log(squeezed.length, squeezed[0]!.lord);   // 9 Rahu

The six run Mercury, Ketu, Venus, Sun, Moon and Mars, and the last ends exactly at the antardasha's end, 1996-10-17T02:07:37Z. computeVimshottariPratyantar is unchanged: it treats whatever span it is given as a whole antardasha, so on the clipped birth antardasha it fits all nine into the remaining span, starting with Rahu. For an antardasha that is not clipped the two calls return the same list. Neither takes an asOfDate. An unknown lord throws PanchangError with code INVALID_INPUT. See Dashas & Transits.

Input validation

Only inputs that used to hang, crash with a raw TypeError, or return garbage are affected. Valid input gives the same result as before.

Input5.3.05.4.0
getSunrise(new Date('x'), loc), and getSunset, getMoonrise, getMoonset on an Invalid Date or an instant beyond the solver's rangeNever returnedINVALID_DATE
houseSystem: 'koch', divisional 'D60', an unknown graha in computeDignityA raw TypeErrorINVALID_INPUT, e.g. unknown house system "koch"; expected one of whole-sign, equal, placidus-kp
A lagna rashi index outside 0 to 11 in computeYogas, a negative or fractional one in computeArudhas, a non-integer vikramSamvat in convertHinduToGregorianA raw TypeError (below 0 or fractional) or an often wrong yoga list (12 and up), twelve arudhas anyway, and []INVALID_INPUT, and INVALID_DATE for the vikramSamvat
An unknown yoga type in computeYogas, an unknown nodeAspectsSilently ignoredINVALID_INPUT
A vara outside 0 to 6 in computeRahuKalam, computeGulikaKalam, computeYamaganda, computeGowriPanchangamAn Invalid Date window or a TypeErrorINVALID_INPUT. Go still panics, now with a message naming the vara
An unknown lord in computeVimshottariPratyantarA plain ErrorPanchangError with code INVALID_INPUT
An Invalid Date in getAyanamsa, getSiderealSunLongitude, getSiderealMoonLongitudeNaNINVALID_DATE
An Invalid Date in getUpcomingSolarEclipse, getUpcomingLunarEclipse or computePlanetaryPositionsnull from the two eclipse lookups, NaN longitudes from the positionsINVALID_DATE
A non-integer or out-of-range timezoneOffsetMinutes in buildEclipsesTable or buildMoonPhasesTable, such as 5.5 or 900The table was builtINVALID_TIMEZONE
A table language other than en or hi in buildFestivalsTable, buildEclipsesTable, buildMoonPhasesTableThe festival table was built anyway, the other two threw a TypeErrorA RangeError in TypeScript, INVALID_INPUT in Go
A Moon longitude outside [0, 360) in the three moon-longitude dashasA wrong result or a crashWrapped into range, so 360 reads as 0. NaN or Infinity throws INVALID_INPUT.
formatInZone(new Date('2025-03-20T00:00:00Z'), 5.5)2025-03-20T00:05:30.000+00:undefinedINVALID_TIMEZONE. Any integer offset now prints, 3660 as +61:00.
computePrashnaChart and computeKpCuspalSubLords with an option passed as undefinedFell through to Lahiri and whole-signKeep their KP defaults, the same as an absent key

One relaxation: from untyped JavaScript, janmaRashi: null or janmaNakshatra: null in getDailyPanchang now means the same as leaving the key out, so chandraBalam and tarabala come back null. 5.3 threw a RangeError. The TypeScript type still takes only a number.

Documented, not changed: an omitted timezone falls back to the host's zone in untyped JavaScript. The Go port reports INVALID_TIMEZONE instead, and accepts the zone names "" (UTC) and "Local" (the host), which TypeScript rejects. See Errors & Compatibility.

Faster, with no output changes

The speed work in this release changed no output: every table file and every pinned test value is byte-identical before and after it. Each figure below is a ratio, the time before divided by the time after, measured on one machine with the two builds alternating, as medians. They are not absolute times.

CallTypeScriptGo
getDailyPanchang, a year of days1.4x1.3x
getDailyPanchang, a year in America/New_York1.5x1.4x
getInstantPanchang, a year of instants1.5x1.4x
computeFestivalsForYear1.8x1.5x
buildMuhurtaTable, one year2.2x2.0x
convertHinduToGregorian6.5x5.0x
getUpcomingEclipses4.6x3.9x
computeSadeSati18x16x
computeKpCuspalSubLords / computeBhava12x38x
A birth-chart bundle2.2x2.5x

Most of the causes were repeated work. New-moon searches and planet positions were recomputed across days and charts, and are now kept in bounded caches keyed by every input, so no result depends on which calls ran before it. House cusps computed nine planet positions they never read. The converters and table builders built whole days to read four labels. Sade Sati sampled Saturn at steps where it cannot change sign, and a timezone formatter was rebuilt on every call. One cause was not repeated work: in TypeScript, the sine and cosine behind every series evaluation now keep their reduced argument in locals instead of module-level variables. That alone gives the chart primitives their whole speedup and most of the gain on a distinct day and in the Ekadashi and Sankranti listings. The caches give nearly all of the gain on a repeated day. See Performance.

Go: additive

github.com/ishankgupta95/panchang/source/go/v5 carries every change above with the same instants, days, festivals and labels, and adds API without removing or changing any. Every exported function, method, field, constant and type of v5.3.0 is unchanged.

  • New calls: ComputeVimshottariPratyantarIn, ComputeJaimini8Karakas, (*Session).ComputeSripatiLagnaWithCusps and (*Session).GetUpcomingEclipsesContext.
  • Table readers, the Go form of the panchang-ts/festivals, /eclipses, /moon-phases and /muhurta subpaths: ReadFestivalsForYear, ReadFestivalsForDate, ReadFestivalsForDateKey, ReadFestivalsYearRange and the same four for eclipses and moon phases, plus ReadMuhurtaForYear, ReadMuhurtaForDate, ReadMuhurtaForDateKey, ReadMuhurtaYearRange, ReadMuhurtaOccasion and ReadBestMuhurtaDays, with their result types in types.
  • Enum helpers and constants: AllKaraka8Names, AllMoonPhaseNames, AllMoonPhaseTableNames, AllNarayanDirections, AllNodeAspects, AllReferences and AllYogaPolarities, the eight YoginiName constants, and JSDate.Time().
  • Behaviour: a zero-value Session now behaves like New(). An empty ayanamsa means Lahiri in ComputeAyanamsa and GetSidereal*Longitude, as an omitted one does in TypeScript. ComputeAshtottariDasha and ComputeYoginiDasha wrap an out-of-range Moon longitude instead of returning ErrInvalidInput.

What to rebuild and re-pin

  • Rebuild every festival table and diff it. Festival days move, holika_dahan appears (and karthigai_deepam in tables for 'all' and 'tamil-nadu'), and a table built west of UTC no longer starts on the previous 31 December. The format is unchanged, so nothing will warn you.
  • Re-read cached listings and muhurta scores. Year and range listings in a zone with daylight saving, the eclipse listings and computeEkadashiDatesForYear near a year boundary can all change. An eclipse around sunrise now shows on one day, not two, so the other day's muhurta score can move: New York on 28 March 2025 scores 45 for vivahRule, not 0, and still fails.
  • Rebuild eclipse tables if you read subtype. A solar eclipse whose peak is below the horizon now carries the subtype of its deepest visible phase, and its name and description follow. That is rare: at New York over 1950 to 2080 it is one eclipse, 1 July 2057, annular before and partial now, and the Delhi, London, Sydney and Reykjavik tables do not change.
  • Move any Holika Dahan logic from holi to holika_dahan, and check anything that hard-coded the meaning of bathukamma_saddula, masik_karthigai, the Chhath keys or the default Shravan Somvar list.
  • Recompute stored Ashtakoot totals and Pathu Porutham verdicts, and re-pin snapshots of the Pathu Yoni description.
  • Re-pin Brahma Muhurta wherever you stored or displayed it.
  • Re-read Sankranti and solar new-year dates cached west of UTC, and format every day value in the location's zone.
  • Re-pin new-year dates and conversions: the Odisha new year at every offset, a lunar new year whose Pratipada holds no sunrise (Delhi 2026 moves from 20 to 19 March), and convertHinduToGregorian in an Adhika Chaitra year.
  • Handle the new nulls and re-pin daily values. getDailyPanchang and getInstantPanchang return null when there is no sunrise to start the Hindu day, moon.set on a day with no moonrise is that day's own moonset or null, never the next day's, and computeVarjyam returns null for an index that is not the sunrise nakshatra. The eclipse of the day, specialYogas with computeEndTimes: false and some Bhadra ends move.
  • Recompute Shadbala, Bhava Bala and the Varshaphala year lord.
  • Re-pin yoga lists and Placidus-KP charts: the Sun no longer breaks Kemadruma, and 'placidus-kp' returns cusps between about 66.3° and 66.56° of latitude instead of PLACIDUS_DIVERGED.
  • Re-pin Ashtottari and Yogini birth antardashas, Narayan variable durations, sub-period ends and Sade Sati nextArcStart, and switch the birth antardasha's pratyantars to computeVimshottariPratyantarIn.
  • Match festivals on key, never on name, and match errors on code, never on message text.