当前位置: 首页 > 面试题库 >

java.time是否无法解析秒的分数?

司空修贤
2023-03-14
问题内容

在Mac OS X(Mavericks)上的Java 8(b132)的第一个发行版中,使用新java.time包的此代码有效:

String input = "20191203123456"; 
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddHHmmss");
LocalDateTime localDateTime = LocalDateTime.parse( input, formatter );

渲染:

2019-12-03T12:34:56

但是,当我在DateTimeFormatter类doc中指定的几分之一秒内添加“ SS”(并输入“ 55”)时,将引发异常:

java.time.format.DateTimeParseException: Text '2011120312345655' could not be parsed at index 0

文档说严格模式是默认使用的,并且需要与输入数字相同数量的格式字符。所以我很困惑为什么这段代码失败:

String input = "2011120312345655"; 
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddHHmmssSS");
LocalDateTime localDateTime = LocalDateTime.parse( input, formatter );

使用文档(“ 978”)中的示例的另一个示例(失败):

String input = "20111203123456978"; 
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddHHmmssSSS");
LocalDateTime localDateTime = LocalDateTime.parse( input, formatter );

此示例有效,添加了一个小数点(但我在文档中没有找到这样的要求):

String input = "20111203123456.978"; 
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddHHmmss.SSS");
LocalDateTime localDateTime = LocalDateTime.parse( input, formatter );

渲染:

localDateTime: 2011-12-03T12:34:56.978

从输入字符串或格式中省略句点字符会导致失败。

失败:

String input = "20111203123456.978"; 
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddHHmmssSSS");
LocalDateTime localDateTime = LocalDateTime.parse( input, formatter );

失败:

String input = "20111203123456978"; 
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddHHmmss.SSS");
LocalDateTime localDateTime = LocalDateTime.parse( input, formatter );

问题答案:

错误-Java 9中已修复
此问题已在JDK-bug-log中报告。Stephen Colebourne提到以下解决方法:

DateTimeFormatter dtf = 
  new DateTimeFormatterBuilder()
  .appendPattern("yyyyMMddHHmmss")
  .appendValue(ChronoField.MILLI_OF_SECOND, 3)
  .toFormatter();

注意:此解决方法不能涵盖仅两个模式符号SS的用例。调整可能仅是使用其他字段,例如MICRO_OF_SECOND(SSSSSS的6倍)或NANO_OF_SECOND(SSSSSSSSS的9倍)。对于两个小数位数,请参见下面的更新。

@PeterLawrey关于模式符号“ S”的含义,请参见此文档:

分数:以秒为单位输出毫微秒的字段。毫微秒的值具有9位数字,因此,图案字母的计数为1到9。如果小于9,则毫微秒的值将被截断,仅输出最高有效位。在严格模式下解析时,解析位数必须与模式字母的数量匹配。在宽大模式下解析时,解析的位数必须至少是模式字母的数量,最多9位。

因此,我们看到S代表秒的任何分数(包括纳秒),而不仅仅是毫秒。此外,不幸的是,小数部分目前无法很好地进行相邻值解析。

编辑:

作为背景,这里有一些关于相邻值解析的说明。只要用小数点或时间部分分隔符(冒号)之类的文字来分隔字段,对要解析的文本中的字段进行解释就并不困难,因为解析器随后便知道何时停止(即何时结束字段部分)以及下一个字段开始时。因此,如果指定小数点,则JSR-310解析器可以处理文本序列。

但是,如果你有一个跨越多个字段的相邻数字序列,那么会出现一些实现上的困难。为了让解析器知道某个字段何时在文本中停止,必须事先指示解析器给定的字段由固定宽度的数字字符表示。这适用于所有appendValue(…)采用数字表示法的方法。

不幸的是,JSR-310的小数部分(appendFraction(…))也无法很好地做到这一点。如果在类的javadoc中DateTimeFormatterBuilder寻找关键字“ adjacent”,那么你会发现此功能仅由appendValue(…)-methods 实现。请注意,模式字母S的规范略有不同,但内部代表appendFraction()-method。我认为至少要等到Java 9(如JDK-bug-log或更高版本中所述),直到小数部分也可以管理相邻的值解析为止。



 类似资料:
  • 我使用的是 Jackson 2.8,需要与不允许在 ISO 8601 时间戳内毫秒的 API 进行通信。 预期格式为:“ 我正在使用杰克逊的JavaTimeModule,设置为。 但这会打印毫秒。 所以我尝试使用,这没有改变任何东西。 我目前的解决方法是这样的: 我正在重写<code>Instant的默认序列化程序。类</code>。 有没有什么好的方法使用一些配置参数来解决这个问题?

  • 问题内容: 有没有一种方法可以创建JSR-310格式器,该格式器能够以可变的秒分数来解析以下两个日期/时间? 要么 示例代码: 问题答案: 这样可以解决问题: JiriS的答案不正确,因为它使用,而正确的方法是使用(它也处理小数点)。差异可以在第二个系统中看到,其中错误地解析了“2015-05-07T13:20:22.000276”。 在大多数情况下,解析时比直接使用格式化程序更整洁。 使用生成器

  • 当我尝试向github推送一个新的远程分支时,我一直遇到同样的问题,我不知道如何处理它。事情就是这样: 我创建了一个分支,例如 对那个分支进行更改 提交这些更改 然后我签出到我的开发分支(如果由于这样或那样的原因我当时无法推送) 当我返回该分支我尝试推送 我收到消息: 要推送当前分支并将远程设置为上游,请使用 致命:功能/5110无法解析为分支。 我发现解决这个问题的唯一方法是删除我的分支,然后重

  • 运行时错误: 线程"main"java.time.format.DateTimeParseException中的异常:无法在索引20解析文本'1999-09-09 09:09:09.999' 如何解决我的案子?

  • 我们有一个库,用户可以以多种格式传入日期。它们遵循ISO,但有时会缩写。 或者更好的是,是否有某种方法可以解析一个字符串,并且如果字符串对任何日期[时间]都有意义,它会尝试一切可能的方法并返回一个时态对象?

  • 我正在使用lxml的解析一些大的XML文件(3-5Gig)。由于其中一些文件具有无效字符a。 当使用lxml时。埃特里。parse I可以提供一个解析器,用于恢复无效字符: 有没有办法让iterparse获得相同的功能? 编辑:编码不是这里的问题。这些XML文件中存在无效的字符,可以通过定义一个具有恢复=True的XMLParser来清理这些字符。因为我需要为此使用迭代解析,所以我不能使用自定义解