o7planning

Java HijrahDate Tutorial with Examples

  1. HijrahDate
  2. Basic Example
  3. Supported Range Example
  4. Month Length Example

1. HijrahDate

The HijrahDate class represents dates in the Hijrah calendar system, commonly known as the Islamic or Arabic calendar, which is a calendar system based on the lunar calendar, consisting of 12 lunar months with 354 or 355 days. It is used to identify Islamic holidays, such as the annual fasting period or the Hijrah event.
The Islamic calendar uses the Hijrah era, which corresponds to the year 622 of the Gregorian calendar (also known as ISO). In that year, Muhammad and his followers migrated from Mecca to Yathrib (now Medina) and established the first Muslim community, an event commemorated as the Hijrah. In the West, this era is often denoted AH (Anno Hegirae in Latin). In Muslim countries it is also sometimes denoted H. In English, the period before Hijrah is denoted BH (Before Hijrah).
January 1, year 1 in the Hijrah calendar corresponds to July 16, 622. The following website provides an online tool to help you convert dates in the Hijrah calendar to the Gregorian calendar and vice versa:
Gregorian (ISO)
Hijrah
622-07-16
1-01-01
2000-01-01
1420-09-24
Year
A year in the Islamic calendar has about 354 or 355 days, which is 11 days shorter than the Gregorian calendar.
Approximate formula to convert Hijrah calendar year (AH) to Gregorian calendar year (CE) and vice versa:
AH = (CE − 622) × 33 ÷ 32

CE = AH + 622 − (AH ÷ 32)
Month
The Islamic calendar has 12 months with 29 or 30 days. If the Crescent Moon is visible shortly after sunset on the evening of day 29, the following day is the first day of the new month. If no sighting is made, a 30th day is added to the current month, which is then followed by the first day of the subsequent month.
The traditional version of the Islamic calendar requires an authorized person or committee to make an actual sighting of the Crescent Moon to determine the length of each month.
This dependence on astronomical observations makes it difficult to predict the length of Islamic months. Clouds and other adverse atmospheric conditions can obscure an otherwise visible Crescent Moon. When this happens, the month may be extended by a day, delaying both the beginning of the new month and the events associated with it. This is why the dates for Muslim holidays may change at short notice.
Some countries and Muslim communities now use modified versions of the traditional calendar that are designed to make the timing of Islamic months and observances easier to predict.
A new month may also begin on different days in different countries. Because the time of the moonset at a location depends on its longitude, a new month and key religious rituals like the Ramadan fast may begin a day earlier in, for example, West African Muslim countries than in Indonesia or Malaysia.
Names of the months in the Hijrah calendar:
Months
ISO Months
Hijrah Months
1
January
Muharram
2
February
Safar
3
March
Rabi Al-Awwal
4
April
Rabi Al-Thani
5
May
Jumada Al-Awwal
6
June
Jumada Al-Thani
7
July
Rajab
8
August
Sha`ban
9
September
Ramadan
10
October
Shawwal
11
November
Dhul-Qa`dah
12
December
Dhul-Hijjah
Names of days of the week:
English Day-Of-Week
Hijrah Day-Of-Week
1
Sunday
Al-Ahad
2
Monday
Al-Ithnayn
3
Tuesday
Al-Thulathaa
4
Wednesday
Al-Arbo’aa
5
Thursday
Al-Khamees
6
Friday
Al-Jum’ah
7
Saturday
Al-Sabt

2. Basic Example

Basically, the Islamic calendar has many variations, the reason being that many countries and many sects use it. The HijrahDate class supports several of them, the important thing is that Java allows you to configure it to add new variants.
The default variant supported in Java is "islamic-umalqura" - Saudi Arabian Umm Al-Qura Islamic Calendar. (See more the HijrahChronology class for more details.)
  • Java HijrahChronology
For ease of understanding let's analyze the example below (Using the default Islamic calendar variant):
HijrahDate_default_variant_ex1.java
LocalDate localDate = LocalDate.of(2000, 1, 1);
HijrahDate hijrahDate = HijrahDate.from(localDate);

System.out.printf("localDate: %s%n", localDate); // 2000-01-01
System.out.printf("hijrahDate: %s%n%n", hijrahDate); // Hijrah-umalqura AH 1420-09-24

HijrahEra era = hijrahDate.getEra(); // HijrahEra.AH
System.out.printf(" > era.name(): %s%n%n", era.name()); // AH

