Java 在HijrahChronology中为日期更正jdk 8配置自定义变量

Java 在HijrahChronology中为日期更正jdk 8配置自定义变量,java,javafx,java-8,javafx-8,java-time,Java,Javafx,Java 8,Javafx 8,Java Time,我在javafx-JDK 8中使用了DatePicker,并使用了HijrahChronology.INSTANCE,这样日期选择器就可以同时显示日历了——一切都很好,但我在公历和hijri日历之间有1天的差异。Hijri日历向后1天 我正在尝试根据以下链接更改变体 但却无法成功。请解释或提供更好或明确的解决方案 代码: dateOfTransaction是JavaFx中DatePicker的实例 我没有使用过Joda Time,我也不想使用,除非这是唯一的解决方案。不幸的是,Java(8到1

我在javafx-JDK 8中使用了DatePicker,并使用了HijrahChronology.INSTANCE,这样日期选择器就可以同时显示日历了——一切都很好,但我在公历和hijri日历之间有1天的差异。Hijri日历向后1天

我正在尝试根据以下链接更改变体

但却无法成功。请解释或提供更好或明确的解决方案

代码:

dateOfTransaction是JavaFx中DatePicker的实例 我没有使用过Joda Time,我也不想使用,除非这是唯一的解决方案。

不幸的是,Java(8到10)不支持在运行时提供定制的Hijrah变体(以下是我几个月前提交的相关bug报告:)

但是,有两种变通方法:

1-操作JRE附带的默认hijrah变体。在Java 8中,您可以在以下位置找到它:

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

在Java 9和10中,它捆绑在以下位置:

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

2-您可以在运行时使用反射API注入自定义Hijrah变体:

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));
    }
}
public static void injectCustomHijriVariant(地图年份月地图,长isoStartDate)
抛出NoSuchFieldException、IllegalAccessException、NoSuchMethodException、InvocationTargetException
{
int minYear=Integer.MAX_值;
int maxYear=Integer.MIN_值;
for(int year:yearMonthMap.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(hijrahronomology.INSTANCE,true);
字段hijrahStartEpochMonthField=HijrahChronology.class.getDeclaredField(“hijrahStartEpochMonth”);
hijrahStartEpochMonthField.setAccessible(true);
hijrahStartEpochMonthField.set(hijrahronomology.INSTANCE,minYear*12);
Field minEpochDayField=HijrahChronology.class.getDeclaredField(“minEpochDay”);
minEpochDayField.setAccessible(true);
minEpochDayField.set(hijrahromology.INSTANCE,isoStart);
方法createEpochMonthMethod=HijrahChronology.class.getDeclaredMethod(“createEpochMonths”,int.class,
int.class,int.class,Map.class);
CreatePochMonthsMethod.setAccessible(true);
int[]hijrahEpochMonthStartDays=(int[])createEpochMonthsMethod.invoke(HijrahChronology.INSTANCE,isoStart,minYear,maxYear,years);
字段HIJRAHEPHOMONTHSTARTDAYSFIELD=
HijrahChronology.class.getDeclaredField(“hijrahEpochMonthStartDays”);
hijrahEpochMonthStartDaysField.setAccessible(true);
hijrahEpochMonthStartDaysField.set(hijrahromology.INSTANCE,hijrahEpochMonthStartDays);
Field maxEpochDayField=hijrahromology.class.getDeclaredField(“maxEpochDay”);
maxEpochDayField.setAccessible(true);
maxEpochDayField.set(HijrahChronology.INSTANCE,hijrahEpochMonthStartDays[hijrahEpochMonthStartDays.length-1]);
方法getYearLengthMethod=HijrahChronology.class.getDeclaredMethod(“getYearLength”,int.class);
getYearLengthMethod.setAccessible(true);
Field minYearLengthField=hijrahronomology.class.getDeclaredField(“minYearLength”);
minYearLengthField.setAccessible(真);
Field maxYearLengthField=HijrahChronology.class.getDeclaredField(“maxYearLength”);
maxYearLengthField.setAccessible(真);
对于(int year=minYear;year
如果您需要帮助修复代码,我想您需要向我们展示您的代码。“我的千里眼”目前正在低潮运行。请将行int[]中的“yearMonthsMap”替换为“yearMonthsMap”(int[])CreatePochMonthsMethod.invoke(HijrahChronology.INSTANCE,isoStart,minYear,maxYear,years);感谢您在使用任何日期/时间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));
    }
}