另一个例子是 M 它用于一年中的一个月 m 它用它来表示每分钟。 日期、时间、时区等组成部分的符号区分大小写。检查 DateTimeFormatter 了解这些符号的更多信息。 快速演示:
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
区域偏移量与时区不同。时区在窗体中有一个id, Continent/City 例如 Asia/Calcutta 而区域偏移量是以小时和分钟表示的,它表示一个地方的日期和时间偏移了多少小时和分钟 UTC 日期和时间。因此,许多时区id可以具有相同的区域偏移量。换言之,可以从时区id导出区域偏移量,但反过来是不可能的,例如在下面的演示中, OffsetDateTime 将能够从的时区id确定区域偏移 Asia/Calcutta 但是尝试使用 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));
}
}
输出:
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)
我使用“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")));
}
}
3条答案
按热度按时间sycxhyv71#
z和z不一样。
DateTimeFormatter
前者作为时区偏移量计算,后者作为时区名称计算。另一个例子是
M
它用于一年中的一个月m
它用它来表示每分钟。日期、时间、时区等组成部分的符号区分大小写。检查
DateTimeFormatter
了解这些符号的更多信息。快速演示:
输出:
区域偏移量与时区不同。时区在窗体中有一个id,
Continent/City
例如Asia/Calcutta
而区域偏移量是以小时和分钟表示的,它表示一个地方的日期和时间偏移了多少小时和分钟UTC
日期和时间。因此,许多时区id可以具有相同的区域偏移量。换言之,可以从时区id导出区域偏移量,但反过来是不可能的,例如在下面的演示中,OffsetDateTime
将能够从的时区id确定区域偏移Asia/Calcutta
但是尝试使用z
会失败的。输出:
我使用“offsetdatetime.parse()”(在java中)来解析这种格式。我可以通过在这里传递“t”(而不是“t”)和“z”(而不是“z”)来解析日期时间。
我已经解释过了
Z
以及z
. 让我们关注T
以及t
. 如果你仔细观察,你会发现我到处都用单引号T
即'T'
这使得它成为在日期时间字符串中使用的字符串文本。这意味着它可以是任何东西。't'
或者'Foo'
或者'Bar'
. 只要DateTimeFormatter
与日期时间字符串中的大小写匹配,它的工作没有任何问题。我在下面的演示中展示了它:输出:
从trail:date-time了解有关现代日期时间api的更多信息。
ujv3wf0j2#
热释光;博士
虽然在这一点上我不知道ISO8601,但是有文档记载java的一个参数
OffsetDateTime.parse(CharSequence)
允许大写和小写T
以及Z
.追踪文件
文件上说:
字符串必须表示有效的日期和时间,并使用
DateTimeFormatter.ISO_OFFSET_DATE_TIME
.文件
DateTimeFormatter.ISO_OFFSET_DATE_TIME
表示格式包括:这个
ISO_LOCAL_DATE_TIME
偏移量id…解析不区分大小写。最后一句允许大写
Z
大小写z
用于偏移。文件ISO_LOCAL_DATE_TIME
说的是T
:字母“t”。解析不区分大小写。
所以这允许大写
T
大小写t
.我们不应该相信java告诉我们标准的真相。似乎iso8601标准是一个秘密,除非你花钱买一个拷贝(一个有趣的方法来说服人们遵循一个标准imho)。维基百科上有一篇关于标准的文章。它给出了大写字母,没有提到是否允许小写字母。
链接
java和java.time文档
OffsetDateTime.parse(CharSequence)
DateTimeFormatter.ISO_OFFSET_DATE_TIMEDateTimeFormatter.ISO_LOCAL_DATE_TIME
维基百科文章:iso 8601gtlvzcf83#
那么,有谁能告诉它是在iso8601中被允许的,还是仅仅在解析逻辑中被遗漏了呢?
我不认为生成它们是有效的,尽管我猜解析器允许这样做是好的(尽管不是很好)。
我可以访问的规范性ebnf(8601-1 dis附录a)对所有指示符仅使用大写拉丁字母,无论它们是z、t、w、r、p、y、m、d、h、m还是s,并且与(非a)bnf不同,据我所知,ebnf终端区分大小写。