我在 javafx - JDK 8 中使用了 DatePicker 并使用了 HijrahChronology.INSTANCE - 这样日期选择器就会同时显示日历 - 一切正常,但我在公历和回历之间有 1 天的差异。回历倒退 1 天。
我正在尝试根据以下链接更改变体 https://bugs.openjdk.java.net/browse/JDK-8187987
却无法成功。请解释或引用更好或更明确的解决方案。
代码:
HijrahChronology hijriChronology = HijrahChronology.INSTANCE;
dateOfTransaction.setChronology(hijriChronology);
dateOfTransaction是JavaFx中DatePicker的实例 我没有使用过 Joda Time,我也不想使用,除非那是唯一的解决方案。
最佳答案
不幸的是,Java(8 到 10)不支持在运行时提供自定义 Hijrah 变体(这是我几个月前提交的相关错误报告:https://bugs.openjdk.java.net/browse/JDK-8187987)。
但是,有 2 个解决方法:
1- 操纵 JRE 附带的默认 hijrah 变体。在 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- 您可以使用反射 API 在运行时注入(inject)自定义 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));
}
}
关于java - 在 HijrahChronology 中配置自定义变体以进行日期校正 jdk 8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51016469/