How to handle all Zone Offset in one DateTimeFormater Java 8

拜拜、爱过 提交于 2019-12-06 01:50:25

Another alternative is to use optional sections, delimited by [], and the respective offset patterns (VV and x):

DATE_TIME_FORMATTER = DateTimeFormatter
                         // pattern with optional sections: fraction of seconds and offsets
                         .ofPattern("yyyy-MM-dd'T'HH:mm:ss[.SSSSSS][VV][x][xx][xxx]");

Each pair of [] is equivalent to one optionalStart and optionalEnd section. Note that I also had to include the uppercase S (fraction of second) as optional, to parse the case where this field is not present.

The other patterns (VV and x) correspond to the various offsets you need. From the javadoc:

Pattern  Count  Equivalent builder methods
-------  -----  --------------------------
  VV      2      appendZoneId()
  x       1      appendOffset("+HHmm","+00")
  xx      2      appendOffset("+HHMM","+0000")
  xxx     3      appendOffset("+HH:MM","+00:00")

This works for all your input dates.


The only difference is that [.SSSSSS] accepts exactly 6 digits in the fraction-of-seconds field (or zero digits, as it's an optional section), while appendFraction accepts any quantity from 0 to 6 digits. To get exactly this same behaviour, you must use the DateTimeFormatterBuilder:

DATE_TIME_FORMATTER = new DateTimeFormatterBuilder()
    // date and time
    .appendPattern("yyyy-MM-dd'T'HH:mm:ss")
    // fraction of seconds, from 0 to 6 digits
    .appendFraction(ChronoField.MICRO_OF_SECOND, 0, 6, true)
    // optional offset patterns
    .appendPattern("[VV][x][xx][xxx]")
    .toFormatter();

Simply reverse the order of your optional sections:

private static final DateTimeFormatter DATE_TIME_FORMATTER = new DateTimeFormatterBuilder()
        .appendPattern("yyyy-MM-dd'T'HH:mm:ss")
        .appendFraction(ChronoField.MICRO_OF_SECOND, 0, 6, true)
        .optionalStart().appendZoneId().optionalEnd()
        .optionalStart().appendOffset("+HHmm", "+0000").optionalEnd()
        .optionalStart().appendOffset("+HH:mm", "+00:00").optionalEnd()
        .optionalStart().appendOffset("+HH", "+00").optionalEnd()
        .toFormatter();

This parses all your 10 sample date-time strings.

I am not quite sure why it works. I suppose that it is now trying +HHmm before +HH, which makes sure it gets alle four digits when there are four, instead of leaving the last two unparsed.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!