docs: add quickstart, advanced guide, and examples for hijri-core

This commit is contained in:
Aric Camarata 2026-05-28 14:14:20 -04:00
parent 4d231b8aec
commit b6ee3b08d0
4 changed files with 325 additions and 0 deletions

View file

@ -0,0 +1,48 @@
# Example: Gregorian to Hijri Conversion Table
Convert a range of notable Gregorian dates to Hijri.
```js
import { toHijri } from 'hijri-core';
const MONTH_NAMES = [
'', 'Muharram', 'Safar', "Rabi' al-Awwal", "Rabi' al-Thani",
'Jumada al-Ula', 'Jumada al-Akhirah', 'Rajab', "Sha'ban",
'Ramadan', 'Shawwal', "Dhu al-Qi'dah", 'Dhu al-Hijjah',
];
const dates = [
{ label: 'Islamic New Year 1446', date: new Date('2024-07-07') },
{ label: 'Ashura 1446', date: new Date('2024-07-16') },
{ label: 'Ramadan 1446 start', date: new Date('2025-03-01') },
{ label: 'Eid al-Fitr 1446', date: new Date('2025-03-30') },
{ label: 'Arafat Day 1446', date: new Date('2025-06-05') },
{ label: 'Eid al-Adha 1446', date: new Date('2025-06-06') },
];
console.log(`${'Event'.padEnd(26)} Gregorian Hijri`);
console.log('-'.repeat(62));
for (const { label, date } of dates) {
const h = toHijri(date);
const greg = date.toISOString().slice(0, 10);
const hijri = h
? `${h.day} ${MONTH_NAMES[h.month]} ${h.year} AH`
: 'out of range';
console.log(`${label.padEnd(26)} ${greg} ${hijri}`);
}
```
Sample output:
```
Event Gregorian Hijri
--------------------------------------------------------------
Islamic New Year 1446 2024-07-07 1 Muharram 1446 AH
Ashura 1446 2024-07-16 10 Muharram 1446 AH
Ramadan 1446 start 2025-03-01 1 Ramadan 1446 AH
Eid al-Fitr 1446 2025-03-30 1 Shawwal 1446 AH
Arafat Day 1446 2025-06-05 9 Dhu al-Hijjah 1446 AH
Eid al-Adha 1446 2025-06-06 10 Dhu al-Hijjah 1446 AH
```

View file

@ -0,0 +1,53 @@
# Example: Ramadan Calendar Generator
Generate the full Ramadan calendar for a given Hijri year showing Gregorian dates.
```js
import { toGregorian, daysInHijriMonth } from 'hijri-core';
const HIJRI_YEAR = 1446;
const RAMADAN = 9;
const totalDays = daysInHijriMonth(HIJRI_YEAR, RAMADAN);
console.log(`Ramadan ${HIJRI_YEAR} AH — ${totalDays} days`);
console.log('');
console.log('Day Gregorian Weekday');
console.log('-'.repeat(32));
const DAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
for (let d = 1; d <= totalDays; d++) {
const greg = toGregorian(HIJRI_YEAR, RAMADAN, d);
const iso = greg.toISOString().slice(0, 10);
const weekday = DAYS[greg.getUTCDay()];
// Mark Jumu'ah
const marker = weekday === 'Friday' ? ' ★' : '';
console.log(`${String(d).padStart(3)} ${iso} ${weekday}${marker}`);
}
```
Sample output:
```
Ramadan 1446 AH — 30 days
Day Gregorian Weekday
--------------------------------
1 2025-03-01 Saturday
2 2025-03-02 Sunday
3 2025-03-03 Monday
4 2025-03-04 Tuesday
5 2025-03-05 Wednesday
6 2025-03-06 Thursday
7 2025-03-07 Friday ★
8 2025-03-08 Saturday
...
28 2025-03-28 Friday ★
29 2025-03-29 Saturday
30 2025-03-30 Sunday
```
> Eid al-Fitr falls on 1 Shawwal — the day after the last day of Ramadan.

130
.github/wiki/guides/advanced.md vendored Normal file
View file

