Sure, here is the translation: Java DateTimeFormatter 解析带有特殊字符的日期时间

huangapple go评论70阅读模式
英文:

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。小写的mmss表示偏移量的分钟和秒是可选的。您可以根据偏移量不是整数小时时的实际情况进行选择。

我所说的从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);

huangapple
  • 本文由 发表于 2020年9月25日 20:59:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/64064664.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定