Joda 时间 - IllegalFieldValueException:dayOfMonth 的值 30 必须在 [1,29] 范围内
Joda time - IllegalFieldValueException: Value 30 for dayOfMonth must be in the range [1,29]
有一个对某些外部系统的调用,其中 returns 回历日期。在生产环境中,我们收到的是 '30-02-1436'
.
考虑将回历转换为公历日期的代码片段,但它没有这样做。
public static String convertHijriToGregorianDate(String hijriDate){
Chronology iso = ISOChronology.getInstanceUTC(); // get the ISO standard chronology which we follow now
Chronology hijri = IslamicChronology.getInstanceUTC(); // the hijri based chronology
//String hijriDate = "19-08-1435"; // example/format which is received as a parameter in the method from response
if(null != hijriDate && !hijriDate.isEmpty()){
String[] parts = hijriDate.trim().split("-"); // you will get an array of size 3 by splitting with regex '-'
String hijriYear = parts[2];
String hijriMonth = parts[1];
String hijriDay = parts[0];
// Construct the Local Date corresponding to the hijri chronology
LocalDate todayHijri = new LocalDate(Integer.parseInt(hijriYear), Integer.parseInt(hijriMonth), Integer.parseInt(hijriDay), hijri);
// Construct the Local Date corresponding to the iso chronology based on the hijri date
LocalDate todayIso = new LocalDate(todayHijri.toDateTimeAtStartOfDay(), iso);
return String.valueOf(todayIso);
}
return null;
}
请指出代码有什么问题。我们在 stacktrace-
中遇到了这个问题
org.joda.time.IllegalFieldValueException: Value 30 for dayOfMonth must
be in the range [1,29]
at org.joda.time.field.FieldUtils.verifyValueBounds(FieldUtils.java:252)
at org.joda.time.chrono.BasicChronology.getDateMidnightMillis(BasicChronology.java:632)
at org.joda.time.chrono.BasicChronology.getDateTimeMillis0(BasicChronology.java:186)
at org.joda.time.chrono.BasicChronology.getDateTimeMillis(BasicChronology.java:160)
at org.joda.time.chrono.LimitChronology.getDateTimeMillis(LimitChronology.java:177)
at org.joda.time.chrono.BasicChronology.getDateTimeMillis(BasicChronology.java:155)
at org.joda.time.LocalDate.(LocalDate.java:457)
使用的 Joda 时间版本是 2.9.1
我已经通过表达式
检查了 Joda-Time 中所有可用的闰年模式 (=4)
Chronology hijri =
IslamicChronology.getInstance(DateTimeZone.UTC, IslamicChronology.LEAP_YEAR_15_BASED);
很遗憾,没有任何适合您的方法。但是,沙特阿拉伯的 umalqura-calendar 认为“30-02-1436”有效。它对应公历日期 2014-12-22。
Joda-Time 不支持伊斯兰历的这种变体,因此您无法在此处执行任何操作,除非您愿意迁移到包含 umalqura 变体的 Java-8。
System.out.println(HijrahDate.of(1436, 2, 30)); // Hijrah-umalqura AH 1436-02-30
DateTimeFormatter fh =
DateTimeFormatter.ofPattern(
"dd-MM-yyyy",
Locale.forLanguageTag("en")
).withChronology(HijrahChronology.INSTANCE);
System.out.println(HijrahDate.from(fh.parse(input)));
// Hijrah-umalqura AH 1436-02-30
System.out.println(LocalDate.from(HijrahDate.from(fh.parse(input))));
// 2014-12-22
注意:不幸的是,unicode 扩展 Locale.forLanguageTag("en-u-ca-islamic-umalqura")
在我的实验中似乎不起作用,因此有必要明确指定时间顺序。
选择:
如果您无法迁移到 Java-8 或什至需要伊斯兰日历的更多功能(例如其他变体,如 Joda-Time 中使用的那些),那么您也可以试试我的图书馆 Time4J:
String input = "30-02-1436";
ChronoFormatter<HijriCalendar> hf =
ChronoFormatter.ofPattern(
"dd-MM-yyyy",
PatternType.CLDR,
Locale.ROOT,
HijriCalendar.family()
).withCalendarVariant(HijriCalendar.VARIANT_UMALQURA).with(Leniency.STRICT);
System.out.println(hf.parse(input)); // AH-1436-02-30[islamic-umalqura]
System.out.println(hf.parse(input).transform(PlainDate.axis())); // 2014-12-22
日期被解释为 2 月 30 日,但这个月必须少于 30 天。这解释了错误消息。因此请更正输入,使其对应于可能的日期。
有一个对某些外部系统的调用,其中 returns 回历日期。在生产环境中,我们收到的是 '30-02-1436'
.
考虑将回历转换为公历日期的代码片段,但它没有这样做。
public static String convertHijriToGregorianDate(String hijriDate){
Chronology iso = ISOChronology.getInstanceUTC(); // get the ISO standard chronology which we follow now
Chronology hijri = IslamicChronology.getInstanceUTC(); // the hijri based chronology
//String hijriDate = "19-08-1435"; // example/format which is received as a parameter in the method from response
if(null != hijriDate && !hijriDate.isEmpty()){
String[] parts = hijriDate.trim().split("-"); // you will get an array of size 3 by splitting with regex '-'
String hijriYear = parts[2];
String hijriMonth = parts[1];
String hijriDay = parts[0];
// Construct the Local Date corresponding to the hijri chronology
LocalDate todayHijri = new LocalDate(Integer.parseInt(hijriYear), Integer.parseInt(hijriMonth), Integer.parseInt(hijriDay), hijri);
// Construct the Local Date corresponding to the iso chronology based on the hijri date
LocalDate todayIso = new LocalDate(todayHijri.toDateTimeAtStartOfDay(), iso);
return String.valueOf(todayIso);
}
return null;
}
请指出代码有什么问题。我们在 stacktrace-
中遇到了这个问题org.joda.time.IllegalFieldValueException: Value 30 for dayOfMonth must be in the range [1,29] at org.joda.time.field.FieldUtils.verifyValueBounds(FieldUtils.java:252) at org.joda.time.chrono.BasicChronology.getDateMidnightMillis(BasicChronology.java:632) at org.joda.time.chrono.BasicChronology.getDateTimeMillis0(BasicChronology.java:186) at org.joda.time.chrono.BasicChronology.getDateTimeMillis(BasicChronology.java:160) at org.joda.time.chrono.LimitChronology.getDateTimeMillis(LimitChronology.java:177) at org.joda.time.chrono.BasicChronology.getDateTimeMillis(BasicChronology.java:155) at org.joda.time.LocalDate.(LocalDate.java:457)
使用的 Joda 时间版本是 2.9.1
我已经通过表达式
检查了 Joda-Time 中所有可用的闰年模式 (=4)Chronology hijri =
IslamicChronology.getInstance(DateTimeZone.UTC, IslamicChronology.LEAP_YEAR_15_BASED);
很遗憾,没有任何适合您的方法。但是,沙特阿拉伯的 umalqura-calendar 认为“30-02-1436”有效。它对应公历日期 2014-12-22。
Joda-Time 不支持伊斯兰历的这种变体,因此您无法在此处执行任何操作,除非您愿意迁移到包含 umalqura 变体的 Java-8。
System.out.println(HijrahDate.of(1436, 2, 30)); // Hijrah-umalqura AH 1436-02-30
DateTimeFormatter fh =
DateTimeFormatter.ofPattern(
"dd-MM-yyyy",
Locale.forLanguageTag("en")
).withChronology(HijrahChronology.INSTANCE);
System.out.println(HijrahDate.from(fh.parse(input)));
// Hijrah-umalqura AH 1436-02-30
System.out.println(LocalDate.from(HijrahDate.from(fh.parse(input))));
// 2014-12-22
注意:不幸的是,unicode 扩展 Locale.forLanguageTag("en-u-ca-islamic-umalqura")
在我的实验中似乎不起作用,因此有必要明确指定时间顺序。
选择:
如果您无法迁移到 Java-8 或什至需要伊斯兰日历的更多功能(例如其他变体,如 Joda-Time 中使用的那些),那么您也可以试试我的图书馆 Time4J:
String input = "30-02-1436";
ChronoFormatter<HijriCalendar> hf =
ChronoFormatter.ofPattern(
"dd-MM-yyyy",
PatternType.CLDR,
Locale.ROOT,
HijriCalendar.family()
).withCalendarVariant(HijriCalendar.VARIANT_UMALQURA).with(Leniency.STRICT);
System.out.println(hf.parse(input)); // AH-1436-02-30[islamic-umalqura]
System.out.println(hf.parse(input).transform(PlainDate.axis())); // 2014-12-22
日期被解释为 2 月 30 日,但这个月必须少于 30 天。这解释了错误消息。因此请更正输入,使其对应于可能的日期。