用于时区偏移的java.time DateTimeFormatter模式

Che*_*tah 15 java parsing date formatter java-time

我正在尝试解析:2014-05-02-10.45.05.993280-5:00-5:00是与UTC的偏移量.DateTimeFormatter在Java 8中使用java.time .

对于第一位,我有以下内容:yyyy-MM-dd-HH.mm.ss.SSSSSS但是,我无法弄清楚解析偏移量的模式应该是什么.

如果我有4位数(-05:00)的偏移量,我可以使用:yyyy-MM-dd-HH.mm.ss.SSSSSSxxx,但这不适用于3位数.

有任何想法吗?

Men*_*ild 17

使用大写字母X代替x,因此使用XXX.区别在于大X可以将输入字母"Z"识别为UTC-Offset +00:00,而小型字母X则不能.

建议模式:

yyyy-MM-dd-HH.mm.ss.SSSSSSXXX
Run Code Online (Sandbox Code Playgroud)

请注意以下JDK-bug:

java.time.format.DateTimeFormatter无法解析单个数字小时的偏移量

更新:

我现在已经在bug-log中测试了所描述的解决方法.

String input = "2014-05-02-10.45.05.993280-5:00";
DateTimeFormatter f = new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd-HH.mm.ss.SSSSSS").parseLenient().appendOffset("+HH:MM", "Z").toFormatter();
System.out.println(f.parse(input, ZonedDateTime::from));
Run Code Online (Sandbox Code Playgroud)

但它引发了一个例外:

线程"main"中的异常java.time.format.DateTimeParseException:无法在java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.)的索引26处解析文本'2014-05-02-10.45.05.993280-5:00'. java:1947)at HelloWorld.main的java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1849)(HelloWorld.java:16)

因此,宽松的解析也无济于事.所以现在只剩下三个选项了:

  • 使用bug报告器建议的解决方法:[...]解决方法是分别解析日期/时间,使用手动编码解析器进行偏移,并将LocalDateTime与手解析偏移量结合起来.不是一件容易的事.

  • 尝试自己专门的字符串预处理.如果您有固定格式,那么您可以尝试在位置26插入零位数(如果总输入长度是一个数字太小).

  • 或者您使用可以执行此操作的外部库.如果您愿意添加额外的依赖项,我的库Time4J(v4.0)可以做到这一点.看到这段代码:

String input = "2014-05-02-10.45.05.993280-5:00"; ZonalDateTime zdt = ZonalDateTime.parse( input, Moment.localFormatter("yyyy-MM-dd-HH.mm.ss.SSSSSSXXX", PatternType.CLDR)); System.out.println(zdt); // 2014-05-02T10:45:05,993280UTC-05:00 ZonedDateTime result = zdt.toTemporalAccessor();

更新:根据JDK-bug-status,该错误已针对Java-9修复,但Java-8的后端似乎不可用.


msa*_*gel 17

所有的答案都很好。java8+ 有以下用于解析和格式化时区的模式:V, z, O, X, x, Z

这是根据文档中的规则进行解析的:

   Symbol  Meaning                     Presentation      Examples
   ------  -------                     ------------      -------
   V       time-zone ID                zone-id           America/Los_Angeles; Z; -08:30
   z       time-zone name              zone-name         Pacific Standard Time; PST
   O       localized zone-offset       offset-O          GMT+8; GMT+08:00; UTC-08:00;
   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;
   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15;
   Z       zone-offset                 offset-Z          +0000; -0800; -08:00;
Run Code Online (Sandbox Code Playgroud)

但是格式化怎么样?下面是一个日期示例(假设ZonedDateTime),显示了不同格式模式的这些模式行为:

   Symbol  Meaning                     Presentation      Examples
   ------  -------                     ------------      -------
   V       time-zone ID                zone-id           America/Los_Angeles; Z; -08:30
   z       time-zone name              zone-name         Pacific Standard Time; PST
   O       localized zone-offset       offset-O          GMT+8; GMT+08:00; UTC-08:00;
   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;
   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15;
   Z       zone-offset                 offset-Z          +0000; -0800; -08:00;
Run Code Online (Sandbox Code Playgroud)

在正偏移的情况下,+符号字符在任何地方都使用(-现在有的地方)并且永远不会被省略。

这对于新类型很有效java.time。如果您打算将它们用于java.util.Datejava.util.Calendar- 并非所有类型都可以工作,因为这些类型已损坏(因此标记为已弃用,请不要使用它们)


Jor*_*lla 8

SimpleDateFormat符号的偏移量是ZcheckJava7或。Java8 SimpleDateFormat API

然后,您的解析器格式为 String

2014-05-02-10.45.05.993280-5:00
Run Code Online (Sandbox Code Playgroud)

必须是:

yyyy-MM-dd-HH.mm.ss.SSSSSSZ
Run Code Online (Sandbox Code Playgroud)

更新:用于格式化和解析DateTimeFormatter的偏移模式是:

O       localized zone-offset       offset-O          GMT+8; GMT+08:00; UTC-08:00;
X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;
x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15;
Z       zone-offset                 offset-Z          +0000; -0800; -08:00;
Run Code Online (Sandbox Code Playgroud)

您想要的模式DateTimeFormatterX

  • 我正在使用 `DateTimeFormatter` 并且添加一个 `Z` 似乎不起作用 (2认同)