时区偏移的 java.time DateTimeFormatter 模式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30710829/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 10:02:58  来源:igfitidea点击:

java.time DateTimeFormatter pattern for timezone offset

javadateparsingformatterjava-time

提问by Cheetah

I am trying to parse: 2014-05-02-10.45.05.993280-5:00where the -5:00is the offset from UTC. Using a java.time DateTimeFormatterin Java 8.

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

For the first bit I have the following: yyyy-MM-dd-HH.mm.ss.SSSSSShowever, I can't figure out what the pattern should be to parse the offset also.

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

If I had the offset with 4 digits (-05:00) I could use: yyyy-MM-dd-HH.mm.ss.SSSSSSxxx, but this doesn't work for 3 digits.

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

Any ideas?

有任何想法吗?

采纳答案by Meno Hochschild

Use capital letter X instead of x, hence XXX. The difference is that big X can recognize the input letter "Z" as UTC-Offset +00:00 while small pattern letter X cannot.

使用大写字母 X 而不是 x,因此是 XXX。区别在于大X可以将输入字母“Z”识别为UTC-Offset +00:00,而小模式字母X则不能。

Suggested pattern:

建议模式:

yyyy-MM-dd-HH.mm.ss.SSSSSSXXX

Please be also aware of following JDK-bug:

还请注意以下JDK 错误

java.time.format.DateTimeFormatter cannot parse an offset with single digit hour

java.time.format.DateTimeFormatter 无法解析具有单位数小时的偏移量

UPDATE:

更新:

I have now tested the described workaround in the 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));

But it throws an exception:

但它抛出一个异常:

Exception in thread "main" java.time.format.DateTimeParseException: Text '2014-05-02-10.45.05.993280-5:00' could not be parsed at index 26 at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1947) at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1849) at HelloWorld.main(HelloWorld.java:16)

线程“main”中的异常 java.time.format.DateTimeParseException: 文本 '2014-05-02-10.45.05.993280-5:00' 无法在 java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter. java:1947) 在 java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1849) 在 HelloWorld.main(HelloWorld.java:16)

So lenient parsing does not help either. So there are now only three options left for you:

所以宽松的解析也无济于事。所以现在你只剩下三个选择:

  • Use workaround suggested by bug reporter: [...] workaround is to parse the date/time separately, use a hand coded parser for the offset and combine the LocalDateTime with the hand parsed offset. Not an easy work around.

  • Try your own specialized string preprocessing. If you have a fixed format then you can try to insert the zero-digit at position 26 (if the total input length is one digit too small).

  • Or you use an external library which can do this. My library Time4J (v4.0) can do that if you are willing to add an extra dependency. See this code:

  • 使用错误报告者建议的解决方法:[...] 解决方法是单独解析日期/时间,使用手动编码解析器作为偏移量,并将 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();

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();

Update:According to JDK-bug-status, the bug has been fixed for Java-9, but a backport for Java-8 does not seem to be available though.

更新:根据 JDK-bug-status,该错误已针对 Java-9 修复,但 Java-8 的反向移植似乎不可用。

回答by Jordi Castilla

Offset for SimpleDateFormatsign is Zcheck Java7or Java8SimpleDateFormat API.

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

Then, your parser format for String

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

2014-05-02-10.45.05.993280-5:00

must be:

必须是:

yyyy-MM-dd-HH.mm.ss.SSSSSSZ

UPDATE: for DateTimeFormatterthe offset Patterns for Formatting and Parsingare:

更新:用于格式化和解析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;

Your desired pattern in DateTimeFormatteris X.

您想要的模式DateTimeFormatterX