Jodatime 非法即时异常

Jodatime IllegalInstantException

我已经尝试了关于此代码段的几乎所有内容,但我仍然遇到 IllegalInstentException。

public int getDateDay() {
    DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
    DateTime dt;
    try {
        dt = formatter.parseDateTime(date);
    } catch (IllegalInstantException e) {
        dt = formatter.parseLocalDateTime(date).toDateTime();
    }
    return dt.getDayOfMonth();
}

Fatal Exception: org.joda.time.IllegalInstantException Illegal instant due to time zone offset transition (daylight savings time 'gap'): 2018-10-21T00:00:00.000 (America/Sao_Paulo) keyboard_arrow_up arrow_right org.joda.time.chrono.ZonedChronology.localToUTC (ZonedChronology.java:157) org.joda.time.chrono.ZonedChronology.getDateTimeMillis (ZonedChronology.java:122) org.joda.time.chrono.AssembledChronology.getDateTimeMillis (AssembledChronology.java:133) org.joda.time.base.BaseDateTime. (BaseDateTime.java:257) org.joda.time.DateTime. (DateTime.java:532) org.joda.time.LocalDateTime.toDateTime (LocalDateTime.java:750) org.joda.time.LocalDateTime.toDateTime (LocalDateTime.java:731)

似乎输入的日期无效。此问题已在 page.

中讨论

原因:

Joda-Time only allows the key classes to store valid date-times. For example, 31st February is not a valid date so it can't be stored (except in Partial).

The same principle of valid date-times applies to daylight savings time (DST). In many places DST is used, where the local clock moves forward by an hour in spring and back by an hour in autumn/fall. This means that in spring, there is a "gap" where a local time does not exist.

The error "Illegal instant due to time zone offset transition" refers to this gap. It means that your application tried to create a date-time inside the gap - a time that did not exist. Since Joda-Time objects must be valid, this is not allowed.

可能的解决方案可能如下:

  • Use LocalDateTime, as all local date-times are valid.

  • When converting a LocalDate to a DateTime, then use toDateTimeAsStartOfDay() as this handles and manages any gaps.

  • When parsing, use parseLocalDateTime() if the string being parsed has no time-zone.