Skip to the guide
All guides

Iranian holidays

Look up official Iranian public holidays for any Jalali date, list a whole year, and find business days. Official dates are used for 1394 to 1405, and other years are estimated.

app RTLY-Kit 0.2.0checked reading 5 minutes

On this page

What it does

RtlyKit\Holiday\IranHolidays answers four questions about a Jalali date. Is it an official public holiday? What is the holiday called? Is it a weekend? What is the next working day? All methods are static and the class is final. Titles are returned in Persian, as on the official calendar.

Two kinds of holiday are combined:

  • Fixed solar holidays fall on the same Jalali date every year (Nowruz, 22 Bahman and so on). They are exact.
  • Islamic (lunar) holidays move through the Jalali year by about 11 days each year. For the Jalali years 1380 to 1405 the library returns the dates that were published. For other years it calculates them from the Hijri calendar. See Accuracy and limits .

To see where the dates of a year come from, to correct them, or to add your own days, use HolidayCalendar. The static methods on this page use its default calendar.

Checking a single day

Every lookup accepts a Jalali object or three integers (year, month, day).

PHP
use RtlyKit\Calendar\Jalali;
use RtlyKit\Holiday\IranHolidays;
use function RtlyKit\is_iran_holiday;

var_dump(IranHolidays::isHoliday(1404, 11, 22));              // bool(true)
var_dump(IranHolidays::getTitle(1404, 11, 22));               // string(38) "پیروزی انقلاب اسلامی"
var_dump(IranHolidays::isHoliday(Jalali::create(1404, 1, 5))); // bool(false)
var_dump(is_iran_holiday(1404, 1, 1));                        // bool(true)  (namespaced helper)

getTitle() returns the first title, or null. When two holidays fall on one day, use getTitles(). It returns a list with the fixed holiday first and the Islamic one second:

PHP
print_r(IranHolidays::getTitles(1405, 1, 1));
// Array ( [0] => جشن نوروز [1] => عید فطر )

In 1405, Eid al-Fitr is on 1 Farvardin, the same day as Nowruz. This is the official date.

Listing a whole year

Three methods return a year. Each result is keyed by Y/m/d strings in ascending order:

  • allFixed(int $year) returns only the fixed solar holidays, one title per date.
  • all(int $year) returns fixed and Islamic holidays. Titles on the same day are joined with / .
  • allTitles(int $year) is the structured form. Each value is a list<string> .
PHP
foreach (IranHolidays::allFixed(1404) as $date => $title) {
    echo $date, '  ', $title, "\n";
}
// 1404/01/01  جشن نوروز
// 1404/01/02  عید نوروز
// 1404/01/03  عید نوروز
// 1404/01/04  عید نوروز
// 1404/01/12  روز جمهوری اسلامی
// 1404/01/13  روز طبیعت
// 1404/03/14  رحلت امام خمینی
// 1404/03/15  قیام ۱۵ خرداد
// 1404/11/22  پیروزی انقلاب اسلامی
// 1404/12/29  ملی شدن صنعت نفت

echo count(IranHolidays::all(1404));    // 26 (fixed + Islamic holidays, one entry per day)

The Islamic part of 1404 includes 1404/01/11 عید فطر, 1404/03/16 عید قربان, 1404/03/24 عید غدیر خم, 1404/04/14 تاسوعای حسینی and 1404/04/15 عاشورای حسینی. When a fixed and an Islamic holiday share a day, all() joins them, for example 1404/01/12 روز جمهوری اسلامی / تعطیل عید فطر.

Weekends and business days

Three helpers take a Jalali object:

  • isWeekend($date) is true only on Friday.
  • isBusinessDay($date) is true when the day is neither a weekend nor a holiday.
  • nextBusinessDay($date) returns the first business day after the given date.
PHP
foreach ([Jalali::create(1404, 11, 20), Jalali::create(1404, 11, 21), Jalali::create(1404, 11, 22)] as $d) {
    echo $d->toDateString(),
        ' weekend=', var_export(IranHolidays::isWeekend($d), true),
        ' business=', var_export(IranHolidays::isBusinessDay($d), true),
        ' next=', IranHolidays::nextBusinessDay($d)->toDateString(), "\n";
}
// 1404/11/20 weekend=false business=true next=1404/11/21
// 1404/11/21 weekend=false business=true next=1404/11/23
// 1404/11/22 weekend=false business=false next=1404/11/23

Note. Only Friday counts as a weekend. Thursday is a business day here. Thursday half-days, regional calendars and one-off closures (for example for weather) are not modelled. If your organisation closes on Thursdays, filter that yourself after calling isBusinessDay().

Invalid input

Bad input throws a subclass of RtlyKitException, never a raw PHP error. See Error handling.

PHP
IranHolidays::isHoliday(1404, 13, 1);  // InvalidDateException: Invalid Jalali date: 1404/13/1
IranHolidays::isHoliday(1404);         // InvalidDateException: Month and day are required when the year is given as int.
IranHolidays::all(99999);              // InvalidDateException, code date_out_of_range (year outside -620..9377)

Accuracy and limits

Iran fixes its religious dates by moon sighting. What you get depends on the Jalali year:

YearsSource of the Islamic dates
1394, 1396 to 1405Official yearly calendar, checked against a second source
1380 to 1393, 1395Published dates from one source
All other yearsCalculated from the Umm al-Qura table, inside AH 1300 to 1500

Good to know. A calculated date can differ from the announced one by one or two days. Check the announcement before you use an estimated date for payroll, deadlines or legal dates. IranHolidays::sourceOf($year) tells you which source a year uses, and HolidayCalendar lets you correct the dates.

  • Range of the estimate. Estimated Islamic holidays are reported only inside the embedded Umm al-Qura table (Hijri years 1300 to 1500, 1882-11-12 to 2077-11-16). Outside it, the lookups return the fixed solar holidays only, because an arithmetic extrapolation is not reliable for holidays. Example: IranHolidays::getTitles(Jalali::create(1500, 1, 1)) returns just ["جشن نوروز"] .
  • Jalali year range. all() , allTitles() and allFixed() accept Jalali years -620 to 9377 and work for every year in that range. For a year outside it they throw InvalidDateException with the code date_out_of_range and the context year , min and max . Where Islamic holidays cannot be derived (before the Hijri epoch, or outside AH 1300 to 1500), only the fixed holidays are returned and nothing is thrown.
  • Not covered. One-off holidays that the government declares, and observances that are not days off.
  • Source of the data is described on the Accuracy and data page.

Related: the Jalali calendar and the Hijri calendar.