@ -0,0 +1,130 @@
# Advanced Usage
## Iterating over a Hijri month
Build a calendar grid for a given Hijri month:
```js
import { daysInHijriMonth, toGregorian } from 'hijri-core';
const HY = 1446;
const HM = 9; // Ramadan
const days = daysInHijriMonth(HY, HM);
for (let d = 1; d <= days; d++) {
const greg = toGregorian(HY, HM, d);
console.log(`${String(d).padStart(2)} Ramadan — ${greg.toISOString().slice(0, 10)}`);
}
```
## Custom calendar engines
`hijri-core` exposes a registry so you can plug in your own conversion engine — a lunar sighting authority, an adjusted algorithmic calendar, or a custom dataset:
```js
import { registerCalendar, toHijri } from 'hijri-core';
registerCalendar('my-calendar', {
toHijri(date) {
// Return { year, month, day, monthName, calendar: 'my-calendar' } or null
// date is a JS Date; use local components for timezone-safe lookup
const y = date.getFullYear();
const m = date.getMonth() + 1;
const d = date.getDate();
// ... your logic
return null;
},
toGregorian(hy, hm, hd) {
// Return a Date (UTC midnight) or null for out-of-range
return null;
},
isValidHijriDate(hy, hm, hd) {
return false;
},
daysInHijriMonth(hy, hm) {
return 29;
},
});
// Use it just like the built-in calendars
const result = toHijri(new Date('2025-03-20'), { calendar: 'my-calendar' });
```
## Generating a Ramadan calendar
Print the Gregorian dates for Ramadan across multiple years:
```js
import { toGregorian } from 'hijri-core';
const RAMADAN = 9;
for (let hy = 1440; hy <= 1450; hy++) {
const start = toGregorian(hy, RAMADAN, 1);
const end = toGregorian(hy, RAMADAN + 1, 1);
if (!start) continue;
// Ramadan ends the day before Shawwal 1
const last = new Date(end.getTime() - 86400_000);
console.log(
`${hy} AH: ${start.toISOString().slice(0, 10)} — ${last.toISOString().slice(0, 10)}`
);
}
```
## Date range validation
Before batch-processing a range of dates, check the calendar bounds:
```js
import { toHijri } from 'hijri-core';
function isSupportedDate(date) {
return toHijri(date) !== null;
}
const dates = [
new Date('1900-01-01'), // outside UAQ range
new Date('2000-01-01'), // inside range
new Date('2077-11-16'), // may be outside future range
];
for (const d of dates) {
const supported = isSupportedDate(d);
console.log(`${d.toISOString().slice(0, 10)}: ${supported ? 'supported' : 'out of range'}`);
}
```
## FCNA vs UAQ differences
FCNA and UAQ can differ by one or two days around month transitions:
```js
import { toHijri } from 'hijri-core';
const dates = [
new Date('2025-03-01'),
new Date('2025-03-29'),
new Date('2025-03-30'),
new Date('2025-03-31'),
];
console.log('Date UAQ FCNA');
console.log('-'.repeat(48));
for (const d of dates) {
const uaq = toHijri(d, { calendar: 'uaq' });
const fcna = toHijri(d, { calendar: 'fcna' });
const fmtH = (h) => h ? `${h.day}/${h.month}/${h.year}` : 'out of range';
console.log(`${d.toISOString().slice(0, 10)} ${fmtH(uaq).padEnd(16)} ${fmtH(fcna)}`);
}
```
## Related pages
- [API Reference](../API-Reference) — full function signatures and types
- [Architecture](../Architecture) — calendar engine interface, table format, accuracy bounds

94
.github/wiki/guides/quickstart.md vendored Normal file
View file

@ -0,0 +1,94 @@
# Quick Start
Five minutes from install to Hijri date conversions.
## Install
```sh
npm install hijri-core
```
## Convert Gregorian to Hijri
```js
import { toHijri } from 'hijri-core';
const d = new Date('2025-03-20');
const h = toHijri(d);
console.log(h);
// { year: 1446, month: 9, day: 20, monthName: 'Ramadan', calendar: 'uaq' }
console.log(`${h.day} ${h.monthName} ${h.year} AH`);
// 20 Ramadan 1446 AH
```
## Convert Hijri to Gregorian
```js
import { toGregorian } from 'hijri-core';
const greg = toGregorian(1446, 9, 1);
console.log(greg.toISOString().slice(0, 10));
// 2025-03-01
```
## Check a Hijri date is valid
```js
import { isValidHijriDate } from 'hijri-core';
isValidHijriDate(1446, 9, 30); // true — Ramadan 1446 has 30 days
isValidHijriDate(1446, 9, 31); // false — no 31st day in any Hijri month
isValidHijriDate(1446, 13, 1); // false — Hijri calendar has only 12 months
```
## Days in a month
```js
import { daysInHijriMonth } from 'hijri-core';
daysInHijriMonth(1446, 9); // 30 (Ramadan 1446)
daysInHijriMonth(1446, 10); // 29 (Shawwal 1446)
```
## Choosing a calendar
Two calendars are built in:
| Name | Description |
| ---- | ----------- |
| `'uaq'` | Umm al-Qura (Saudi Arabia, official tabular calendar) — **default** |
| `'fcna'` | Fiqh Council of North America (astronomical computation for North America) |
```js
import { toHijri } from 'hijri-core';
const d = new Date('2025-03-20');
const uaq = toHijri(d, { calendar: 'uaq' });
const fcna = toHijri(d, { calendar: 'fcna' });
console.log(uaq.day, uaq.month, uaq.year);
console.log(fcna.day, fcna.month, fcna.year);
```
## Out-of-range dates
Both built-in calendars cover a finite date range. `toHijri` and `toGregorian` return `null` when the input falls outside the supported range:
```js
import { toHijri } from 'hijri-core';
const result = toHijri(new Date('1800-01-01'));
if (result === null) {
console.log('Date outside calendar range');
}
```
## Next steps
- [API Reference](../API-Reference) — all functions and types
- [Advanced Guide](advanced) — custom calendar engines, iteration, Ramadan calendars
- [Architecture](../Architecture) — calendar engine design, table format