I want to validate Hijri date. In my application Hijri date will come as in the format of dd/MM/YYYY
. I want to validate whether date is valid or not in Joda Time API.
For example, I have the date:
String date = "30/02/1403";
String Pattern = "dd/MM/YYYY";
Can you please help me to validate Hijri date.
My restrictions are:
java.time, the modern Java date and time API, can do this:
DateTimeFormatter hijrahFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy")
.withChronology(HijrahChronology.INSTANCE);
try {
HijrahDate date = hijrahFormatter.parse("30/02/1403", HijrahDate::from);
System.out.println("A valid date: " + date);
} catch (DateTimeParseException dtpe) {
System.out.println("Not a valid date: " + dtpe.getMessage());
}
The output from this snippet is:
A valid date: Hijrah-umalqura AH 1403-02-30
Format pattern letters are case sensitive. You need lowercase yyyy
for calendar year (or uuuu
for proleptic year).
I want to validate in Java 6. I can't use in Java 8.
That’s old now (Java 11 is out). My suggestions are:
The first two options will reject your date of 30/02/1403, though, believing there are only 29 days in the 2nd month of 1403.
DateTimeFormatter hijrahFormatter = DateTimeFormatter.ofPattern("dd/MM/uuuu")
.withChronology(HijrahChronology.INSTANCE);
String dateString = "30/02/1403";
try {
TemporalAccessor parsed = hijrahFormatter.parse(dateString);
HijrahDate date = HijrahChronology.INSTANCE.date(parsed.get(ChronoField.YEAR),
parsed.get(ChronoField.MONTH_OF_YEAR),
parsed.get(ChronoField.DAY_OF_MONTH));
if (date.format(hijrahFormatter).equals(dateString)) {
System.out.println("A valid date: " + date);
} else {
System.out.println("Not a valid date: " + dateString);
}
} catch (DateTimeParseException dtpe) {
System.out.println("Not a valid date: " + dtpe.getMessage());
}
Output:
Not a valid date: 30/02/1403
According to my understanding the following simpler way to construct the date ought to work, but doesn’t:
HijrahDate date = HijrahDate.from(parsed);
I get org.threeten.bp.DateTimeException: Field not found: EpochDay
. The way I construct the date instead is lenient, that is, it accepts that the day of month is out of range and produces a date of Hijrah-umalqura AH 1403-03-01
. So to complete the validation I format the date back and require that I get the original string again.
If instead of 30/02/1403
I try with 29/02/1403
, I get
A valid date: Hijrah-umalqura AH 1403-02-29
DateTimeFormatter islamicFormatter = DateTimeFormat.forPattern("dd/MM/yyyy")
.withChronology(IslamicChronology.getInstance());
try {
LocalDate date = LocalDate.parse("30/02/1403", islamicFormatter);
System.out.println("A valid date: " + date);
} catch (IllegalArgumentException iae) {
System.out.println("Not a valid date: " + iae.getMessage());
}
Joda-Time too thinks there are 29 days in this month and states that very clearly:
Not a valid date: Cannot parse "30/02/1403": Value 30 for dayOfMonth must be in the range [1,29]
With a string of 29/02/1403
I got:
A valid date: 1403-02-29
Joda-Time’s Islamic chronology comes with four different leap year patterns. I tried all four. They all yield 29 days in the second month of 1403. I am sorry, this as close as I can get.
From the Joda-Time homepage:
Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to
java.time
(JSR-310).
I refer you to the knowledgeable answer by Meno Hochschild, the author of Time4J. It would seem to me that Time4J version 3.50 solves your issue according to your requirements and on Java 6.
But If you will check the Islamic calendar it is a valid date of 2nd month.
You’re much more an expert than I am. I seem to understand that variants of the Hijri calendar exist. According to your variant 30/02/1403 is a perfectly valid date. The version given by alhabib Islamic web services agrees with yours: Safar 30, 1403 is the same day as December 16, 1982 in the Gregorian calendar. On the other hand according to searchtruth.com, there are only 29 days in the month of Safar 1403 (Safar 29, 1403 corresponds to December 15, 1982 Gregorian and is followed by Rabi Al-Awwal 1, 1403 corresponding to December 16).
java.time
.java.time
was first described.java.time
to Java 6 and 7 (ThreeTen for JSR-310).As supplement to the answer of Ole, I enumerate here some variants of Hijri calendar and the validation results using my lib Time4J which offers more support for variants and also offers an extra static validation method:
String variant;
for (HijriAlgorithm ha : HijriAlgorithm.values()) {
variant = ha.getVariant();
System.out.println(variant + "=>" + HijriCalendar.isValid(variant, 1403, 2, 30));
}
variant = HijriCalendar.VARIANT_DIYANET;
System.out.println(variant + "=>" + HijriCalendar.isValid(variant, 1403, 2, 30));
variant = HijriCalendar.VARIANT_UMALQURA;
System.out.println(variant + "=>" + HijriCalendar.isValid(variant, 1403, 2, 30));
The output is:
islamic-eastc=>false
islamic-easta=>false
islamic-civil=>false
islamic-tbla=>false
islamic-fatimidc=>false
islamic-fatimida=>false
islamic-habashalhasibc=>false
islamic-habashalhasiba=>false
islamic-diyanet=>true
islamic-umalqura=>true
So we can see that all algorithmic variants of Hijri calendar don't support your expectation but the diyanet and the umalqura variant. Probably you want the umalqura variant (the official calendar of Saudi-Arabia, but please clarify if you have more details about your expectations).
About your wish to solve your problem with Joda-Time, sorry, there is no chance to validate 1403-02-30 as valid because Joda-Time only supports four algorithmic variants (as subset of what Time4J supports). The same can be said for the Threeten-Backport which supports only "islamic-tbla" (or "islamic-civil" - here the API is not well documented). The java.time
-package only supports one variant, too, but that variant (umalqura) matches your expectation. However, java.time
does not run on Java 6.
If you are willing to consider an alternative to Joda-Time which matches your expectations about validation then I see mainly two ways:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With