Проверка даты хиджры (исламский календарь) на Java 6 - PullRequest
0 голосов
/ 13 ноября 2018

Я хочу подтвердить дату Хиджры. В моем приложении дата Хиджры придет как в формате dd/MM/YYYY. Я хочу проверить, является ли дата действительной или нет в Joda Time API.

Например, у меня есть дата:

String date = "30/02/1403";
String Pattern = "dd/MM/YYYY";

Не могли бы вы помочь мне подтвердить дату хиджры.

Мои ограничения:

  • Я хочу проверить в Java 6. Я не могу использовать в Java 8.
  • Я должен подтвердить с исламским календарем. подтвердить с датой хиджры. Моя дата уже в формате хиджры. Я должен подтвердить, что эта дата действительна или нет по исламскому календарю.
  • В исламском календаре 30/02/1403 действительна дата 2-го месяца.

Ответы [ 3 ]

0 голосов
/ 13 ноября 2018

java.time

java.time, современный API даты и времени Java, может сделать это:

    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());
    }

Вывод этого фрагмента:

Действительная дата: хиджра-умалькура AH 1403-02-30

Буквы шаблона формата чувствительны к регистру. Вам нужен нижний регистр yyyy для календарного года (или uuuu для года, когда наступил приступ).

Java 6? Три варианта.

Я хочу проверить в Java 6. Я не могу использовать в Java 8.

Это старое сейчас (Java 11 вышла). Мои предложения:

  1. Используйте ThreeTen Backport, бэкпорт java.time для Java 6 и 7. Оказывается, он не работает идеально для вашего случая, но вы можете.
  2. Используйте Joda-Time, как вы и просили с самого начала.
  3. Использовать Time4J.

Первые два варианта отклонят вашу дату 30/02/1403, хотя, полагая, что во втором месяце 1403 года осталось только 29 дней.

ThreeTen Backport

    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());
    }

Выход:

Недействительная дата: 30/02/1403

Насколько я понимаю, следующий простой способ построения даты должен работать, но не работает:

        HijrahDate date = HijrahDate.from(parsed);

Я получаю org.threeten.bp.DateTimeException: Field not found: EpochDay. Вместо этого я строю дату так, что она принимает, что день месяца выходит за пределы допустимого диапазона, и выдает дату Hijrah-umalqura AH 1403-03-01. Поэтому для завершения проверки я форматирую дату назад и требую, чтобы я снова получил исходную строку.

Если вместо 30/02/1403 я попробую с 29/02/1403, я получу

Действительная дата: хиджра-умалькура AH 1403-02-29

Joda-Time

    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 также считает, что в этом месяце 29 дней, и очень ясно заявляет:

Недопустимая дата: невозможно проанализировать "30/02/1403": значение 30 для dayOfMonth должно быть в диапазоне [1,29]

со строкой 29/02/1403 Я получил:

Действительная дата: 1403-02-29

Исламская хронология Joda-Time включает четыре различных образца високосного года. Я попробовал все четыре. Все они дают 29 дней во втором месяце 1403 года. Извините, это настолько близко, насколько я могу.

С домашней страницы Joda-Time:

Обратите внимание, что Joda-Time считается в значительной степени «законченным» проектом. Никаких серьезных улучшений не планируется. Если вы используете Java SE 8, пожалуйста, перенесите до java.time (JSR-310).

Time4J

Я отсылаю вас к знающему ответу Мено Хохшильда, автора Time4J. Мне кажется, что Time4J версии 3.50 решает вашу проблему в соответствии с вашими требованиями и на Java 6.

Но эта дата действительна или нет?

Но если вы проверите исламский календарь, это действительная дата 2-го месяца.

Вы гораздо больше эксперт, чем я. Кажется, я понимаю, что существуют варианты календаря хиджры. По вашему варианту 30/02/1403 - это совершенно действительная дата. Версия, предоставленная исламскими веб-службами alhabib, совпадает с вашей версией: Safar 30, 1403 - это тот же день, что и 16 декабря 1982 года в григорианском календаре. С другой стороны, согласно searchtruth.com, в месяце Safar 1403 есть только 29 дней (Safar 29, 1403 соответствует 15 декабря 1982 г. по григорианскому языку, а за ним следует Rabi Al-Awwal 1, 1403, соответствующий 16 декабря).

Ссылки

0 голосов
/ 14 ноября 2018

В дополнение к ответу Ole, я перечисляю здесь некоторые варианты календаря Hijri и результаты проверки, используя мою библиотеку Time4J, которая предлагает больше поддержки вариантов, а также предлагает дополнительный метод статической проверки :

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));

Вывод:

islamic-eastc => false

исламский-easta => ложный

исламское-гражданского => ложь

islamic-tbla => false

islamic-fatimidc => false

исламское-fatimida => ложь

islamic-habashalhasibc => false

исламское-habashalhasiba => ложь

islamic-diyanet => true

исламское-umalqura => верно

Итак, мы видим, что все алгоритмические варианты календаря Хиджры не поддерживают ваши ожидания, кроме варианта дианет и умалькуры. Возможно, вам нужен вариант umalqura (официальный календарь Саудовской Аравии, но, пожалуйста, уточните, если у вас есть более подробная информация о ваших ожиданиях).

О вашем желании решить вашу проблему с Joda-Time, извините, у вас нет шансов подтвердить 1403-02-30 как действительное, потому что Joda-Time поддерживает только четыре алгоритмических варианта (как подмножество того, что поддерживает Time4J). То же самое можно сказать и о Threeten-Backport, который поддерживает только «islamic-tbla» (или «islamic-civil» - здесь API плохо документирован). Пакет java.time также поддерживает только один вариант, но этот вариант (umalqura) соответствует вашим ожиданиям. Однако java.time не работает на Java 6.

Если вы готовы рассмотреть альтернативу Joda-Time, которая соответствует вашим ожиданиям в отношении проверки, тогда я вижу в основном два пути:

  • my lib Time4J (версия обратного порта v3.50, которая работает на Java 6 + 7)
  • msarhan
0 голосов
/ 13 ноября 2018

Вот что я использую:

//import the regex class

# import java.util.regex. *;

Add the below inside your main class.

String pattern = "(?:[0-2]\d)|(?:30)\/[0-1]\d\/14\d{2}";

if(Pattern.matches(pattern, yourdate)) {
    System.out.println("hijra date");
}
...