Java 是时区指示符-“;";及;Z";ISO8601格式是否区分大小写?
我使用以下ISO8601格式:Java 是时区指示符-“;";及;Z";ISO8601格式是否区分大小写?,java,java-time,iso8601,datetimeformatter,offsetdatetime,Java,Java Time,Iso8601,Datetimeformatter,Offsetdatetime,我使用以下ISO8601格式: YYYY-MM-DDThh:mm:ssZ 我使用了OffsetDateTime.parse()来解析这种格式。我可以通过在这里传递t(而不是t)和z(而不是z)来解析日期时间 那么,有人能告诉我们,它是在ISO8601中被允许的,还是仅仅在解析逻辑中被遗漏了 那么,有人能告诉我们,在ISO8601中,它是被允许的,还是仅仅在解析逻辑中被遗漏了 我认为生成它们是无效的,尽管我认为解析器允许这样做是好的(尽管不是很好) 我可以访问的规范性EBNF(8601-1 DI
YYYY-MM-DDThh:mm:ssZ
我使用了OffsetDateTime.parse()
来解析这种格式。我可以通过在这里传递t
(而不是t
)和z
(而不是z
)来解析日期时间
那么,有人能告诉我们,它是在ISO8601中被允许的,还是仅仅在解析逻辑中被遗漏了
那么,有人能告诉我们,在ISO8601中,它是被允许的,还是仅仅在解析逻辑中被遗漏了
我认为生成它们是无效的,尽管我认为解析器允许这样做是好的(尽管不是很好)
我可以访问的规范性EBNF(8601-1 DIS附录A)对所有指示符仅使用大写拉丁字母,无论它们是Z、T、W、R、p、Y、M、D、H、M或S,并且与(非A)BNF不同,据我所知,EBNF终端区分大小写。Z
与Z
不同。
DateTimeFormatter
将前者计算为区域偏移量,将后者计算为时区名称
另一个示例可以是M
,它用于一年中的月份,以及M
,它用于小时分钟
日期、时间、时区等组成部分的符号区分大小写。检查以了解有关这些符号的更多信息
快速演示:
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
ZonedDateTime odt = ZonedDateTime.now(ZoneId.of("Asia/Calcutta"));
System.out.println(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssZ").format(odt));
System.out.println(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssz").format(odt));
}
}
2020-12-22T00:14:44+0530
2020-12-22T00:14:44IST
2020-12-22T00:30:40+0530
Exception in thread "main" java.time.DateTimeException: Unable to extract ZoneId from temporal 2020-12-22T00:30:40.865087+05:30
at java.base/java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:289)
at java.base/java.time.format.DateTimeFormatterBuilder$ZoneTextPrinterParser.format(DateTimeFormatterBuilder.java:4072)
at java.base/java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2341)
at java.base/java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1843)
at java.base/java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1817)
at Main.main(Main.java:9)
2020-12-22T00:45:50+05:30
2020-12-22T00:45:50+05:30
输出:
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
ZonedDateTime odt = ZonedDateTime.now(ZoneId.of("Asia/Calcutta"));
System.out.println(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssZ").format(odt));
System.out.println(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssz").format(odt));
}
}
2020-12-22T00:14:44+0530
2020-12-22T00:14:44IST
2020-12-22T00:30:40+0530
Exception in thread "main" java.time.DateTimeException: Unable to extract ZoneId from temporal 2020-12-22T00:30:40.865087+05:30
at java.base/java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:289)
at java.base/java.time.format.DateTimeFormatterBuilder$ZoneTextPrinterParser.format(DateTimeFormatterBuilder.java:4072)
at java.base/java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2341)
at java.base/java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1843)
at java.base/java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1817)
at Main.main(Main.java:9)
2020-12-22T00:45:50+05:30
2020-12-22T00:45:50+05:30
区域偏移量与时区不同。时区的ID格式为,大陆/城市
,例如亚洲/加尔各答
,而时区偏移量以小时和分钟表示,表示一个地点的日期和时间与UTC
日期和时间的偏移量。因此,许多时区ID可以具有相同的区域偏移量。换言之,可以从时区ID导出区域偏移量,但反过来是不可能的。例如,在下面的演示中,OffsetDateTime
将能够从Asia/Calcutta
的时区ID确定区域偏移量,但尝试使用z
获取时区名称(如上例所示)将失败
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
OffsetDateTime odt = OffsetDateTime.now(ZoneId.of("Asia/Calcutta"));
System.out.println(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssZ").format(odt));
System.out.println(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssz").format(odt));
}
}
输出:
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
ZonedDateTime odt = ZonedDateTime.now(ZoneId.of("Asia/Calcutta"));
System.out.println(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssZ").format(odt));
System.out.println(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssz").format(odt));
}
}
2020-12-22T00:14:44+0530
2020-12-22T00:14:44IST
2020-12-22T00:30:40+0530
Exception in thread "main" java.time.DateTimeException: Unable to extract ZoneId from temporal 2020-12-22T00:30:40.865087+05:30
at java.base/java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:289)
at java.base/java.time.format.DateTimeFormatterBuilder$ZoneTextPrinterParser.format(DateTimeFormatterBuilder.java:4072)
at java.base/java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2341)
at java.base/java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1843)
at java.base/java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1817)
at Main.main(Main.java:9)
2020-12-22T00:45:50+05:30
2020-12-22T00:45:50+05:30
我使用“OffsetDateTime.parse()”(java)来解析这种格式。我
能够通过传递“t”(而不是“t”)和“z”来解析日期时间
(而不是“Z”)在这里
我已经解释了Z
和Z
。让我们关注T
和T
。如果仔细观察,您会发现我在T
周围使用了单引号,即'T'
,这使得它成为一个字符串文字,可以在日期时间字符串中使用。这意味着它可以是任何东西,例如't'
或'Foo'
或'Bar'
。只要DateTimeFormatter
中的文本与日期时间字符串中的文本在相同的情况下匹配,它就可以正常工作。我在下面的演示中展示了它:
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String strDateTime = "2020-12-22T00:45:50+05:30";
// The given string is already in the format which is use by OffsetDateTime for
// parsing without a DateTimeFormatter
OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
// Let's try to parse it using different types of DateTimeFormatter instances
System.out.println(OffsetDateTime.parse(strDateTime, DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssXXX")));
//The following line will fail as the literal does not match case-wise
//System.out.println(OffsetDateTime.parse(strDateTime, DateTimeFormatter.ofPattern("uuuu-MM-dd't'HH:mm:ssXXX")));
strDateTime = "2020-12-22t00:45:50+05:30";// Now, DateTimeFormatter with 't' will work successfully
System.out.println(OffsetDateTime.parse(strDateTime, DateTimeFormatter.ofPattern("uuuu-MM-dd't'HH:mm:ssXXX")));
}
}
输出:
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
ZonedDateTime odt = ZonedDateTime.now(ZoneId.of("Asia/Calcutta"));
System.out.println(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssZ").format(odt));
System.out.println(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssz").format(odt));
}
}
2020-12-22T00:14:44+0530
2020-12-22T00:14:44IST
2020-12-22T00:30:40+0530
Exception in thread "main" java.time.DateTimeException: Unable to extract ZoneId from temporal 2020-12-22T00:30:40.865087+05:30
at java.base/java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:289)
at java.base/java.time.format.DateTimeFormatterBuilder$ZoneTextPrinterParser.format(DateTimeFormatterBuilder.java:4072)
at java.base/java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2341)
at java.base/java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1843)
at java.base/java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1817)
at Main.main(Main.java:9)
2020-12-22T00:45:50+05:30
2020-12-22T00:45:50+05:30
从TL中了解有关现代日期时间API的更多信息;博士
虽然在这一点上我不知道ISO 8601,但有文档记载Java的one argOffsetDateTime.parse(CharSequence)
同时允许大写和小写t
和Z
跟踪文档
文件说:
字符串必须表示有效的日期和时间,并使用
DateTimeFormatter.ISO\u OFFSET\u DATE\u TIME
DateTimeFormatter.ISO\u OFFSET\u DATE\u TIME
的文档说明该格式包括:
ISO\u LOCAL\u DATE\u TIME
- 偏移量ID…解析不区分大小写
Z
和小写Z
进行偏移。ISO\u LOCAL\u DATE\u TIME
的文档说明了T
:
- 字母“T”。解析不区分大小写
T
和小写T
我们不应该相信Java告诉我们关于标准的真相。ISO 8601标准似乎是一个秘密,除非你花钱买一份(这是一种说服人们遵循标准IMHO的有趣方式)。维基百科上有一篇关于标准的好文章。它用大写字母表示,没有提到是否允许用小写字母表示
链接
- Java和Java.time文档