No description
Find a file
2026-02-25 15:08:47 -05:00
.github/workflows feat: initial release of hijri-core v1.0.0 2026-02-25 14:06:02 -05:00
.wiki chore: pre-release CR/QA polish for v1.0.0 2026-02-25 15:07:32 -05:00
src chore: pre-release CR/QA polish for v1.0.0 2026-02-25 15:07:32 -05:00
.editorconfig feat: initial release of hijri-core v1.0.0 2026-02-25 14:06:02 -05:00
.gitignore feat: initial release of hijri-core v1.0.0 2026-02-25 14:06:02 -05:00
.npmrc chore: clear .npmrc to remove pnpm-only key that warns on npm publish 2026-02-25 15:08:47 -05:00
.nvmrc feat: initial release of hijri-core v1.0.0 2026-02-25 14:06:02 -05:00
CHANGELOG.md feat: initial release of hijri-core v1.0.0 2026-02-25 14:06:02 -05:00
LICENSE feat: initial release of hijri-core v1.0.0 2026-02-25 14:06:02 -05:00
package.json chore: pre-release CR/QA polish for v1.0.0 2026-02-25 15:07:32 -05:00
pnpm-lock.yaml feat: initial release of hijri-core v1.0.0 2026-02-25 14:06:02 -05:00
pnpm-workspace.yaml feat: initial release of hijri-core v1.0.0 2026-02-25 14:06:02 -05:00
README.md chore: pre-release CR/QA polish for v1.0.0 2026-02-25 15:07:32 -05:00
test-cjs.cjs chore: pre-release CR/QA polish for v1.0.0 2026-02-25 15:07:32 -05:00
test.mjs chore: pre-release CR/QA polish for v1.0.0 2026-02-25 15:07:32 -05:00
tsconfig.json feat: initial release of hijri-core v1.0.0 2026-02-25 14:06:02 -05:00
tsup.config.ts feat: initial release of hijri-core v1.0.0 2026-02-25 14:06:02 -05:00

hijri-core

npm CI license

Zero-dependency Hijri calendar engine. Supports the Umm al-Qura (UAQ) and FCNA/ISNA calendars out of the box. Extensible via a calendar registry for custom implementations.

Installation

npm install hijri-core
# or
pnpm add hijri-core

Quick Start

import { toHijri, toGregorian, isValidHijriDate, daysInHijriMonth } from 'hijri-core';

// Gregorian to Hijri (UAQ, default)
const hijri = toHijri(new Date(2025, 2, 1));
// { hy: 1446, hm: 9, hd: 1 }

// Hijri to Gregorian (UAQ)
const greg = toGregorian(1446, 9, 1);
// Date: 2025-03-01

// FCNA/ISNA calendar
const hijriFcna = toHijri(new Date('2025-03-01'), { calendar: 'fcna' });
const gregFcna  = toGregorian(1446, 9, 1, { calendar: 'fcna' });

// Validation and month length
isValidHijriDate(1444, 9, 1);  // true
daysInHijriMonth(1444, 9);     // 29

Custom Calendar

import { registerCalendar, toHijri, type CalendarEngine } from 'hijri-core';

const myEngine: CalendarEngine = {
  id: 'my-calendar',
  toHijri: (date) => { /* your logic */ return { hy: 1446, hm: 1, hd: 1 }; },
  toGregorian: (hy, hm, hd) => { /* your logic */ return new Date(); },
  isValid: (hy, hm, hd) => hy > 0 && hm >= 1 && hm <= 12 && hd >= 1,
  daysInMonth: (hy, hm) => 30,
};

registerCalendar('my-calendar', myEngine);

const result = toHijri(new Date(), { calendar: 'my-calendar' });

API

Conversion functions

Function Parameters Returns Notes
toHijri(date, opts?) Date, ConversionOptions? HijriDate | null Throws on invalid Date
toGregorian(hy, hm, hd, opts?) number, number, number, ConversionOptions? Date | null Returns null on invalid input
isValidHijriDate(hy, hm, hd, opts?) number, number, number, ConversionOptions? boolean
daysInHijriMonth(hy, hm, opts?) number, number, ConversionOptions? number

ConversionOptions.calendar defaults to 'uaq'. Pass 'fcna' or any registered calendar name.

Registry functions

Function Parameters Returns
registerCalendar(name, engine) string, CalendarEngine void
getCalendar(name) string CalendarEngine
listCalendars() none string[]

Data exports

Export Type Description
hDatesTable HijriYearRecord[] Full Umm al-Qura reference table (184 entries)
hmLong string[] Long month names (e.g., "Ramadan")
hmMedium string[] Medium month names (e.g., "Ramadan")
hmShort string[] Short month names (e.g., "Ram")
hwLong string[] Long weekday names
hwShort string[] Short weekday names
hwNumeric number[] Weekday numbers (1 = Sunday)

Custom Calendars

Implement the CalendarEngine interface to add any calendar system:

interface CalendarEngine {
  readonly id: string;
  toHijri(date: Date): HijriDate | null;
  toGregorian(hy: number, hm: number, hd: number): Date | null;
  isValid(hy: number, hm: number, hd: number): boolean;
  daysInMonth(hy: number, hm: number): number;
}

Register with registerCalendar('my-id', myEngine). Then pass { calendar: 'my-id' } to any conversion function.

Compatibility

  • Node.js 20, 22, 24
  • Modern browsers (ESM build)
  • CommonJS and ESM

TypeScript

import type { HijriDate, HijriYearRecord, CalendarEngine, ConversionOptions } from 'hijri-core';

Documentation

Full API reference and architecture notes: GitHub Wiki

License

MIT. Copyright (c) 2024-2026 Aric Camarata.