panchang-ts 5.3.0 → 5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +270 -34
- package/dist/index.cjs +1902 -865
- package/dist/index.d.cts +217 -69
- package/dist/index.d.ts +217 -69
- package/dist/index.js +1902 -866
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
Pure TypeScript Hindu Panchang (almanac), Jyotish, and Birth Chart calculations.
|
|
7
7
|
Zero runtime dependencies. Works offline in React Native (Hermes), Node.js, and browsers.
|
|
8
8
|
|
|
9
|
-
**Fast** (~0.
|
|
9
|
+
**Fast** (~0.16 ms trimmed, ~0.30 ms full) · **Typed** (full TypeScript) · **Offline** (pure JS math) · **9,207 tests across 146 files**
|
|
10
10
|
|
|
11
11
|
> 📖 **Full documentation: [dharmagya.app/docs/panchang-ts](https://dharmagya.app/docs/panchang-ts)**
|
|
12
|
-
> This README covers install, quick start, and the 5.1 → 5.2, 5.0 → 5.1 and 4.x → 5 migrations
|
|
12
|
+
> This README covers install, quick start, and the 5.3 → 5.4, 5.1 → 5.2, 5.0 → 5.1 and 4.x → 5 migrations
|
|
13
13
|
> in full, plus a per-feature quick reference. The complete reference (every option, result field,
|
|
14
14
|
> table format, accuracy bound and performance note) lives on the docs site.
|
|
15
15
|
|
|
@@ -38,8 +38,8 @@ const result = getDailyPanchang(
|
|
|
38
38
|
{ latitude: 23.1765, longitude: 75.7885 }, // Ujjain, India
|
|
39
39
|
{ timezone: 330 }, // IST = UTC+5:30 = 330 minutes
|
|
40
40
|
);
|
|
41
|
-
// → DailyPanchangResult | null. Null only
|
|
42
|
-
//
|
|
41
|
+
// → DailyPanchangResult | null. Null only when no sunrise-to-sunrise day starts on that date
|
|
42
|
+
// (polar latitudes, or an offset far from local solar time). Narrow with `if (!result) return;`.
|
|
43
43
|
|
|
44
44
|
console.log(result!.angas.tithis[0].name); // "Krishna Chaturdashi"
|
|
45
45
|
console.log(result!.angas.nakshatras[0].name); // "Mrigashira"
|
|
@@ -185,6 +185,230 @@ pre-computed for Varanasi, which is a fourth point again.
|
|
|
185
185
|
|
|
186
186
|
---
|
|
187
187
|
|
|
188
|
+
## Upgrading to 5.4
|
|
189
|
+
|
|
190
|
+
Correctness fixes from a full TypeScript and Go audit, festival rules brought in line with the
|
|
191
|
+
reference almanac and its competitors, a corrected Yoni koota table, one new export and two new
|
|
192
|
+
festival keys. Nothing is removed or renamed and no signature changes, but many published values
|
|
193
|
+
move, so read the first sections before upgrading if you cache or diff output. The Go module
|
|
194
|
+
(`source/go/v5`) carries the same changes byte for byte.
|
|
195
|
+
|
|
196
|
+
### Festival days now follow the reference almanac
|
|
197
|
+
|
|
198
|
+
Every rule below was checked against published dates: the reference almanac first, then AstroSage
|
|
199
|
+
and other almanacs, with the classical rule (Nirnaya Sindhu, Dharma Sindhu) as the tie-breaker.
|
|
200
|
+
The dates relied on are pinned in `testdata/almanac/almanac-festival-selection-2026-09.json` and
|
|
201
|
+
`almanac-festival-rules-2026-09-nakshatra-solar.json`. Over 5 cities and 1900 to 2100 every
|
|
202
|
+
once-a-year festival now fires exactly once per year and every monthly one at most once per paksha
|
|
203
|
+
or month; before, most of them were listed on two consecutive days in some years. Two exceptions
|
|
204
|
+
remain while their rules are deferred (below): Phagli still takes every day whose sunrise holds
|
|
205
|
+
Purnima (two days in 2033, none in 2018 at Delhi), and a paksha whose Trayodashi touches no
|
|
206
|
+
pradosha window has no Pradosh.
|
|
207
|
+
|
|
208
|
+
- **A tithi current at two sunrises** (vriddhi): the first day, as the reference publishes (Anant
|
|
209
|
+
Chaturdashi 2018-09-23, Ghatasthapana 2015-10-13), except the Tritiya vratas (Hariyali, Kajari
|
|
210
|
+
and Hartalika Teej, Gangaur) and Jagannath Rath Yatra, which take the second (Hartalika Teej
|
|
211
|
+
2006-08-27). Ugadi, Gudi Padwa, Hanuman Jayanti, Navaratri, Durga Ashtami, Guru, Sharad, Kartika
|
|
212
|
+
and Vat Savitri Purnima, Mahalaya Amavasya and others lose their second-day duplicate.
|
|
213
|
+
- **Festivals chosen by a kala** use the reference's windows (madhyahna the third fifth of
|
|
214
|
+
daytime, aparahna the fourth, pradosha sunset to sunset + night/5, nishita the 8th night
|
|
215
|
+
muhurta). The day whose window the tithi covers most decides Ganesh and Vinayaka Chaturthi
|
|
216
|
+
(madhyahna), Dhanteras, Diwali and Parashurama Jayanti (pradosha) and Govardhan Puja (daytime),
|
|
217
|
+
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
|
|
218
|
+
with the Shravana rule. Rama Navami (madhyahna), Bhai Dooj and Vat Savitri Amavasya (aparahna)
|
|
219
|
+
take the last day whose window the tithi touches, Narak Chaturdashi the first day whose
|
|
220
|
+
arunodaya it touches, and Vasant Panchami the first day on which Panchami has begun by two
|
|
221
|
+
fifths of the daytime. Vinayaka Chaturthi in December 2025 at Delhi drops its 12-23 duplicate
|
|
222
|
+
and keeps 12-24.
|
|
223
|
+
- **Raksha Bandhan, Yajur Upakarma, Nag Panchami and Akshaya Tritiya** take the first sunrise day
|
|
224
|
+
on which the tithi lasts at least 3 muhurtas, else the day it begins. Akshaya Tritiya 2020 at
|
|
225
|
+
Delhi drops its 04-25 duplicate and keeps 04-26.
|
|
226
|
+
- **Pradosh vrat** is the day whose pradosha window (sunset to sunset + night/5) overlaps
|
|
227
|
+
Trayodashi most; it reproduces every reference date for Delhi 2025 and 2027 (Ravi Pradosh
|
|
228
|
+
2025-02-09 was missing).
|
|
229
|
+
- **Holika Dahan** is a new festival key, `holika_dahan`, on the evening the reference's Bhadra
|
|
230
|
+
ladder chooses; **`holi` is now the next day** (Rangwali Holi), as the reference publishes it.
|
|
231
|
+
That holds for `getDailyPanchang`, the listings and the tables. `getInstantPanchang` reports by
|
|
232
|
+
the tithi at the instant, so an instant in Phalguna Purnima lists `holika_dahan` and `holi`
|
|
233
|
+
together, and it never lists `karthigai_deepam` (it reports `masik_karthigai` on that day).
|
|
234
|
+
- **Chhath** is anchored on the Shashthi sunrise day with Nahay Khay, Kharna and Usha Arghya at
|
|
235
|
+
-2, -1 and +1 days; **Maha Navami** takes the first day whose sunset less two muhurtas follows the
|
|
236
|
+
start of Navami (2015-10-21, 2027-10-08); **Saddula Bathukamma** moves to Durgashtami;
|
|
237
|
+
**Varamahalakshmi** is the Friday in the 7 days ending on the Shravana Purnima sunrise day.
|
|
238
|
+
- **Masik Karthigai** is one day per Krittika transit (the first day Krittika holds at sunset, else
|
|
239
|
+
at sunrise); it fired on two consecutive days in about three months of four. **Karthigai Deepam**
|
|
240
|
+
is a new festival key, `karthigai_deepam`, on the Karthigai-month Krittika day nearest the full
|
|
241
|
+
moon, for regions `all` and `tamil-nadu`. On that day those two regions list it in place of
|
|
242
|
+
`masik_karthigai`; every other region still lists `masik_karthigai`, so a table built for `all`
|
|
243
|
+
and filtered by region afterwards loses that month's Masik Karthigai outside Tamil Nadu.
|
|
244
|
+
- **Onam** is exactly one day a year: the Thiruvonam of Chingam, the first of two Chingam sunrises,
|
|
245
|
+
the day holding it when it holds no sunrise, and the later of two Thiruvonams in one Chingam
|
|
246
|
+
(at Kochi, 2024-09-15 and 2013-09-16).
|
|
247
|
+
- **Shravan Somvar, Mangala Gauri, Kartik Somvar and Magha Shanivar** follow `masaSystem`: the
|
|
248
|
+
default purnimanta gives the North Indian Mondays (Sawan Somwar 2025: 07-14, 07-21, 07-28, 08-04),
|
|
249
|
+
`amanta` the southern ones as before, region `nepal` the solar month. This changes the default
|
|
250
|
+
output: a caller that never sets `masaSystem` now gets the North Indian dates.
|
|
251
|
+
- Deferred for lack of a reference capture: a Pradosh fallback when Trayodashi touches no pradosha
|
|
252
|
+
window, Phagli, and the Guru Purnima short-udaya refinement.
|
|
253
|
+
|
|
254
|
+
### Yoni koota and Pathu Porutham Yoni
|
|
255
|
+
|
|
256
|
+
**Yoni koota (`computeAshtakoot`)** now uses the published five-level table (4 same animal, 3
|
|
257
|
+
friendly, 2 neutral, 1 unfriendly, 0 enemy); the old one never awarded 3 and matched no published
|
|
258
|
+
chakra. The table is the chakra of Mahidhar Sharma's tika on Muhurta Chintamani, as carried by
|
|
259
|
+
Frawley and the Jagannatha Hora port PyJHora; the sources are in
|
|
260
|
+
`testdata/charts/yoni-koota-references.json`. 550 of the 1,296 valid pairs of natal Moons change
|
|
261
|
+
total (372 by -1, 166 by +1, 12 by +2). **Pathu Porutham Yoni** (`computePathuPorutham`) is now the
|
|
262
|
+
Tamil pass/fail test, failing only on the seven enemy pairs, and no longer reads the Ashtakoot
|
|
263
|
+
score; its description reads, for example, `"horse ↔ snake, not enemies"`.
|
|
264
|
+
|
|
265
|
+
### Day-valued results west of UTC, and the Odisha new year
|
|
266
|
+
|
|
267
|
+
`computeSankrantisForYear` (`SankrantiEvent.date`) and the solar branch of `getHinduNewYear`
|
|
268
|
+
(Tamil Nadu, Kerala, Punjab, West Bengal, Assam) now return the UTC midnight that falls within the
|
|
269
|
+
local day, like every other day-valued result, so formatting them in the location's zone gives the
|
|
270
|
+
right day (Puthandu 2025 in New York read as April 12). At UTC and east of it, IST included, every
|
|
271
|
+
value is byte-identical. **`getHinduNewYear(year, 'odisha')`** returns Pana Sankranti, the Mesha
|
|
272
|
+
Sankranti day, instead of Chaitra Shukla Pratipada: the transit's civil date, or, when the transit
|
|
273
|
+
falls later than 0.315 of the way through the night after sunset, the date of the sunrise that ends
|
|
274
|
+
that night. That cutoff is fitted to the reference
|
|
275
|
+
almanac's Bhubaneswar dates (2024-04-13 for a 21:15 transit, 2028-04-14 for 21:47); no textbook
|
|
276
|
+
Odia rule reproduces them. The cutoff is a fraction of the local night, so the date depends on the
|
|
277
|
+
location (2028 is 04-13 at Delhi and 04-14 at Bhubaneswar), and it can fall a day before
|
|
278
|
+
`SankrantiEvent.date`, which moves a transit after sunset to the next day (Bhubaneswar 2024: 04-13
|
|
279
|
+
and 04-14). The festival listings are not part of this change: `computeFestivalsForYear` returns
|
|
280
|
+
the local midnight of each day and `computeFestivalsInRange` the range start's local time of day,
|
|
281
|
+
and both read correctly in the location's zone.
|
|
282
|
+
|
|
283
|
+
### Values that move
|
|
284
|
+
|
|
285
|
+
- **Brahma Muhurta** (`muhurtas.brahma`, `computeBrahmaMuhurta`) is now the 14th of the 15 night
|
|
286
|
+
muhurtas, from two night muhurtas to one before sunrise (about 96 to 48 minutes at an
|
|
287
|
+
equinox). It used daylight/30, a 24 minute window ending 24 minutes before sunrise. The daily
|
|
288
|
+
panchang measures the night from sunset to the next sunrise, so the window's midpoint is
|
|
289
|
+
exactly Pratah Sandhya's start, which the reference almanac captures in `testdata` confirm;
|
|
290
|
+
they hold no Brahma Muhurta value of their own.
|
|
291
|
+
- **Year and range listings in zones with daylight saving** (`computeFestivalsForYear`,
|
|
292
|
+
`computeFestivalsInRange`, `computeAuspiciousDatesForYear`, `computeAuspiciousDatesInRange`,
|
|
293
|
+
`computeMoonPhasesForYear`, `computeEclipsesForYear`) now step civil days in the zone. They
|
|
294
|
+
used a fixed 24 hour step from an offset taken on 1 July, so in America and Europe they skipped
|
|
295
|
+
the spring-forward day, listed the fall-back day twice, included the previous 31 December and
|
|
296
|
+
dropped the requested one, and stamped winter dates at 23:00 of the previous day (Diwali 2026
|
|
297
|
+
in New York came back as `2026-11-09T04:00Z`, 23:00 on 8 November in the zone and 9 November at
|
|
298
|
+
the July offset; it is now `2026-11-08T05:00Z`, local midnight). Numeric offsets and zones without
|
|
299
|
+
daylight saving, IST included, are byte-identical.
|
|
300
|
+
- **Festivals that went missing**: Sankashti Chaturthi when Chaturthi touches no moonrise (about
|
|
301
|
+
7% of Krishna pakshas, for example Delhi 2025-10-10), Ugadi, Gudi Padwa and Navaratri when a
|
|
302
|
+
kshaya Pratipada follows an adhika month, the Smarta Ekadashi of a vriddha Ekadashi followed by
|
|
303
|
+
a kshaya Dwadashi, and Onam in adhika Bhadrapada years (2012, 2096). Across 9 cities over
|
|
304
|
+
1900 to 2100 these four fixes add 1,677 entries and remove or move none (the rule changes above
|
|
305
|
+
restore further dates of their own, and do move and remove entries).
|
|
306
|
+
- **`getHinduNewYear`** on a kshaya Chaitra Shukla Pratipada now returns the containing day, the
|
|
307
|
+
day the library's own Ugadi falls on and the reference publishes (2026-03-19, was 2026-03-20).
|
|
308
|
+
- **`convertHinduToGregorian`** now finds Adhika Chaitra Krishna-paksha dates in purnimanta mode.
|
|
309
|
+
- **`computeEclipsesInRange` / `computeEclipsesForYear`** select by the eclipse's peak, not its
|
|
310
|
+
syzygy, so an eclipse near a range or year boundary is listed exactly once.
|
|
311
|
+
- **`computeEkadashiDatesForYear`** covers the local calendar year exactly: a fast on local
|
|
312
|
+
31 December moves from the next year's list into its own (Pune 1912 loses 1912-01-01, which is
|
|
313
|
+
the 1911-12-31 fast). The values themselves are unchanged: each is still the UTC midnight that
|
|
314
|
+
falls within the local day of the fast, so format it in the location's zone.
|
|
315
|
+
- **Years 1900 and 2100** now work at every offset in the year listings and table builders. The
|
|
316
|
+
festival, moon-phase, eclipse and auspicious-date listings, the lunar `getHinduNewYear`,
|
|
317
|
+
`convertHinduToGregorian` and the table builders reject years 0 to 99 with `INVALID_DATE` instead
|
|
318
|
+
of silently reading them as 1900 to 1999. `computeEkadashiDatesForYear` and
|
|
319
|
+
`computeSankrantisForYear` still take any year, so 99 now means the year 99 rather than 1999,
|
|
320
|
+
and the solar `getHinduNewYear` returns `null` for such a year (5.3 returned the 1999 date).
|
|
321
|
+
- **Daily panchang edges**: a civil day with no sunrise at a polar transition returns `null`
|
|
322
|
+
instead of the next day's panchang, and `getInstantPanchang` returns `null` for an instant whose
|
|
323
|
+
Hindu day has no sunrise to start it; `moon.set` is no longer taken from the next civil day on a
|
|
324
|
+
day with no moonrise; one eclipse no longer shows on two consecutive days when sunrise falls
|
|
325
|
+
between syzygy and peak; a solar eclipse whose peak is below the horizon is described by its
|
|
326
|
+
deepest visible phase (so its description says it is visible while `visibleFromLocation`, which
|
|
327
|
+
is about the peak, stays `false`); `computeEndTimes: false` no longer changes `specialYogas`; the
|
|
328
|
+
Bhadra boundary is no longer about a minute off.
|
|
329
|
+
- **Dashas**: Ashtottari and Yogini antardashas of the birth mahadasha are now those of the full
|
|
330
|
+
mahadasha clipped at birth, as Vimshottari's already were; Narayan `{ duration: 'variable' }`
|
|
331
|
+
gives 12 years to a sign whose lord occupies it (it gave 0, or 1 for an exalted lord); sub-periods
|
|
332
|
+
now end exactly at their parent's end (they drifted by up to 8 ms).
|
|
333
|
+
- **Shadbala**: Nathonatha Bala is continuous across sunrise and sunset (it jumped by 60 virupas);
|
|
334
|
+
cached Shadbala and Bhava Bala totals move by up to about 34 virupas in the pinned charts, and
|
|
335
|
+
more for a birth just after sunrise in a long night; the Varshaphala year lord can change with
|
|
336
|
+
them.
|
|
337
|
+
- **Sade Sati** no longer skips a retrograde re-entry when finding `nextArcStart`, which could be
|
|
338
|
+
about 21 years late.
|
|
339
|
+
- **Kemadruma** no longer counts the Sun, consistent with Sunapha and Anapha.
|
|
340
|
+
- **`computeVarjyam`** returns `null` when the index is not the nakshatra in force at sunrise,
|
|
341
|
+
instead of a meaningless window (usually a few seconds, occasionally a plausible-looking hour).
|
|
342
|
+
- **Placidus-KP houses** between about 66.2 and 66.56 degrees of latitude now return cusps instead
|
|
343
|
+
of `PLACIDUS_DIVERGED`.
|
|
344
|
+
|
|
345
|
+
### New export
|
|
346
|
+
|
|
347
|
+
- `computeVimshottariPratyantarIn(mahaDasha, antardasha)`: the pratyantars of an antardasha split
|
|
348
|
+
over its full length and clipped, which is what the birth antardasha needs.
|
|
349
|
+
`computeVimshottariPratyantar` is unchanged.
|
|
350
|
+
|
|
351
|
+
### Input handling
|
|
352
|
+
|
|
353
|
+
Only inputs that used to hang, crash with a raw `TypeError`, or return garbage:
|
|
354
|
+
|
|
355
|
+
- An Invalid Date, or an instant beyond the rise and set solver's range, throws `INVALID_DATE`
|
|
356
|
+
instead of hanging `getSunrise` and friends forever.
|
|
357
|
+
- An unknown house system, divisional, graha, yoga type or node-aspect mode, or a vara outside 0
|
|
358
|
+
to 6, throws `PanchangError` `INVALID_INPUT`. Before, these crashed with a `TypeError`, returned
|
|
359
|
+
an Invalid Date window, or (yoga type, node-aspect mode) were silently ignored.
|
|
360
|
+
`computeVimshottariPratyantar` with an unknown lord throws `INVALID_INPUT` too (a plain `Error`
|
|
361
|
+
before), and the sidereal-longitude helpers throw `INVALID_DATE` for an Invalid Date (5.3
|
|
362
|
+
returned `NaN`).
|
|
363
|
+
- An Invalid Date in `getUpcomingSolarEclipse` or `getUpcomingLunarEclipse` (5.3: `null`) or in
|
|
364
|
+
`computePlanetaryPositions` (5.3: `NaN` longitudes) throws `INVALID_DATE`. A non-integer or
|
|
365
|
+
out-of-range `timezoneOffsetMinutes` in `buildEclipsesTable` or `buildMoonPhasesTable` throws
|
|
366
|
+
`INVALID_TIMEZONE`; 5.3 built the table.
|
|
367
|
+
- An unknown table language throws a `RangeError` in TypeScript (`INVALID_INPUT` in Go); 5.3
|
|
368
|
+
built the festivals table anyway and crashed with a `TypeError` in the other two builders.
|
|
369
|
+
- One relaxation: `janmaRashi: null` or `janmaNakshatra: null` in `getDailyPanchang` now means the
|
|
370
|
+
same as leaving it out (5.3 threw a `RangeError`).
|
|
371
|
+
- A Moon longitude outside [0, 360) is wrapped into it by all three moon-longitude dashas; NaN or
|
|
372
|
+
Infinity throws `INVALID_INPUT`.
|
|
373
|
+
- `formatInZone` renders any integer offset correctly and throws `INVALID_TIMEZONE` for a
|
|
374
|
+
fractional one (5.3 printed `+00:undefined`).
|
|
375
|
+
- `computePrashnaChart` and `computeKpCuspalSubLords` keep their KP defaults when an option is
|
|
376
|
+
passed as `undefined`.
|
|
377
|
+
|
|
378
|
+
**Documented, not changed**: an omitted `timezone` falls back to the host's zone in untyped
|
|
379
|
+
JavaScript; the Go port reports `INVALID_TIMEZONE` instead, and accepts the zone names `""` (UTC)
|
|
380
|
+
and `"Local"` (the host), which TypeScript rejects.
|
|
381
|
+
|
|
382
|
+
### Faster, with no output changes
|
|
383
|
+
|
|
384
|
+
The full parity documents, every table file and every golden are byte-identical before and
|
|
385
|
+
after. Measured on the same machine, alternating builds, medians:
|
|
386
|
+
|
|
387
|
+
| call | TypeScript | Go |
|
|
388
|
+
|---|---|---|
|
|
389
|
+
| `getDailyPanchang`, a year of days | 1.4x | 1.3x |
|
|
390
|
+
| `getDailyPanchang`, a year in `America/New_York` | 1.5x | 1.4x |
|
|
391
|
+
| `getInstantPanchang`, a year of instants | 1.5x | 1.4x |
|
|
392
|
+
| `computeFestivalsForYear` | 1.8x | 1.5x |
|
|
393
|
+
| `buildMuhurtaTable`, one year | 2.2x | 2.0x |
|
|
394
|
+
| `convertHinduToGregorian` | 6.5x | 5.0x |
|
|
395
|
+
| `getUpcomingEclipses` | 4.6x | 3.9x |
|
|
396
|
+
| `computeSadeSati` | 18x | 16x |
|
|
397
|
+
| `computeKpCuspalSubLords` / `computeBhava` | 12x | 38x |
|
|
398
|
+
| a birth-chart bundle | 2.2x | 2.5x |
|
|
399
|
+
|
|
400
|
+
Most of the causes were repeated work: the same new-moon searches and planet positions recomputed
|
|
401
|
+
across days and charts (now kept in bounded caches keyed by every input, so no result depends on
|
|
402
|
+
which calls ran before it), house cusps computing nine planet positions they never read, the
|
|
403
|
+
converters and table builders building whole days to read four labels, Sade Sati sampling Saturn at
|
|
404
|
+
steps where it cannot change sign, and a timezone formatter rebuilt on every call. One was not: in
|
|
405
|
+
TypeScript, the sine and cosine behind every series evaluation passed their reduced argument through
|
|
406
|
+
module-level variables, and now keep it in locals with the same operations in the same order. That
|
|
407
|
+
change alone gives the chart primitives their whole speedup and most of the gain on a distinct day
|
|
408
|
+
and in the Ekadashi and Sankranti listings; the caches give nearly all of it on a repeated day.
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
188
412
|
## Upgrading to 5.2
|
|
189
413
|
|
|
190
414
|
No type breaks and no removed exports. What changes is output: a set of dates that
|
|
@@ -773,7 +997,7 @@ console.log(i.angas.tithi.name, i.angas.nakshatra.name);
|
|
|
773
997
|
📖 [Festivals →](https://dharmagya.app/docs/panchang-ts/festivals)
|
|
774
998
|
|
|
775
999
|
```typescript
|
|
776
|
-
r.festivals.forEach(f => console.log(f.key, f.name, f.type
|
|
1000
|
+
r.festivals.forEach(f => console.log(f.key, f.name, f.type));
|
|
777
1001
|
// `name` is localized, so match on `key`, never on `name`:
|
|
778
1002
|
const hasDiwali = r.festivals.some(f => f.key === 'diwali');
|
|
779
1003
|
|
|
@@ -914,7 +1138,7 @@ import {
|
|
|
914
1138
|
} from 'panchang-ts';
|
|
915
1139
|
|
|
916
1140
|
const v = computeVarshaphala(birth, 30, loc); // Tajik + Muntha + 27 Sahams
|
|
917
|
-
computeTithiPravesha(birth, 30, loc); //
|
|
1141
|
+
computeTithiPravesha(birth, 30, loc); // natal tithi's Sun-Moon separation returns
|
|
918
1142
|
computeKpSubLord(45.5).subLord; // 243 sub-divisions
|
|
919
1143
|
computePrashnaChart(questionTime, querentLoc); // horary, Placidus-KP default
|
|
920
1144
|
```
|
|
@@ -995,7 +1219,7 @@ InteractionManager.runAfterInteractions(() => {
|
|
|
995
1219
|
|
|
996
1220
|
📖 [Full accuracy notes →](https://dharmagya.app/docs/panchang-ts/accuracy)
|
|
997
1221
|
|
|
998
|
-
|
|
1222
|
+
9,207 tests across 146 files, including fixtures cross-verified against reference
|
|
999
1223
|
panchang calculations spanning 2025-2026 across 10 Indian cities plus New York,
|
|
1000
1224
|
London, Sydney, Dubai, Singapore (diaspora fixtures cover DST on
|
|
1001
1225
|
`America/New_York`).
|
|
@@ -1015,10 +1239,14 @@ London, Sydney, Dubai, Singapore (diaspora fixtures cover DST on
|
|
|
1015
1239
|
| Varjyam windows | count + position vs the reference almanac over a 61-day / two-nakshatra-cycle sweep, ≤2 min (62/62 windows) |
|
|
1016
1240
|
| Sade Sati arc start/end | ±1-2 days vs authoritative ephemerides |
|
|
1017
1241
|
|
|
1018
|
-
**Festival dating**
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1242
|
+
**Festival dating** follows the reference almanac's day choice when a tithi
|
|
1243
|
+
touches two days: the first of two sunrise days (the later one for the Teej and
|
|
1244
|
+
Gangaur Tritiya vratas and Rath Yatra); the day holding more of madhyahna (Ganesh
|
|
1245
|
+
and Vinayaka Chaturthi), of pradosha (Diwali, Dhanteras, Pradosh vrat) or of the
|
|
1246
|
+
nishita muhurta (Shivaratri); three muhurtas after sunrise for Raksha Bandhan,
|
|
1247
|
+
Upakarma, Nag Panchami and Akshaya Tritiya; the Holika Dahan ladder, with Holi on
|
|
1248
|
+
the next day; Chhath counted from its Shashthi. Rules with few published years to
|
|
1249
|
+
check against can still drift ±1 day. The exact list is
|
|
1022
1250
|
[documented](https://dharmagya.app/docs/panchang-ts/accuracy#festival-tradeoff).
|
|
1023
1251
|
|
|
1024
1252
|
**Detection conventions:** Aadal / Vidaal follow the classical Moon-from-Sun
|
|
@@ -1032,36 +1260,40 @@ tyajya spells). Do Ghati does not rotate by weekday.
|
|
|
1032
1260
|
|
|
1033
1261
|
📖 [Full performance notes →](https://dharmagya.app/docs/panchang-ts/performance)
|
|
1034
1262
|
|
|
1035
|
-
Measured at Pune, Apple M-series, Node (median of 11 processes
|
|
1036
|
-
days** is the calendar-scan cost; **same day repeated** is
|
|
1037
|
-
re-rendering one date sees.
|
|
1038
|
-
this release.
|
|
1263
|
+
Measured at Pune, Apple M-series, Node (median of 11 processes, the three builds
|
|
1264
|
+
interleaved). **Distinct days** is the calendar-scan cost; **same day repeated** is
|
|
1265
|
+
what a UI re-rendering one date sees. The last two columns are the published 5.3.0
|
|
1266
|
+
and 4.3.1 packages, benchmarked beside this release.
|
|
1039
1267
|
|
|
1040
|
-
| `getDailyPanchang` call | Distinct days | Same day repeated | 4.3.1 (distinct) |
|
|
1041
|
-
|
|
1042
|
-
| Default (all sections + end-times) | **~0.
|
|
1043
|
-
| `sections: []` + `computeEndTimes: false` | ~0.
|
|
1044
|
-
| `getInstantPanchang` | ~0.
|
|
1268
|
+
| `getDailyPanchang` call | Distinct days | Same day repeated | 5.3.0 (distinct) | 4.3.1 (distinct) |
|
|
1269
|
+
|---|---|---|---|---|
|
|
1270
|
+
| Default (all sections + end-times) | **~0.30 ms** | **~0.10 ms** | ~0.41 ms | ~5.83 ms |
|
|
1271
|
+
| `sections: []` + `computeEndTimes: false` | ~0.16 ms | ~0.05 ms | ~0.26 ms | n/a |
|
|
1272
|
+
| `getInstantPanchang` | ~0.13 ms | ~0.02 ms | ~0.22 ms | ~0.44 ms |
|
|
1045
1273
|
|
|
1046
|
-
**A default day is ~
|
|
1274
|
+
**A default day is ~1.4× cheaper than 5.3.0 and ~20× cheaper than 4.3.1**, a
|
|
1275
|
+
repeated day ~1.9× and ~66×. The levers:
|
|
1047
1276
|
|
|
1048
1277
|
- **`sections`** skips the optional ephemeris-backed blocks (`'festivals'`,
|
|
1049
|
-
`'eclipse'`, `'moonTimes'`, `'lunarWindows'`).
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1278
|
+
`'eclipse'`, `'moonTimes'`, `'lunarWindows'`). A narrowed call's values equal
|
|
1279
|
+
the full call's and omitted sections sit at their documented `null` / `[]`,
|
|
1280
|
+
with three couplings: `'festivals'` also fills `moon.rise` and
|
|
1281
|
+
`inauspicious.bhadra`, which it needs, and the Surya/Chandra Grahan entry in
|
|
1282
|
+
`festivals` comes with `'eclipse'`, so `['festivals']` alone omits it.
|
|
1283
|
+
- **`computeEndTimes: false`** drops the published end times and the yoga and
|
|
1284
|
+
karana transition searches (`specialYogas` still covers the whole day);
|
|
1285
|
+
~2-5%. Use it to drop fields you don't want, not to go faster.
|
|
1286
|
+
|
|
1287
|
+
Range helpers narrow internally: `computeEkadashiDatesForYear` **~16 ms/year**
|
|
1288
|
+
(5.3.0: ~19, 4.3.1: ~2,410), `computeFestivalsInRange` **~79 ms/year** (~136, ~2,230),
|
|
1289
|
+
`computeSankrantisForYear` **~2.8 ms/year** (~3.3, ~160). Solar rise/set events are
|
|
1058
1290
|
cached process-wide (bounded, 20k entries), which also makes them
|
|
1059
1291
|
single-valued.
|
|
1060
1292
|
|
|
1061
1293
|
One deliberate regression: raw chart primitives (`computeRashiChart`,
|
|
1062
|
-
`computeNavamsa`) cost ~0.
|
|
1294
|
+
`computeNavamsa`) cost ~0.18 ms vs ~0.10 in 4.3.1 (5.3.0: ~0.32), the price of an
|
|
1063
1295
|
order-of-magnitude accuracy gain against JPL DE441. `computeShadbala` /
|
|
1064
|
-
`computeBhavaBala` went the other way, ~
|
|
1296
|
+
`computeBhavaBala` went the other way, ~3.6× to 3.7× faster than 4.3.1.
|
|
1065
1297
|
|
|
1066
1298
|
---
|
|
1067
1299
|
|
|
@@ -1085,11 +1317,15 @@ try {
|
|
|
1085
1317
|
Error codes: `INVALID_DATE`, `INVALID_LATITUDE`, `INVALID_LONGITUDE`,
|
|
1086
1318
|
`INVALID_ELEVATION`, `INVALID_TIMEZONE`, `INVALID_AYANAMSA`, `INVALID_INPUT`,
|
|
1087
1319
|
`TIMEZONE_RESOLUTION_FAILED`, `NO_SUNRISE`, `NO_SUNSET`, `SEARCH_DIVERGED`,
|
|
1088
|
-
`CIRCUMPOLAR` (Placidus-KP houses
|
|
1320
|
+
`CIRCUMPOLAR` and `PLACIDUS_DIVERGED` (Placidus-KP houses beyond the polar
|
|
1321
|
+
circles, |latitude| above about 66.56°; whole-sign and equal houses still work
|
|
1322
|
+
there), `SAHAM_DEPENDENCY_ERROR` (an internal Varshaphala saham ordering fault).
|
|
1089
1323
|
|
|
1090
1324
|
**Polar locations.** `getDailyPanchang` and `getInstantPanchang` return `null`
|
|
1091
1325
|
rather than throwing: the Hindu day is undefined when sunrise can't be
|
|
1092
|
-
computed
|
|
1326
|
+
computed, including on the civil day a polar night or midnight sun ends,
|
|
1327
|
+
whose first sunrise belongs to the next day. The low-level `getSunrise` /
|
|
1328
|
+
`getSunset` primitives still throw
|
|
1093
1329
|
`PanchangError(NO_SUNRISE)` / `PanchangError(NO_SUNSET)` for direct callers
|
|
1094
1330
|
who need the precise reason. `getMoonrise` / `getMoonset` return `null` (normal
|
|
1095
1331
|
for the Moon).
|