misri_hijri 0.1.0 copy "misri_hijri: ^0.1.0" to clipboard
misri_hijri: ^0.1.0 copied to clipboard

Hijri calendar dates for Dart/Flutter with a choice of calculation system — Misri (fixed tabular, 30-year cycle) or Umm al-Qura (Saudi official, astronomical lookup table) — behind one shared API.

misri_hijri #

Hijri (Islamic) calendar dates for Dart and Flutter, with a choice of calculation system behind one shared API:

Engine Type How it works Range
MisriHijriCalendar HijriCalendarType.misri Fixed tabular (arithmetical) calendar: a 30-year cycle with a deterministic leap-year pattern. No lookup table, no moon-sighting. Any year, past or future
UmmAlQuraCalendar HijriCalendarType.ummAlQura Saudi Arabia's official calendar, backed by an astronomical month-start lookup table. Supports manual regional adjustments. ~1356–1500 AH (14 Mar 1937 – 16 Nov 2077 CE)

Pure Dart — no Flutter dependency, so it works in Flutter apps, server-side Dart, and CLI tools alike.

Install #

dependencies:
  misri_hijri: ^0.1.0

Quick start #

import 'package:misri_hijri/misri_hijri.dart';

void main() {
  // Pick an engine with a single parameter.
  final today = Hijri.now(type: HijriCalendarType.ummAlQura);
  print(today.format('DDDD, dd MMMM yyyy'));

  // Convert from Gregorian.
  final d = Hijri.fromDate(
    DateTime(2025, 3, 20),
    type: HijriCalendarType.misri,
  );
  print('${d.year}-${d.month}-${d.day}');

  // Build from an explicit Hijri date and go back to Gregorian.
  final eid = Hijri.fromHijri(1446, 10, 1, type: HijriCalendarType.ummAlQura);
  print(eid.toDateTime()); // DateTime
}

Or use an engine directly when you always know which calendar you need:

final m = MisriHijriCalendar.fromDate(DateTime(2025, 3, 20));
final u = UmmAlQuraCalendar.fromHijri(1446, 9, 1);

The shared interface #

Both engines implement HijriCalendarBase, so application code can accept either one:

void printDate(HijriCalendarBase date) {
  print(date.format('DDDD, dd MMMM yyyy'));
}

printDate(MisriHijriCalendar.now());
printDate(UmmAlQuraCalendar.now());

HijriCalendarBase exposes the same surface for both engines:

  • year, month, day, weekday, daysInMonth, isLeapYear
  • monthName, monthNameShort, weekdayName, weekdayNameShort
  • toDateTime() — the Gregorian equivalent
  • hijriToGregorian(year, month, day) — convert an arbitrary Hijri date
  • getDaysInMonth(year, month), lengthOfYear({year})
  • getMonthDays(month, year) — day-of-month → weekday-name map
  • toList()[year, month, day], isoFormatyyyy-mm-dd, isValid()
  • format(pattern) / formatDate(year, month, day, pattern) / toFormat / fullDate() — see below
  • addDays(int), addMonths(int) — return a new instance of the same engine; addMonths clamps the day to the destination month's length
  • isBefore, isAfter, isAtSameMomentAs, compareTo — chronological comparison that works across engine types (compared via toDateTime)

The engine classes add only their constructors (now, yesterday, tomorrow, fromDate, fromHijri) and, for UmmAlQuraCalendar, setAdjustments for regional moon-sighting corrections.

Worked examples #

Reference conversions produced by this package, for checking against an external source. Weekdays are included so you can confirm the exact day.

Note on the Misri engine: its 30-year cycle treats years 2, 5, 8, 10, 13, 16, 19, 21, 24, 27, 29 (year mod 30) as leap, and anchors 1 Muharram 1 AH to 16 July 622 CE. Some "tabular / arithmetical Hijri" converters use the leap set 2, 5, 7, 10, 13, 16, 18, 21, 24, 26, 29 instead, which can shift a result by a day or two — compare against a converter that uses the same rule.

Gregorian → Misri #

Gregorian Misri Hijri
Sun 1 January 1950 13 Rabiul Awwal 1369 AH
Fri 31 December 1999 24 Ramazanul Moazzam 1420 AH
Wed 10 April 2024 2 Shawwalul Mukarram 1445 AH
Fri 6 June 2025 10 Zilhijjatil Haram 1446 AH
Mon 5 November 2040 1 Zilqadatil Haram 1462 AH

Misri → Gregorian #

