Skip to content

Version 0.4.3 is tagged on GitHub and is not published on npm. A beta will be published before the stable 1.0.0.

Date adapter

Two adapters can drive a Material datepicker. Register one of them. HijriDateAdapter is the main adapter. NativeHijriDateAdapter is the alternative when the stored value has to be a JavaScript Date.

Main adapterAlternative
ProviderprovideHijriDateAdapter()provideNativeHijriDateAdapter()
Importngx-mat-hijri-adapterngx-mat-hijri-adapter/native
Stored valueCalendarDateDate at UTC noon
Calendar math@internationalized/dateIn-repo Umm al-Qura table
Names and formattingPackage month names and digitsIntl
Works withDatepicker, reactive fields, signal fieldsDatepicker

HijriDateAdapter

This is the main adapter. It implements DateAdapter<CalendarDate> for the Umm al-Qura and Gregorian calendars. ng add registers it, and the reactive and signal fields provide their own instance of it.

provideHijriDateAdapter() registers the adapter together with MAT_DATE_FORMATS and MAT_DATE_LOCALE. Call it once from the application providers. Its options are:

  • calendar: 'gregorian' or 'islamic-umalqura'. Defaults to islamic-umalqura.
  • locale: digits, Gregorian month names, weekday names, and the first day of the week. Hijri month names stay the package's Arabic and English names. Defaults to ar-SA.
  • timeZone: used by today(). Defaults to the runtime time zone.
  • firstDayOfWeek: 0 for Sunday through 6 for Saturday. Defaults to the locale's week info.
  • formats: Material format slots. Defaults to HIJRI_DATE_FORMATS. Numeric dates render as day/month/year. Named dates render as day month, year.
ts
import { CalendarCode, CalendarLocale, provideHijriDateAdapter } from 'ngx-mat-hijri-adapter';

bootstrapApplication(App, {
  providers: [
    provideHijriDateAdapter({
      calendar: CalendarCode.gregorian,
      locale: CalendarLocale.enUS,
      timeZone: 'UTC',
    }),
  ],
});

A datepicker then stores a CalendarDate. Parsing accepts numeric dates, ISO YYYY-MM-DD in the adapter calendar, and Hijri month names, including Arabic-Indic and Persian digits.

ts
import type { CalendarDate } from '@internationalized/date';

date = new FormControl<CalendarDate | null>(null);
html
<mat-form-field>
  <mat-label>Date</mat-label>
  <input matInput [matDatepicker]="picker" [formControl]="date" />
  <mat-datepicker-toggle matIconSuffix [for]="picker" />
  <mat-datepicker #picker />
</mat-form-field>

NativeHijriDateAdapter

This provider is an alternative for a plain mat-datepicker that stores a Date. The restrictions, and the live examples, are on the Native adapter.

Locale is not the calendar

On both adapters, calendar and locale are independent. ar-SA does not select the Hijri calendar, en-US does not select Gregorian, and a Hijri calendar does not force Saturday as the week start. In this runtime, en-US and ar-SA start the week on Sunday, and ar-EG starts it on Saturday. setLocale updates those rules and leaves the calendar as it is.

Switching calendars

setCalendar() switches an adapter instance at runtime, and calendar reads the current one. Material redraws through localeChanges. On HijriDateAdapter, later reads convert the CalendarDate into the new calendar. On NativeHijriDateAdapter, the Date stays the same instant and later reads use the new calendar, so 1 Ramadan 1445 reads as 11 March 2024. Use setCalendar() on an adapter provided to a single component, as the reactive and signal fields do.

ts
const adapter = inject(DateAdapter) as HijriDateAdapter;

adapter.setCalendar(CalendarCode.gregorian);
adapter.calendar; // 'gregorian'

Month indexing

Both adapters follow Material's 0-based months. The calendar helpers on the main entry are 1-based. createDate throws for a month outside 0–11, a day outside that month, or an Umm al-Qura year outside 1300–1599. Adding months clamps to the last valid day. Adding a year or month that leaves AH 1300–1599 returns an invalid date.

ts
adapter.createDate(1445, 8, 1); // 1 Ramadan 1445: Material months are 0-based
adapter.addCalendarMonths(adapter.createDate(1445, 8, 30), 1); // 29 Shawwal 1445

Time methods are not implemented.