Java 8中无法使用DateTimeFormatter和ZonedDateTime从TemporalAccessor获



我最近迁移到Java 8,希望能够更轻松地处理本地和分区时间。

然而,在我看来,在解析一个简单的日期时,我面临着一个简单的问题。

public static ZonedDateTime convertirAFecha(String fecha) throws Exception {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
            ConstantesFechas.FORMATO_DIA).withZone(
            obtenerZonaHorariaServidor());
    ZonedDateTime resultado = ZonedDateTime.parse(fecha, formatter);
    return resultado;
}

在我的例子中:

  • fecha is '15/06/2014'
  • ConstantesFechas。FORMATO_DIA is 'dd/MM/yyyy'
  • obtenerZonaHorariaServidor返回ZoneId.systemDefault()

这是一个简单的例子。但是,解析会抛出以下异常:

java.time.format。DateTimeParseException:文本'15/06/2014'不能无法从TemporalAccessor获取ZonedDateTime{},ISO解析为2014-06-15类型java.time.format.Parsed

提示吗?我一直在尝试解析和使用TemporalAccesor的不同组合,但到目前为止还没有任何运气。

这不起作用,因为您的输入(和Formatter)没有时区信息。一种简单的方法是首先将日期解析为LocalDate(不包含时间或时区信息),然后创建ZonedDateTime:

public static ZonedDateTime convertirAFecha(String fecha) {
  DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
  LocalDate date = LocalDate.parse(fecha, formatter);
  ZonedDateTime resultado = date.atStartOfDay(ZoneId.systemDefault());
  return resultado;
}

这是一个错误,请参阅JDK-bug-log。根据这些信息,Java 9和Java 8u20的问题已经解决了。请尝试下载最新的Java 8 -版本。今天2014-05-12:有一个早期访问版本8u20可用。

更新:

我个人认为,既然你只有并期望"dd/MM/yyyy"作为模式,你应该使用LocalDate作为你的主要类型,就像@assylias已经提出的那样。关于您的上下文,几乎可以肯定使用ZonedDateTime是一个设计失败。您想对这种类型的对象做什么?我只能把专门的时区计算当作用例。而且你甚至不能直接将这些ZonedDateTime -对象存储在数据库中,所以这种类型远没有许多人想象的那么有用。

我所描述的用例问题实际上是Java-8与旧的GregorianCalendar类(这是一种all-in-one类型)相比引入的一个新方面。用户必须开始考虑为他们的问题和用例选择合适的时态类型。

简单来说,

ZonedDateTime.parse('2014-04-23', DateTimeFormatter.ISO_OFFSET_DATE_TIME)

抛出异常:

Text '2014-04-23' could not be parsed at index 10
java.time.format.DateTimeParseException: Text '2014-04-23' could not be parsed at index 10

在我看来这是一个bug。

我使用了这个方法:

String dateAsStr = '2014-04-23';
if (dateAsStr.length() == 10) {
    dateAsStr += 'T00:00:00';
}
ZonedDateTime.parse(dateAsStr, DateTimeFormatter.ISO_OFFSET_DATE_TIME.withZone(ZoneId.systemDefault()));

如果来自Google:

而不是:

ZonedDateTime.from(new Date().toInstant());

试试这个:

ZonedDateTime.ofInstant(new Date(), ZoneId.of("UTC")); 

只是一个示例转换,我相信有些人会得到下面的异常

(java.time.DateTimeException: Unable to obtain LocalDateTime from TemporalAccessor: 2014-10-24T18:22:09.800Z of type java.time.Instant)

如果他们尝试

LocalDateTime localDateTime = LocalDateTime.from(new Date().toInstant());

要解决这个问题,请传入Zone -

LocalDateTime localDateTime = LocalDateTime.from(new Date()
        .toInstant().atZone(ZoneId.of("UTC")));

相关内容

  • 没有找到相关文章

最新更新