mirror of
https://github.com/acamarata/temporal-hijri.git
synced 2026-06-30 19:04:29 +00:00
HijriCalendar.toHijri() previously used new Date(y, m, d) (local-time constructor). Under hijri-core's new UTC-day contract the engine reads the UTC calendar day, so on east-of-UTC hosts (e.g. UTC+5) the local midnight falls on the previous UTC date, producing a one-day-off Hijri result. Fix: use Date.UTC(y, m, d) so PlainDate calendar fields land in the Date's UTC components, matching what hijri-core reads. Lock-step dependency: this fix requires the unreleased hijri-core change on fix/utc-day-boundary (commit 3419378). Both packages will be released together per ADR-013. Tests: round-trip regression added (2025-03-01 = 1 Ramadan 1446 AH); all 37 ESM + 9 CJS tests pass at TZ=UTC, TZ=America/New_York, TZ=Pacific/Auckland.
78 lines
3.2 KiB
Markdown
78 lines
3.2 KiB
Markdown
[](https://www.npmjs.com/package/temporal-hijri)
|
|
[](https://github.com/acamarata/temporal-hijri/actions/workflows/ci.yml)
|
|
[](LICENSE)
|
|
|
|
# temporal-hijri
|
|
|
|
Temporal Calendar Protocol implementation for the Hijri calendar. Works with the TC39
|
|
Temporal proposal (Stage 3) and `@js-temporal/polyfill`.
|
|
|
|
Provides `UaqCalendar` (Umm al-Qura) and `FcnaCalendar` (FCNA/ISNA) as plug-in
|
|
calendars for `Temporal.PlainDate`. The underlying conversion logic comes from
|
|
[hijri-core](https://github.com/acamarata/hijri-core).
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
pnpm add temporal-hijri hijri-core
|
|
# Add the polyfill if native Temporal is unavailable:
|
|
pnpm add @js-temporal/polyfill
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
```typescript
|
|
import { Temporal } from '@js-temporal/polyfill';
|
|
import { uaqCalendar } from 'temporal-hijri';
|
|
|
|
const isoDate = Temporal.PlainDate.from('2023-03-23');
|
|
|
|
console.log(uaqCalendar.year(isoDate)); // 1444
|
|
console.log(uaqCalendar.month(isoDate)); // 9 (Ramadan)
|
|
console.log(uaqCalendar.day(isoDate)); // 1
|
|
|
|
// Convert Hijri coordinates to ISO
|
|
const ramadan = uaqCalendar.dateFromFields({ year: 1444, month: 9, day: 1 });
|
|
console.log(ramadan.toString()); // "2023-03-23"
|
|
|
|
// Date arithmetic in Hijri space
|
|
const { Duration } = Temporal;
|
|
const nextMonth = uaqCalendar.dateAdd(isoDate, new Duration(0, 1));
|
|
console.log(uaqCalendar.month(nextMonth)); // 10 (Shawwal)
|
|
```
|
|
|
|
## Calendars
|
|
|
|
| Calendar | ID | Authority | Method | Coverage |
|
|
|-------------|--------------|--------------------|--------------------------|------------------|
|
|
| Umm al-Qura | `hijri-uaq` | KACST, Saudi Arabia | Pre-calculated tables | 1318-1500 AH |
|
|
| FCNA/ISNA | `hijri-fcna` | Fiqh Council of NA | Astronomical new moon | Unbounded |
|
|
|
|
## Documentation
|
|
|
|
Full reference in the [wiki](https://github.com/acamarata/temporal-hijri/wiki).
|
|
|
|
- [API Reference](https://github.com/acamarata/temporal-hijri/wiki/API-Reference)
|
|
- [Architecture](https://github.com/acamarata/temporal-hijri/wiki/Architecture)
|
|
- [Examples](https://github.com/acamarata/temporal-hijri/wiki/examples/basic-usage)
|
|
|
|
## Conversion behavior
|
|
|
|
Conversions between ISO and Hijri dates are pure calendar-date mappings: the same
|
|
ISO date always maps to the same Hijri date on every machine, regardless of the host's
|
|
timezone. `Temporal.PlainDate` carries no time-of-day information, and the underlying
|
|
hijri-core engine operates on UTC calendar days, so there is no timezone dependency.
|
|
|
|
Note: the Islamic calendar begins a new day at sunset, not midnight. This library
|
|
follows the civil-calendar convention (midnight boundary) used by most software. Sunset
|
|
day-start determination is out of scope.
|
|
|
|
## Related
|
|
|
|
- [hijri-core](https://github.com/acamarata/hijri-core): the underlying calendar engine
|
|
- [luxon-hijri](https://github.com/acamarata/luxon-hijri): Hijri support for Luxon
|
|
- [pray-calc](https://github.com/acamarata/pray-calc): Islamic prayer times
|
|
|
|
## License
|
|
|
|
MIT. Copyright (c) 2026 Aric Camarata. See [LICENSE](LICENSE).
|