HijrahChronology chronology = hijrahDate.getChronology();
System.out.printf(" > chronology.getId(): %s%n", chronology.getId()); // Hijrah-umalqura
System.out.printf(" > chronology.getCalendarType(): %s", chronology.getCalendarType()); // islamic-umalqura
Output:
localDate: 2000-01-01
hijrahDate: Hijrah-umalqura AH 1420-09-24

 > era.name(): AH

 > chronology.getId(): Hijrah-umalqura
 > chronology.getCalendarType(): islamic-umalqura
The text representing a HijrahDate consists of 3 parts:
Chronology ID:
(Chronology Identifier): Allows specifying which variant to use. The Gregorian (ISO) and Japanese calendar systems have no variation so this information does not appear.
Era Name:
(Era Name): Only one epoch is supported which is HijrahEra.AH.
Date:
Date information.

3. Supported Range Example

Although in practice the Hijrah calendar system does not limit the date range, but Java only supports it to a small extent, namely:
(**) Test with Java 11.
Hijrah Date
ISO Date
From
Hijrah-umalqura AH 1300-01-01
1882-11-12
To
Hijrah-umalqura AH 1600-12-30
2174-11-25
The example below is used to find the smallest and largest date in the Hijrah calendar system supported by Java.
HijrahDate_date_range_ex1.java
package org.o7planning.hijrahdate.ex;

import java.time.LocalDate;
import java.time.chrono.Chronology;
import java.time.chrono.HijrahChronology;
import java.time.chrono.HijrahDate;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.ValueRange;

public class HijrahDate_date_range_ex1 {
    public static void main(String[] args) {
        Chronology chronology = HijrahChronology.INSTANCE;
        ValueRange range = chronology.range(ChronoField.YEAR);
        int minYear = (int) range.getMinimum();
        int maxYear = (int) range.getMaximum();

        System.out.println("minYear: " + minYear);
        System.out.println("maxYear: " + maxYear);

        // ----- Find the first supported date --------
        // A Hijrah Month have 29 or 30 days.
        HijrahDate hijrahDate = null;
        try {
            hijrahDate = HijrahDate.of(minYear, 12, 30);
        } catch (Exception e) {
            hijrahDate = HijrahDate.of(minYear, 12, 29);
        }
        HijrahDate firstDate = hijrahDate.with(TemporalAdjusters.firstDayOfYear());
        System.out.println("First date: " + firstDate + " --> " + LocalDate.from(firstDate));

        // ----- Find the last supported date --------
        hijrahDate = HijrahDate.of(maxYear, 1, 1);

        hijrahDate.range(ChronoField.DAY_OF_YEAR);
        HijrahDate lastDate = hijrahDate.with(TemporalAdjusters.lastDayOfYear());
        System.out.println("Last date: " + lastDate + " --> " + LocalDate.from(lastDate));
    }
}
Output:
minYear: 1300
maxYear: 1600
First date: Hijrah-umalqura AH 1300-01-01 --> 1882-11-12
Last date: Hijrah-umalqura AH 1600-12-30 --> 2174-11-25

4. Month Length Example

Example: View the length of months of a few years (Default variant - Saudi Arabian Umm Al-Qura Islamic Calendar).
HijrahDate_monthLength_ex1.java
int[] hijrahYears = new int[] { 1441, 1442, 1443, 1444, 1445 };

HijrahDate hijrahDate = HijrahDate.of(hijrahYears[0], 1, 1);
System.out.println("Hijrah Year: " + hijrahYears[0]); // 1441
System.out.println("ISO Year: " + LocalDate.from(hijrahDate).getYear()); // 2019
System.out.println();

for (int month = 1; month <= 12; month++) {
    for (int hijrahYear : hijrahYears) {
        hijrahDate = HijrahDate.of(hijrahYear, month, 1);

        System.out.printf("Year: %s  Month: %s  --> %d%n", hijrahYear, month, hijrahDate.lengthOfMonth());
    }
}
Output:
Year
1441
1442
1443
1444
1445
Month
1
30
29
30
29
29
2
29
30
29
30
30
3
30
29
30
29
30
4
29
30
29
30
30
5
30
29
30
30
29
6
30
30
29
29
30
7
29
29
30
29
29
8
30
30
29
30
29
9
30
30
30
29
30
10
29
29
29
30
29
11
30
30
30
29
29
12
29
29
30
30
30