英文:
Java DateTimeFormatter parsing with special characters
问题
我在使用DateTimeFormatter
解析格式为以下的日期时间String
时遇到了问题:
20200915095318.883[-4:EDT]
我有一个DateTimeFormatter
的模式可以用来生成这种格式,但不能用来解析相同的字符串。该模式为:
yyyyMMddHHmmss.SSS'[x:z]'
如果有其他适用于这种需求的日期时间解析库,我也愿意考虑。目前我的解决方案是遇到这种日期时间字符串时使用一次性正则匹配器,并手动构建其各个部分。这种方法相当繁琐。
英文:
I'm having some troubles getting my format right for using DataTimeFormatter
to parse a date time String
in the format of:
20200915095318.883[-4:EDT]
I have a DateTimeFormatter
pattern that works to produce this format, but it doesn't work to parse the same String. That pattern is:
yyyyMMddHHmmss.SSS'['x':'z']'
If there are other libraries for DateTime parsing that are more appropriate for this type of need I'll happily consider those as well. Right now my solution is a one off regex matcher for when I encounter this DateTime String and to manually build its parts. Which is gross.
答案1
得分: 5
java.time,这个现代的Java日期和时间API,我想您可能已经在使用了,确实是最适合这项工作的库。从Java 9开始,就可以使用以下代码:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("uuuuMMddHHmmss")
.appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true)
.appendLiteral('[')
.appendOffset("+Hmm", "+0")
.appendLiteral(':')
.appendZoneText(TextStyle.SHORT)
.appendLiteral(']')
.toFormatter(Locale.ENGLISH);
String s = "20200915095318.883[-4:EDT]";
OffsetDateTime odt = OffsetDateTime.parse(s, formatter);
ZonedDateTime zdt = ZonedDateTime.parse(s, formatter);
if (odt.getOffset().equals(zdt.getOffset())) {
System.out.println(odt);
System.out.println(zdt);
} else {
System.out.println("Something's wrong here");
}
输出结果为:
> 2020-09-15T09:53:18.883-04:00
> 2020-09-15T09:53:18.883-04:00[America/New_York]
将字符串解析为OffsetDateTime
使用偏移量-4
,而解析为ZonedDateTime
则使用时区缩写EDT
。我检查这两者的偏移量是否一致,因为如果不一致,我就无法确定哪个是正确的。在您的示例字符串中,它们是一致的。
我将+Hmm
作为模式传递给appendOffset()
方法。其他选择包括+H
、+H:mm
、+Hmmss
和+H:mm:ss
。小写的mm
和ss
表示偏移量的分钟和秒是可选的。您可以根据偏移量不是整数小时时的实际情况进行选择。
我所说的从Java 9开始是什么意思呢?java.time、DateTimeFormatterBuilder
以及其appendOffset
方法在Java 8中都已经存在,但是只有从Java 9开始,该方法才能接受只包含一个H
的模式来表示一位数字的小时。
英文:
java.time, the modern Java date and time API that I think you are already using, is indeed the best library for the job. This works since Java 9:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("uuuuMMddHHmmss")
.appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true)
.appendLiteral('[')
.appendOffset("+Hmm", "+0")
.appendLiteral(':')
.appendZoneText(TextStyle.SHORT)
.appendLiteral(']')
.toFormatter(Locale.ENGLISH);
String s = "20200915095318.883[-4:EDT]";
OffsetDateTime odt = OffsetDateTime.parse(s, formatter);
ZonedDateTime zdt = ZonedDateTime.parse(s, formatter);
if (odt.getOffset().equals(zdt.getOffset())) {
System.out.println(odt);
System.out.println(zdt);
} else {
System.out.println("Something’s wrong here");
}
Output is:
> 2020-09-15T09:53:18.883-04:00
> 2020-09-15T09:53:18.883-04:00[America/New_York]
Parsing into an OffsetDateTime
uses the offset, -4
, while parsing into a ZonedDateTime
uses the time zone abbreviation, EDT
. I check that the two agree about the offset because else I would not know which of them to believe. In your example string they do agree.
I am passing +Hmm
as pattern to appendOffset()
. Other choices include +H
, +H:mm
, +Hmmss
and +H:mm:ss
. Lower case mm
and ss
mean that minutes and seconds of the offset are optional. You should choose based on how an offset would look like if it is not a whole number of hours.
What do I mean by since Java 9? java.time, DateTimeFormatterBuilder
and its appendOffset
method are all in Java 8, but only since Java 9 does that method accept a pattern with just one H
for one-digit hour in it.
答案2
得分: 1
你唯一的问题是字符串中的“-4”需要一个前导零,正如@deHaar在他的评论中所指出的,即
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss.SSS['['x':'z']']");
LocalDateTime ldt = LocalDateTime.parse("20200915095318.883[-04:EDT]", formatter);
英文:
Your only problem is that the -4
in your string needs a leading zero, as @deHaar indicated in his comment, i.e.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss.SSS'['x':'z']'");
LocalDateTime ldt = LocalDateTime.parse("20200915095318.883[-04:EDT]", formatter);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论