【问题标题】:Parsing date-time input string with omitted minutes, using java.time classes使用 java.time 类解析省略分钟的日期时间输入字符串
【发布时间】:2018-08-16 04:56:42
【问题描述】:

我在几乎标准的ISO 8601 中输入了字符串,但省略了分钟部分(不要问为什么,我无法控制时髦的数据)。

2018-01-23T12

如何在让分钟默认为零的情况下解析它?

2018-01-23T12:00

DateTimeFormatter.ISO_LOCAL_DATE_TIME

LocalDateTime 的默认解析器是 DateTimeFormatter.ISO_LOCAL_DATE_TIME。此格式化程序允许可选的秒数。小数秒和秒都设置为零。

LocalDateTime ldt = LocalDateTime.parse( "2018-01-23T12:00" ) ;  // Works.

但是忽略分钟会失败,并抛出异常。

LocalDateTime ldt = LocalDateTime.parse( "2018-01-23T12" ) ;  // Fails.

DateTimeFormatterBuilder

我知道DateTimeFormatterBuilder 类及其在设置默认值时容忍可选部分的能力。

但是我已经能够正确使用它了。我尝试了模式"uuuu-MM-dd HH",同时将分钟和秒都设置为默认为零。

String input = "2018-01-23T12";

DateTimeFormatterBuilder b = new DateTimeFormatterBuilder().parseDefaulting( ChronoField.MINUTE_OF_HOUR , 0 ).parseDefaulting( ChronoField.SECOND_OF_MINUTE , 0 ).appendPattern( "uuuu-MM-dd HH" );
DateTimeFormatter f = b.toFormatter( Locale.US );
LocalDateTime ldt = LocalDateTime.parse( input , f );
System.out.println( ldt );

抛出异常:

线程“main”java.time.format.DateTimeParseException 中的异常:无法在索引 10 处解析文本“2018-01-23T12”

在 java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1988)

在 java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1890)

在 java.base/java.time.LocalDateTime.parse(LocalDateTime.java:492)

在 com.basilbourque.example.App.doIt(App.java:31)

在 com.basilbourque.example.App.main(App.java:22)

【问题讨论】:

  • 这有点hacky,但是你有没有想过+":00"到字符串的末尾?
  • @Autumnal 是的,但是……我真的想更多地了解DateTimeFormatterBuilder 的工作原理。换句话说,我对教育比对解决方案更感兴趣。这个特殊问题似乎是 Stack Overflow 问题的一个很好的例子,因为 DateTimeFormatterBuilder"optional""default" 上的其他六个问题都没有涵盖这个。

标签: parsing datetime format java-time


【解决方案1】:

如果您仔细查看错误消息,您会看到它说:Text '2018-01-23T12' could not be parsed at index 10 这意味着问题在于格式中的 T。

如果我们再回到DateTimeFormatterBuilder,指定的模式是:"uuuu-MM-dd HH"。这就是问题所在,当实际上有一个 T 时,它指定了一个空格。解决方案是将此模式替换为:"uuuu-MM-dd'T'HH"

String input = "2018-01-23T12";

DateTimeFormatterBuilder b = new DateTimeFormatterBuilder().parseDefaulting( ChronoField.MINUTE_OF_HOUR , 0 ).parseDefaulting( ChronoField.SECOND_OF_MINUTE , 0 ).appendPattern( "uuuu-MM-dd'T'HH" );
DateTimeFormatter f = b.toFormatter( Locale.US );
LocalDateTime ldt = LocalDateTime.parse( input , f );
System.out.println( ldt );

2018-01-23T12:00

确实,您甚至根本不需要构建器。使用相同的模式指定 DateTimeFormatter。小时的分钟默认为零。

String input = "2018-01-23T12";

DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH" ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f );

2018-01-23T12:00

【讨论】:

  • 哦,哎呀。在我的实验中,我把它搞砸了。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多