java : How to add days to Hijri date?

Using Joda I write:

public static String adjustHijri(String dateHijri, int plusDays) {

    // dateHijri formatted as yyyy-MM-dd, eg: 1440-02-30
    int yearHijri = Integer.parseInt(dateHijri.substring(0, 4));
    int monthHijri = Integer.parseInt(dateHijri.substring(5, 7));
    int dayHijri = Integer.parseInt(dateHijri.substring(8));

    DateTime date = new DateTime(yearHijri, monthHijri, dayHijri, 0, 0, IslamicChronology.getInstance());
    return date.plusDays(plusDays).toString("yyyy-MM-dd");
}

for dateHijri=1440-02-30 I got:

org.joda.time.IllegalFieldValueException: Value 30 for dayOfMonth must be in the range [1,29]

1 answer

  • answered 2018-11-09 04:56 Meno Hochschild

    Your real problem is not to have thought about which variant of Islamic calendar you need.

    The expectation that the second month of Hijri year 1440 has 30 days is only correct for example for the Umalqura calendar of Saudi-Arabia but not for the variant used by Joda-Time. That library only supports four algorithmic variants, see the definition of IslamicChronology.LeapYearPatternType-constants in the API. Your code implicitly uses the LEAP_YEAR_16_BASED-variant. You might try the other three variants if they match your expectation (not tested by me) but the result can also be that none of Joda-Time variants will match. If so then you are completely out of luck with Joda-Time and will probably need to use another library.

    Since you have tagged your question with "android-jodatime", I assume and speculate that you need support for the umalqura calendar on Android. If so then you might consider 3rd-party libs like msarhan or Time4A (my lib). Example in Time4A:

    static final ChronoFormatter<HijriCalendar> HIJRI_FORMAT =
        ChronoFormatter
            .ofPattern("yyyy-MM-dd", PatternType.CLDR, Locale.ROOT, HijriCalendar.family())
            .withCalendarVariant(HijriCalendar.VARIANT_UMALQURA);
    public String addDays(String date, int days) throws ParseException {
        HijriCalendar hcal = HIJRI_FORMAT.parse(date).plus(CalendarDays.of(days));
        return HIJRI_FORMAT.format(hcal);
    }
    

    If you only use the API-level of Android 26 or higher then you can also try the new java.time.chrono.HijrahDate-class which also supports the umalqura-calendar but I assume that this API-level is still excluding too many Android users. And the threeten-backport (for example Jake Whartons ThreetenABP-library) does NOT support the umalqura calendar unfortunatly).