mirror of
https://github.com/acamarata/luxon-hijri.git
synced 2026-07-01 11:14:29 +00:00
126 lines
3.5 KiB
Markdown
126 lines
3.5 KiB
Markdown
# Advanced Usage
|
||
|
||
## Format tokens
|
||
|
||
All Hijri-specific tokens use the `i` prefix. For the full token table, see the [API Reference](../API-Reference).
|
||
|
||
Common tokens:
|
||
|
||
| Token | Example | Description |
|
||
|-------|---------|-------------|
|
||
| `iD` | `1`–`30` | Hijri day, no padding |
|
||
| `iDD` | `01`–`30` | Hijri day, zero-padded |
|
||
| `iM` | `1`–`12` | Hijri month number, no padding |
|
||
| `iMM` | `01`–`12` | Hijri month number, zero-padded |
|
||
| `iMMMM` | `Ramadan` | Full Hijri month name |
|
||
| `iYY` | `46` | Last two digits of Hijri year |
|
||
| `iYYYY` | `1446` | Full Hijri year |
|
||
| `ioooo` | `AH` | Hijri era |
|
||
|
||
```js
|
||
import { toHijri, formatHijriDate } from 'luxon-hijri';
|
||
|
||
const h = toHijri(new Date('2025-03-20'));
|
||
|
||
console.log(formatHijriDate(h, 'iDD/iMM/iYYYY')); // 20/09/1446
|
||
console.log(formatHijriDate(h, 'iD iMMMM iYYYY')); // 20 Ramadan 1446
|
||
console.log(formatHijriDate(h, 'iD iMMMM iYYYY ioooo')); // 20 Ramadan 1446 AH
|
||
```
|
||
|
||
## Hijri date arithmetic with Luxon
|
||
|
||
Luxon handles Gregorian arithmetic. Use `toGregorian` to convert Hijri endpoints, then work in Gregorian:
|
||
|
||
```js
|
||
import { DateTime } from 'luxon';
|
||
import { toHijri, toGregorian } from 'luxon-hijri';
|
||
|
||
// Find when Eid al-Fitr (1 Shawwal) starts for this year
|
||
const today = new Date();
|
||
const h = toHijri(today);
|
||
|
||
if (h) {
|
||
const eidStart = toGregorian(h.hy, 10, 1); // 1 Shawwal
|
||
const eid = DateTime.fromJSDate(eidStart);
|
||
console.log(`Eid al-Fitr ${h.hy}: ${eid.toFormat('MMMM d, yyyy')}`);
|
||
}
|
||
```
|
||
|
||
## Generating a Hijri month calendar
|
||
|
||
The UAQ table encodes day counts per month in a bitmask. To iterate a month, convert each Hijri day to Gregorian and stop when `toGregorian` throws:
|
||
|
||
```js
|
||
import { toGregorian } from 'luxon-hijri';
|
||
import { DateTime } from 'luxon';
|
||
|
||
const HY = 1446;
|
||
const HM = 9; // Ramadan
|
||
|
||
// Determine the month length (29 or 30 days)
|
||
let days = 29;
|
||
try { toGregorian(HY, HM, 30); days = 30; } catch (_) {}
|
||
|
||
const NAMES = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
||
|
||
console.log(`Ramadan ${HY}\n`);
|
||
console.log(NAMES.join(' '));
|
||
|
||
const firstGreg = DateTime.fromJSDate(toGregorian(HY, HM, 1));
|
||
let line = ' '.repeat(firstGreg.weekday % 7); // Sunday = 0
|
||
|
||
for (let d = 1; d <= days; d++) {
|
||
const greg = DateTime.fromJSDate(toGregorian(HY, HM, d));
|
||
line += String(d).padStart(3) + ' ';
|
||
if (greg.weekday === 6) { // Saturday ends row
|
||
console.log(line);
|
||
line = '';
|
||
}
|
||
}
|
||
if (line.trim()) console.log(line);
|
||
```
|
||
|
||
## FCNA vs UAQ differences
|
||
|
||
FCNA and UAQ can differ by a day around month transitions:
|
||
|
||
```js
|
||
import { toHijri } from 'luxon-hijri';
|
||
|
||
const borderDates = [
|
||
new Date('2025-02-28'),
|
||
new Date('2025-03-01'),
|
||
new Date('2025-03-02'),
|
||
];
|
||
|
||
for (const d of borderDates) {
|
||
const uaq = toHijri(d, { calendar: 'uaq' });
|
||
const fcna = toHijri(d, { calendar: 'fcna' });
|
||
|
||
const fmt = h => h ? `${h.hd}/${h.hm}/${h.hy}` : 'null';
|
||
console.log(`${d.toISOString().slice(0, 10)} UAQ: ${fmt(uaq)} FCNA: ${fmt(fcna)}`);
|
||
}
|
||
```
|
||
|
||
## Batch conversion
|
||
|
||
```js
|
||
import { toHijri } from 'luxon-hijri';
|
||
|
||
const isoList = [
|
||
'2025-01-01', '2025-03-01', '2025-03-30',
|
||
'2025-06-06', '2025-12-31',
|
||
];
|
||
|
||
for (const iso of isoList) {
|
||
const h = toHijri(new Date(iso));
|
||
const result = h ? `${h.hd}/${h.hm}/${h.hy} AH` : 'out of range';
|
||
console.log(`${iso} → ${result}`);
|
||
}
|
||
```
|
||
|
||
## Related pages
|
||
|
||
- [API Reference](../API-Reference) — all functions, format tokens, types
|
||
- [Hijri Calendar](../Hijri-Calendar) — background on UAQ and FCNA calendar systems
|
||
- [Architecture](../Architecture) — internals, conversion engine, accuracy
|