mirror of
https://github.com/acamarata/hijri-core.git
synced 2026-07-02 19:50:40 +00:00
docs: add quickstart, advanced guide, and examples for hijri-core
This commit is contained in:
parent
4d231b8aec
commit
b6ee3b08d0
4 changed files with 325 additions and 0 deletions
48
.github/wiki/examples/gregorian-to-hijri.md
vendored
Normal file
48
.github/wiki/examples/gregorian-to-hijri.md
vendored
Normal 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
|
||||||
|
```
|
||||||
53
.github/wiki/examples/ramadan-calendar.md
vendored
Normal file
53
.github/wiki/examples/ramadan-calendar.md
vendored
Normal 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
130
.github/wiki/guides/advanced.md
vendored
Normal 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
94
.github/wiki/guides/quickstart.md
vendored
Normal 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
|
||||||
Loading…
Reference in a new issue