настроить пользовательский вариант в HijrahChronology для корректировки даты JDK 8 - PullRequest
0 голосов
/ 25 июня 2018

Я использовал DatePicker в javafx - JDK 8 и использовал HijrahChronology.INSTANCE - так, чтобы средство выбора даты показывало оба календаря - все работает достаточно хорошо, но у меня разница в 1 день между григорианским календарем и календарем хиджры.Календарь Хиджры на 1 день назад.

Я пытаюсь изменить вариант по следующей ссылке https://bugs.openjdk.java.net/browse/JDK-8187987

, но не могу добиться успеха.Пожалуйста, объясните или отошлите лучшее или ясное решение этой проблемы.

Код:

HijrahChronology hijriChronology = HijrahChronology.INSTANCE;
    dateOfTransaction.setChronology(hijriChronology);

dateOfTransaction является экземпляром DatePicker в JavaFx. Я не использовал Joda Time и не хочуЕсли только это не единственное решение.

1 Ответ

0 голосов
/ 25 июня 2018

К сожалению, Java (от 8 до 10) не поддерживает предоставление собственного варианта хиджры во время выполнения (вот соответствующий отчет об ошибке, который я отправил несколько месяцев назад: https://bugs.openjdk.java.net/browse/JDK-8187987).

Однако есть 2 обходных пути:

1 - манипулировать вариантом хиджры по умолчанию, поставляемым с JRE. В Java 8 его можно найти по следующему адресу:

C: \ Program Files \ Java \ jdk1.8.0_162\ jre \ lib \ hijrah-config-umalqura.properties

В Java 9 и 10 он связан по этому адресу:

/ java / time / chrono /hijrah-config-islamic-umalqura.properties

2- Вы можете внедрить пользовательский вариант хиджры во время выполнения, используя Reflection API:

public static void injectCustomHijriVariant(Map<Integer, int[]> yearMonthsMap, long isoStartDate)
        throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException
{
    int minYear = Integer.MAX_VALUE;
    int maxYear = Integer.MIN_VALUE;

    for(int year : yearMonthsMap.keySet())
    {
        maxYear = Math.max(maxYear, year);
        minYear = Math.min(minYear, year);
    }

    int isoStart = (int) LocalDateTime.ofInstant(Instant.ofEpochMilli(isoStartDate),
                                                 ZoneId.systemDefault()).toLocalDate().toEpochDay();

    Field initCompleteField = HijrahChronology.class.getDeclaredField("initComplete");
    initCompleteField.setAccessible(true);
    initCompleteField.set(HijrahChronology.INSTANCE, true);

    Field hijrahStartEpochMonthField = HijrahChronology.class.getDeclaredField("hijrahStartEpochMonth");
    hijrahStartEpochMonthField.setAccessible(true);
    hijrahStartEpochMonthField.set(HijrahChronology.INSTANCE, minYear * 12);

    Field minEpochDayField = HijrahChronology.class.getDeclaredField("minEpochDay");
    minEpochDayField.setAccessible(true);
    minEpochDayField.set(HijrahChronology.INSTANCE, isoStart);

    Method createEpochMonthsMethod = HijrahChronology.class.getDeclaredMethod("createEpochMonths", int.class,
                                                                              int.class, int.class, Map.class);
    createEpochMonthsMethod.setAccessible(true);
    int[] hijrahEpochMonthStartDays = (int[]) createEpochMonthsMethod.invoke(HijrahChronology.INSTANCE, isoStart, minYear, maxYear, years);

    Field hijrahEpochMonthStartDaysField =
                                        HijrahChronology.class.getDeclaredField("hijrahEpochMonthStartDays");
    hijrahEpochMonthStartDaysField.setAccessible(true);
    hijrahEpochMonthStartDaysField.set(HijrahChronology.INSTANCE, hijrahEpochMonthStartDays);

    Field maxEpochDayField = HijrahChronology.class.getDeclaredField("maxEpochDay");
    maxEpochDayField.setAccessible(true);
    maxEpochDayField.set(HijrahChronology.INSTANCE, hijrahEpochMonthStartDays[hijrahEpochMonthStartDays.length - 1]);

    Method getYearLengthMethod = HijrahChronology.class.getDeclaredMethod("getYearLength", int.class);
    getYearLengthMethod.setAccessible(true);

    Field minYearLengthField = HijrahChronology.class.getDeclaredField("minYearLength");
    minYearLengthField.setAccessible(true);

    Field maxYearLengthField = HijrahChronology.class.getDeclaredField("maxYearLength");
    maxYearLengthField.setAccessible(true);

    for(int year = minYear; year < maxYear; year++)
    {
        int length = (int) getYearLengthMethod.invoke(HijrahChronology.INSTANCE, year);
        int minYearLength = (int) minYearLengthField.get(HijrahChronology.INSTANCE);
        int maxYearLength = (int) maxYearLengthField.get(HijrahChronology.INSTANCE);
        minYearLengthField.set(HijrahChronology.INSTANCE, Math.min(minYearLength, length));
        maxYearLengthField.set(HijrahChronology.INSTANCE, Math.max(maxYearLength, length));
    }
}
...