Misri Hijri Gregorian
1 Moharramul Haram 1350 AH Mon 18 May 1931
27 Ramazanul Moazzam 1420 AH Mon 3 January 2000
10 Zilhijjatil Haram 1446 AH Fri 6 June 2025
1 Rabiul Awwal 1447 AH Sun 24 August 2025
1 Moharramul Haram 1460 AH Fri 5 February 2038

Gregorian → Umm al-Qura #

Gregorian Umm al-Qura Hijri
Mon 20 May 1940 12 Rabi' Al-Akhir 1359 AH
Thu 14 August 1980 3 Shawwal 1400 AH
Mon 15 February 2010 1 Rabi' Al-Awwal 1431 AH
Sat 1 March 2025 1 Ramadan 1446 AH
Wed 30 September 2065 29 Jumada Al-Akhirah 1488 AH

Umm al-Qura → Gregorian #

Umm al-Qura Hijri Gregorian
1 Muharram 1356 AH Sun 14 March 1937
1 Muharram 1400 AH Tue 20 November 1979
1 Ramadan 1446 AH Sat 1 March 2025
1 Shawwal 1446 AH Sun 30 March 2025
29 Dhu Al-Hijjah 1500 AH Mon 15 November 2077

The first and last Umm al-Qura rows are the boundaries of the bundled lookup table (1 Muharram 1356 AH – 29 Dhu al-Hijja 1500 AH); dates outside that range throw an ArgumentError.

Formatting #

format(pattern) replaces these tokens (longest match wins, so DDDD beats DD and yyyy beats yy):

Token Meaning Example (1446-09-05, en)
d, dd Day of month (not zero-padded) 5
m, mm Month number (not zero-padded) 9
MM Short month name Ram
MMMM Long month name Ramadan
yy Last two digits of the year 46
yyyy Full year 1446
DD Short weekday name Wed
DDDD Long weekday name Wednesday
final d = UmmAlQuraCalendar.fromHijri(1446, 9, 5);
d.format('yyyy/mm/dd');            // 1446/9/5
d.format('DDDD, dd MMMM yyyy');    // Wednesday, 5 Ramadan 1446

Note: replacement is a single pass over the pattern. Literal text that contains d, m, or y will also be substituted, so keep patterns to separators like /, -, ,, spaces, and the tokens above.

Locales #

Built-in: en and ar for both engines, plus tr for Umm al-Qura.

UmmAlQuraCalendar.setLocal('ar'); // global default for new instances
final d = UmmAlQuraCalendar.fromHijri(1446, 9, 1, locale: 'ar');
d.format('dd MMMM yyyy'); // ١ رمضان ١٤٤٦  (Arabic-Indic digits)

UmmAlQuraCalendar.addLocale('fr', HijriLocale(
  longMonths: {1: 'Mouharram', /* ... */},
  shortMonths: {/* ... */},
  days: {1: 'Lundi', /* ... 7: 'Dimanche' */},
  shortDays: {/* ... */},
));

Each instance carries its own locale, so changing the global default does not affect instances that are already created.

Weekday name maps use Dart's DateTime.weekday convention: 1 = Monday … 6 = Saturday, 7 = Sunday.

Umm al-Qura adjustments #

Regional moon-sighting can shift a month's start by a day. Override specific month-start indices (same index convention as the internal table, hijriYearMonthIndex + 16260):

final cal = UmmAlQuraCalendar.now();
cal.setAdjustments({/* index: mcjdn */});

Accuracy caveat #

Two entries in the bundled Umm al-Qura lookup table (lib/src/hijri_array.dart) carry inherited comments claiming a manual "correction" to the standard table. They are flagged inline. If you rely on this package for far-future dates, verify those entries against an authoritative Umm al-Qura source.

Attribution #

The Umm al-Qura lookup table and JDN conversion approach are derived from the hijri package (BSD-2-Clause, Copyright 2018 AHMED ALJOAID). See NOTICE for details.

License #

BSD-2-Clause. See LICENSE.

2
likes
0
points
255
downloads

Publisher

verified publishertappstudio.in

Weekly Downloads

Hijri calendar dates for Dart/Flutter with a choice of calculation system — Misri (fixed tabular, 30-year cycle) or Umm al-Qura (Saudi official, astronomical lookup table) — behind one shared API.

Repository (GitHub)
View/report issues

Topics

#hijri #islamic-calendar #calendar #date #i18n

License

unknown (license)

More

Packages that depend on misri_hijri