“t”和“z”区分大小写吗?

b09cbbtk  于 2021-07-03  发布在  Java
关注(0)|答案(3)|浏览(1060)

我使用以下iso8601格式:

YYYY-MM-DDThh:mm:ssZ

我曾经 OffsetDateTime.parse() 解析此格式。我可以通过传递来解析日期和时间 t (代替 T )以及 z (代替 Z )在这里。
那么,有谁能告诉它是在iso8601中被允许的,还是仅仅在解析逻辑中被遗漏了呢?

sycxhyv7

sycxhyv71#

z和z不一样。 DateTimeFormatter 前者作为时区偏移量计算,后者作为时区名称计算。

另一个例子是 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")));
    }
}

输出:

2020-12-22T00:45:50+05:30
2020-12-22T00:45:50+05:30

从trail:date-time了解有关现代日期时间api的更多信息。

ujv3wf0j

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_TIME DateTimeFormatter.ISO_LOCAL_DATE_TIME 维基百科文章:iso 8601

gtlvzcf8

gtlvzcf83#

那么,有谁能告诉它是在iso8601中被允许的,还是仅仅在解析逻辑中被遗漏了呢?
我不认为生成它们是有效的,尽管我猜解析器允许这样做是好的(尽管不是很好)。
我可以访问的规范性ebnf(8601-1 dis附录a)对所有指示符仅使用大写拉丁字母,无论它们是z、t、w、r、p、y、m、d、h、m还是s,并且与(非a)bnf不同,据我所知,ebnf终端区分大小写。

相关问题