下面的代码返回一个这样的 OffsetDateTime
2021-06-30T23:59:59.009966667Z,添加了 2 个额外的零。我有 7 个
在格式化程序中,但它仍然返回 9 位数字。为什么?
即使是单个n 或任何数量小于或等于7 的ns,您也会得到相同的结果。但是,如果您超过7,您将收到类似的异常
Exception in thread "main" java.time.format.DateTimeParseException:
Text '2021-06-30 23:59:59.9966667 +00:00' could not be parsed at index 20
原因是DateTimeFormatter计算模式中n的个数,如果小于或等于.之后的位数,它将使用额外的n来补偿,但是如果ns 的数量超过了位数,它就不会知道额外的ns 是干什么用的。
不仅适用于n,而且适用于大多数(如果不是全部)符号。你可以从下面的例子中理解:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDate1 = "2020/2/2";
String strDate2 = "2020/02/02";
// Notice the single M and d
DateTimeFormatter dtfCorrectForBothDateStrings = DateTimeFormatter.ofPattern("uuuu/M/d", Locale.ENGLISH);
System.out.println(LocalDate.parse(strDate2, dtfCorrectForBothDateStrings));
System.out.println(LocalDate.parse(strDate1, dtfCorrectForBothDateStrings));
// Notice the two M's and d's
DateTimeFormatter dtfCorrectOnlyForSecondDateString = DateTimeFormatter.ofPattern("uuuu/MM/dd", Locale.ENGLISH);
System.out.println(LocalDate.parse(strDate2, dtfCorrectOnlyForSecondDateString));
System.out.println(LocalDate.parse(strDate1, dtfCorrectOnlyForSecondDateString));
}
}
输出:
2020-02-02
2020-02-02
2020-02-02
Exception in thread "main" java.time.format.DateTimeParseException: Text '2020/2/2' could not be parsed at index 5
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2051)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1953)
at java.base/java.time.LocalDate.parse(LocalDate.java:429)
at Main.main(Main.java:16)
为什么它给我.009966667而不是.9966667?
符号n 代表nano-of-second,9966667 纳秒等于0.009966667 秒。
public class Main {
public static void main(String[] args) {
int nanos = 9966667;
System.out.println(nanos + " nanoseconds = " + ((double) nanos / 1_000_000_000) + " second");
}
}
输出:
9966667 nanoseconds = 0.009966667 second
它如何与S 一起工作?
S 代表 fraction-of-second,.9966667 被解析为 0.9966667 秒。
关于OffsetDateTime#toString 实现的说明:
OffsetDateTime#toString 将 fraction-of-second 的数字分组为最接近 3 的倍数(即毫、微米和纳米),例如
- 对于
.99,输出将为.990,并且
- 对于
.996,输出将为.996,并且
- 对于
.9966,输出将为.996600,并且
- 对于
.9966667,输出将为.996666700。
下面是OffsetDateTime#toString的摘录:
输出将是以下 ISO-8601 格式之一:
- uuuu-MM-dd'T'HH:mmXXXXX
- uuuu-MM-dd'T'HH:mm:ssXXXXX
- uuuu-MM-dd'T'HH:mm:ss.SSSXXXXXX
- uuuu-MM-dd'T'HH:mm:ss.SSSSSSXXXXX
- uuuu-MM-dd'T'HH:mm:ss.SSSSSSSSSXXXXX
最终的演示(包含上面讨论的所有内容):
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "2021-06-30 23:59:59.9966667 +00:00";
System.out.println(OffsetDateTime.parse(strDateTime,
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.nnnnnnn XXX", Locale.ENGLISH)));
System.out.println(OffsetDateTime.parse(strDateTime,
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSS XXX", Locale.ENGLISH)));
}
}
输出:
2021-06-30T23:59:59.009966667Z
2021-06-30T23:59:59.996666700Z