UnsupportedTemporalTypeException:不支持的字段:InstantSeconds

Ste*_*eve 5 java formatting datetime java-8

我有这段代码正在生成一个时间戳,然后解析。

DateTimeFormatter formatter = 
    DateTimeFormatter
        .ofPattern("yyyyMMdd kk:HH:ss.SSSZ")
        .withLocale(Locale.getDefault())
        .withZone(ZoneId.systemDefault());

Instant now = Instant.now();

String formatted = formatter.format(now);
Instant parsed = formatter.parse(formatted, Instant::from);
Run Code Online (Sandbox Code Playgroud)

运行时,最后一行会产生异常:

java.time.format.DateTimeParseException: Text '20180123 12:12:45.648-0500' could not be parsed: Unable to obtain Instant from TemporalAccessor: {SecondOfMinute=45, NanoOfSecond=648000000, OffsetSeconds=-18000, MilliOfSecond=648, MicroOfSecond=648000, HourOfDay=12},ISO,America/New_York resolved to 2018-01-23 of type java.time.format.Parsed

Caused by: java.time.DateTimeException: Unable to obtain Instant from TemporalAccessor: {SecondOfMinute=45, NanoOfSecond=648000000, OffsetSeconds=-18000, MilliOfSecond=648, MicroOfSecond=648000, HourOfDay=12},ISO,America/New_York resolved to 2018-01-23 of type java.time.format.Parsed

Caused by: java.time.temporal.UnsupportedTemporalTypeException: **Unsupported field: InstantSeconds**
Run Code Online (Sandbox Code Playgroud)

我用DateTimeFormatter.ISO_INSTANT替换了格式化程序,它可以正常工作。产生的实际数据几乎相同。什么是断开连接?

ISO_INSTANT:  2018-01-23T16:51:25.516Z
My Format:    20180119 23:59:59.999-0800
Run Code Online (Sandbox Code Playgroud)

我必须使用我的格式。这里有什么问题?

Fra*_*lis 11

我知道这是一个老问题,但如果您正在寻找一个简短的答案,只需向 DateTimeFormatter 添加区域设置和区域,您也可以使用默认的:.withLocale(Locale.getDefault()).withZone(ZoneId.systemDefault())

这是代码示例:

    Instant now = Instant.now();
    System.out.println(now.toString());
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss").withLocale(Locale.getDefault()).withZone(ZoneId.systemDefault());
    System.out.println(formatter.format(now));
Run Code Online (Sandbox Code Playgroud)

此代码将使用当前时刻,输出样本,使用日期时间格式化程序对其进行格式化,然后输出格式化的时刻。


Ian*_*bes 6

问题在于您的格式不能完全代表即时消息,因为您的格式根本没有几分钟的代表。格式化程序可以正确地使用Instant并以您的格式输出结果,因为Instant具有格式所需的所有数据,但是您的格式不具备Instant所需的所有数据。

尝试将模式更改为yyyyMMdd kk:HH:mm:ss.SSS,您将看到代码现在可以工作了。请注意添加mm

如果绝对需要无缝模式,则应进行自己的TemporalQuery来从TemporalAccessor中提取所需的信息。在这种情况下,我将分钟设置为0

public class MyQuery implements TemporalQuery<Instant> {

    @Override
    public Instant queryFrom(TemporalAccessor temporal) {
        LocalDate ld = LocalDate.from(temporal);
        LocalTime lt = LocalTime.of(temporal.get(ChronoField.HOUR_OF_DAY), 0, temporal.get(ChronoField.SECOND_OF_MINUTE), temporal.get(ChronoField.NANO_OF_SECOND));
        return ZonedDateTime.of(ld, lt, ZoneId.systemDefault()).toInstant();
    }

}
Run Code Online (Sandbox Code Playgroud)

然后,我们可以像下面这样使用TemporalQuery:

public class Test {
    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter
            .ofPattern("yyyyMMdd kk:HH:mm:ss.SSS")
            .withLocale(Locale.getDefault())
            .withZone(ZoneId.systemDefault());

        Instant now = Instant.now();

        String formatted = formatter.format(now);
        System.out.println(formatted);

        Instant ld = formatter.parse(formatted, new MyQuery());
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 再考虑一下,您可能还用`kk:HH`复制了小时字段,这意味着您有两种小时表示形式... (3认同)
  • @Steve错误消息很难理解,因为InstantSeconds表示自纪元以来的秒数,并且如果没有`MINUTES_OF_HOUR`,我们将无法获得InstantSeconds。我希望错误消息更好! (2认同)