Iranian holidays with iranian_holidays
Iran's official holidays for jalali_date dates in Dart: calculated offline including the lunar Hijri ones, or from holidayapi.ir, Calendarific or Google Calendar.
Iranian holidays and events for jalali_date dates.
تعطیلات و مناسبتهای تقویم رسمی ایران برای تاریخهای jalali_date.
Two ways to get holidays, and you choose one explicitly:
- Offline:
OfflineHolidaySourcecalculates the official holidays on the device, with no network and no third party. Religious holidays follow the lunar Hijri calendar; their dates come from the predicted first sighting of the new crescent in Iran. - Online: a holiday service such as holidayapi.ir, Calendarific, or Google Calendar, or one of your own. It follows announcements and lists every event of the calendar, not only days off.
FallbackHolidaySource combines both: online first, offline when the request fails.
Choosing a source
| Source | Cost and key | Class | Know before using |
|---|---|---|---|
| Offline calculation | Free, no network | OfflineHolidaySource | The 26 official holidays plus Fridays. Hijri dates are calculated and can be one day off from an announcement made later; such changes never reach it. No other events. |
| holidayapi.ir | Free, no key | HolidayApiIrSource | Community service, no service level agreement or published terms. Data is extracted from time.ir. One request per day. No CORS headers, so it does not work in browsers or Flutter web. Fridays count as holidays. |
| Calendarific | Free tier with an API key and a monthly request limit; paid plans above it | CalendarificSource | Commercial service with Iran coverage; one request per Gregorian year. Shipping the key inside an app exposes it; use a proxy of your own through baseUri. Names are English unless your plan supports language. Fridays are added by this package. |
| Google Calendar API public holiday calendar | Free quota with a Google Cloud API key | GoogleCalendarSource | Reads Google's public Iranian holiday calendar, one request per Jalali month. Needs a Google Cloud project with the Calendar API enabled; restrict the key or use a proxy through baseUri. Days off are detected from the event description (Public holiday on the English calendar); pass isHolidayEvent for the Persian calendar. Fridays are added by this package. |
| Your own table | Free | No, implement HolidaySource | Works offline and needs no third party. You update it yourself each year from the official announcement. |
Not usable today: Nager.Date is free but has no Iranian data, and time.ir is a website without a public API.
Tell your users where holiday data comes from, for example on an about or settings screen; HolidaySource.name, website, and notice hold that text.
Installation
dart pub add iranian_holidaysOffline holidays
import 'package:jalali_date/jalali_date.dart';
import 'package:iranian_holidays/iranian_holidays.dart';
void main() {
final offline = OfflineHolidaySource();
final ashura = offline.dayOf(PersianDate(1405, 4, 4));
print(ashura.isHoliday); // true
print(ashura.holidays.first.description); // عاشورای حسینی
print(ashura.holidays.first.additionalDescription); // 10 محرم 1448
for (final day in offline.holidaysOf(1406)) {
print('${day.date} ${day.holidays.map((e) => e.description).join(', ')}');
}
print(offline.hijriDate(PersianDate(1405, 1, 1))); // 1 شوال 1447
}dayOf, holidaysOf, and hijriDate are synchronous; day and month implement HolidaySource like the online sources.
holidaysOf lists the official holidays of a Jalali year without Fridays; dayOf and day count Fridays unless you pass fridaysAreHolidays: false.
How Hijri holidays are calculated
A Hijri month starts the day after the evening its new crescent is first seen in Iran.
The package computes the new moon and the positions of the Sun and the Moon at sunset (Meeus, Astronomical Algorithms), and checks Yallop's visibility criterion at eight cities across Iran, counting a crescent visible with optical aid (q >= -0.232).
Months where the calendar published by the Iranian calendar authority differs are corrected from a table.
Checked against the published calendar for every month with a holiday from 1387 to 1406, the result matches all of them.
Without the table, the calculation alone matches 174 of these 186 months, and 109 of the 112 from 1395 on.
The calendar itself lives in jalali_date as HijriDate and IranianHijri; use it directly when you need Hijri dates without holidays.
What the offline mode cannot do:
A month officially starts when the crescent is actually seen, which is announced only days before. A later announcement that moves a holiday is not picked up. Pass the announced start yourself, or use an online source:
dartfinal offline = OfflineHolidaySource( // 1 Muharram 1448 announced for 1405/03/27. hijriMonthStarts: {(1448, 1): PersianDate(1405, 3, 27)}, );Changes to the holiday law are not picked up either; pass your own
holidayslist (built fromOfficialHoliday.jalaliandOfficialHoliday.hijri) if the law changes.It lists official days off only, not the many other events of the calendar.
The official holidays
| Calendar | Date | Holiday |
|---|---|---|
| Jalali | 1 to 4 Farvardin | Nowruz |
| Jalali | 12 Farvardin | Islamic Republic Day |
| Jalali | 13 Farvardin | Sizdah Bedar |
| Jalali | 14 Khordad | Death of Imam Khomeini |
| Jalali | 15 Khordad | 15 Khordad uprising |
| Jalali | 22 Bahman | Victory of the Islamic Revolution |
| Jalali | 29 Esfand | Oil nationalization day |
| Hijri | 9 and 10 Muharram | Tasua and Ashura |
| Hijri | 20 Safar | Arbaeen |
| Hijri | 28 Safar | Death of the Prophet and martyrdom of Imam Hasan |
| Hijri | 29 Safar | Martyrdom of Imam Reza |
| Hijri | 8 Rabi al-Awwal | Martyrdom of Imam Hasan Askari |
| Hijri | 17 Rabi al-Awwal | Birth of the Prophet and Imam Sadiq |
| Hijri | 3 Jumada al-Thani | Martyrdom of Fatima |
| Hijri | 13 Rajab | Birth of Imam Ali |
| Hijri | 27 Rajab | Mab'ath |
| Hijri | 15 Sha'ban | Birth of Imam Mahdi |
| Hijri | 21 Ramadan | Martyrdom of Imam Ali |
| Hijri | 1 and 2 Shawwal | Eid al-Fitr |
| Hijri | 25 Shawwal | Martyrdom of Imam Sadiq |
| Hijri | 10 Dhu al-Hijjah | Eid al-Adha |
| Hijri | 18 Dhu al-Hijjah | Eid al-Ghadir |
The Persian names are in OfficialHoliday.iran.
Imam Reza is on 29 Safar even in years where Safar has 30 days, as on the published calendars.
Fridays are holidays as well.
Example: 1405 and 1406
Output of OfflineHolidaySource().holidaysOf(year), Fridays not listed.
Both years match the calendar published on time.ir day for day.
A Hijri holiday falls twice in one Jalali year when the lunar year (354 or 355 days) fits inside it: Eid al-Fitr in 1405.
1405
| Jalali | Weekday | Gregorian | Holiday | Calendar date |
|---|---|---|---|---|
| 1405/01/01 | شنبه | 2026-03-21 | جشن نوروز/جشن سال نو عید سعید فطر | 1 فروردین 1 شوال 1447 |
| 1405/01/02 | یکشنبه | 2026-03-22 | عیدنوروز تعطیل به مناسبت عید سعید فطر | 2 فروردین 2 شوال 1447 |
| 1405/01/03 | دوشنبه | 2026-03-23 | عیدنوروز | 3 فروردین |
| 1405/01/04 | سهشنبه | 2026-03-24 | عیدنوروز | 4 فروردین |
| 1405/01/12 | چهارشنبه | 2026-04-01 | روز جمهوری اسلامی | 12 فروردین |
| 1405/01/13 | پنجشنبه | 2026-04-02 | جشن سیزده به در | 13 فروردین |
| 1405/01/25 | سهشنبه | 2026-04-14 | شهادت امام جعفر صادق (ع) | 25 شوال 1447 |
| 1405/03/06 | چهارشنبه | 2026-05-27 | عید سعید قربان | 10 ذوالحجه 1447 |
| 1405/03/14 | پنجشنبه | 2026-06-04 | رحلت حضرت امام خمینی عید سعید غدیر خم | 14 خرداد 18 ذوالحجه 1447 |
| 1405/03/15 | جمعه | 2026-06-05 | قیام 15 خرداد | 15 خرداد |
| 1405/04/03 | چهارشنبه | 2026-06-24 | تاسوعای حسینی | 9 محرم 1448 |
| 1405/04/04 | پنجشنبه | 2026-06-25 | عاشورای حسینی | 10 محرم 1448 |
| 1405/05/13 | سهشنبه | 2026-08-04 | اربعین حسینی | 20 صفر 1448 |
| 1405/05/21 | چهارشنبه | 2026-08-12 | رحلت رسول اکرم؛شهادت امام حسن مجتبی (ع) | 28 صفر 1448 |
| 1405/05/22 | پنجشنبه | 2026-08-13 | شهادت امام رضا (ع) | 29 صفر 1448 |
| 1405/05/30 | جمعه | 2026-08-21 | شهادت امام حسن عسکری (ع) | 8 ربیع الاول 1448 |
| 1405/06/08 | یکشنبه | 2026-08-30 | میلاد رسول اکرم و امام جعفر صادق (ع) | 17 ربیع الاول 1448 |
| 1405/08/22 | جمعه | 2026-11-13 | شهادت حضرت فاطمه زهرا (س) | 3 جمادی الثانیه 1448 |
| 1405/10/02 | چهارشنبه | 2026-12-23 | ولادت امام علی (ع) و روز پدر | 13 رجب 1448 |
| 1405/10/16 | چهارشنبه | 2027-01-06 | مبعث رسول اکرم (ص) | 27 رجب 1448 |
| 1405/11/04 | یکشنبه | 2027-01-24 | ولادت حضرت قائم عجل الله تعالی فرجه و جشن نیمه شعبان | 15 شعبان 1448 |
| 1405/11/22 | پنجشنبه | 2027-02-11 | پیروزی انقلاب اسلامی | 22 بهمن |
| 1405/12/09 | یکشنبه | 2027-02-28 | شهادت حضرت علی (ع) | 21 رمضان 1448 |
| 1405/12/19 | چهارشنبه | 2027-03-10 | عید سعید فطر | 1 شوال 1448 |
| 1405/12/20 | پنجشنبه | 2027-03-11 | تعطیل به مناسبت عید سعید فطر | 2 شوال 1448 |
| 1405/12/29 | شنبه | 2027-03-20 | روز ملی شدن صنعت نفت ایران | 29 اسفند |
1406
| Jalali | Weekday | Gregorian | Holiday | Calendar date |
|---|---|---|---|---|
| 1406/01/01 | یکشنبه | 2027-03-21 | جشن نوروز/جشن سال نو | 1 فروردین |
| 1406/01/02 | دوشنبه | 2027-03-22 | عیدنوروز | 2 فروردین |
| 1406/01/03 | سهشنبه | 2027-03-23 | عیدنوروز | 3 فروردین |
| 1406/01/04 | چهارشنبه | 2027-03-24 | عیدنوروز | 4 فروردین |
| 1406/01/12 | پنجشنبه | 2027-04-01 | روز جمهوری اسلامی | 12 فروردین |
| 1406/01/13 | جمعه | 2027-04-02 | جشن سیزده به در | 13 فروردین |
| 1406/01/14 | شنبه | 2027-04-03 | شهادت امام جعفر صادق (ع) | 25 شوال 1448 |
| 1406/02/27 | دوشنبه | 2027-05-17 | عید سعید قربان | 10 ذوالحجه 1448 |
| 1406/03/04 | سهشنبه | 2027-05-25 | عید سعید غدیر خم | 18 ذوالحجه 1448 |
| 1406/03/14 | جمعه | 2027-06-04 | رحلت حضرت امام خمینی | 14 خرداد |
| 1406/03/15 | شنبه | 2027-06-05 | قیام 15 خرداد | 15 خرداد |
| 1406/03/25 | سهشنبه | 2027-06-15 | تاسوعای حسینی | 9 محرم 1449 |
| 1406/03/26 | چهارشنبه | 2027-06-16 | عاشورای حسینی | 10 محرم 1449 |
| 1406/05/03 | یکشنبه | 2027-07-25 | اربعین حسینی | 20 صفر 1449 |
| 1406/05/11 | دوشنبه | 2027-08-02 | رحلت رسول اکرم؛شهادت امام حسن مجتبی (ع) | 28 صفر 1449 |
| 1406/05/12 | سهشنبه | 2027-08-03 | شهادت امام رضا (ع) | 29 صفر 1449 |
| 1406/05/20 | چهارشنبه | 2027-08-11 | شهادت امام حسن عسکری (ع) | 8 ربیع الاول 1449 |
| 1406/05/29 | جمعه | 2027-08-20 | میلاد رسول اکرم و امام جعفر صادق (ع) | 17 ربیع الاول 1449 |
| 1406/08/12 | چهارشنبه | 2027-11-03 | شهادت حضرت فاطمه زهرا (س) | 3 جمادی الثانیه 1449 |
| 1406/09/21 | یکشنبه | 2027-12-12 | ولادت امام علی (ع) و روز پدر | 13 رجب 1449 |
| 1406/10/05 | یکشنبه | 2027-12-26 | مبعث رسول اکرم (ص) | 27 رجب 1449 |
| 1406/10/23 | پنجشنبه | 2028-01-13 | ولادت حضرت قائم عجل الله تعالی فرجه و جشن نیمه شعبان | 15 شعبان 1449 |
| 1406/11/22 | جمعه | 2028-02-11 | پیروزی انقلاب اسلامی | 22 بهمن |
| 1406/11/29 | جمعه | 2028-02-18 | شهادت حضرت علی (ع) | 21 رمضان 1449 |
| 1406/12/08 | یکشنبه | 2028-02-27 | عید سعید فطر | 1 شوال 1449 |
| 1406/12/09 | دوشنبه | 2028-02-28 | تعطیل به مناسبت عید سعید فطر | 2 شوال 1449 |
| 1406/12/29 | یکشنبه | 2028-03-19 | روز ملی شدن صنعت نفت ایران | 29 اسفند |
Online holidays
import 'package:jalali_date/jalali_date.dart';
import 'package:iranian_holidays/iranian_holidays.dart';
Future<void> main() async {
final api = HolidayApiIrSource();
print(api.notice); // read this before shipping
final source = CachedHolidaySource(api);
final day = await source.day(PersianDate(1403, 1, 1));
print(day.isHoliday); // true
print(day.holidays.first.description); // جشن نوروز/جشن سال نو
final mehr = await source.month(1403, 7);
print(mehr.where((d) => d.isHoliday).map((d) => d.date));
api.close();
}Online first, offline as fallback
final source = FallbackHolidaySource(
CachedHolidaySource(HolidayApiIrSource()),
OfflineHolidaySource(),
);
final day = await source.day(PersianDate(1405, 4, 4)); // works without networkFallbackHolidaySource uses the second source only when the first throws HolidaySourceException.
Caching
CachedHolidaySource keeps answers in memory, so each day is requested once; failed requests are retried on the next call.
CalendarificSource and GoogleCalendarSource already cache whole years or months, so they do not need it.
Errors from any source are HolidaySourceException, and API keys are replaced by REDACTED in its URL.
Sources with your own API key
// Calendarific: https://calendarific.com, key from your account.
final calendarific = CalendarificSource(apiKey: calendarificKey);
// Google Calendar API: key from a Google Cloud project with the Calendar API.
final google = GoogleCalendarSource(apiKey: googleKey);
// Persian names from Google; tell it how days off are marked there.
final googleFa = GoogleCalendarSource(
apiKey: googleKey,
calendarId: GoogleCalendarSource.persianCalendarId,
isHolidayEvent: (summary, description) => description.contains('تعطیل'),
);
// Keep the key on your server: a proxy that adds it and forwards the request.
final proxied = CalendarificSource(
apiKey: 'unused',
baseUri: Uri.parse('https://api.example.com/calendarific/'),
);Read keys from your configuration (for example --dart-define), never from source code.
These two classes are tested against the providers' documented response formats with mock clients; check the results against the official calendar before you rely on them.
Writing your own source
class MyTableSource implements HolidaySource {
@override
String get name => 'Built-in table 1403';
@override
Uri get website => Uri.parse('https://example.com/holidays');
@override
String get notice => 'Official 1403 holidays, updated by hand.';
static final _holidays = {
PersianDate(1403, 1, 1): 'جشن نوروز',
// ...
};
@override
Future<HolidayDay> day(PersianDate date) async {
final key = PersianDate(date.year, date.month, date.day);
final name = _holidays[key];
return HolidayDay(
date: key,
isHoliday: name != null || key.isWeekend,
events: [if (name != null) HolidayEvent(description: name, isHoliday: true)],
);
}
@override
Future<List<HolidayDay>> month(int year, int month) {
final first = PersianDate(year, month, 1);
return Future.wait(first.daysUntil(first.lastDayOfMonth).map(day));
}
}