java - Java OffsetDateTime.parse() 为时间添加额外的零
问题描述
以下代码返回一个 OffsetDateTime,如 2021-06-30T23:59:59.009966667Z,添加了 2 个额外的零。我在格式化程序中有 7 个 n,但它仍然返回 9 个数字。为什么?
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
public class HelloWorld{
public static void main(String []args){
DateTimeFormatter MAIN_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.nnnnnnn XXX");
String dbData = "2021-06-30 23:59:59.9966667 +00:00";
OffsetDateTime time = OffsetDateTime.parse(dbData, MAIN_FORMATTER);
System.out.println(time.toString());
}
}
解决方案
以下代码返回一个 OffsetDateTime,如 2021-06-30T23:59:59.009966667Z,添加了 2 个额外的零。我在格式化程序中有 7 个 n,但它仍然返回 9 个数字。为什么?
即使对于小于或等于的单个n
或任意数量的s,您也会得到相同的结果。但是,如果您超过,您将收到类似的异常n
7
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
来补偿,但如果n
s 的数量超过位数,则不会有任何线索额外n
的 s 是什么。
它不仅适用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
代表纳秒,纳秒等于秒。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
代表秒的分数,并被.9966667
解析为0.9966667
秒。
实施说明OffsetDateTime#toString
:
以最接近的倍数(即毫、微米和纳米)对秒OffsetDateTime#toString
的小数位数进行分组,例如3
- 对于
.99
,输出将是.990
,并且 - 对于
.996
,输出将是.996
,并且 - 对于
.9966
,输出将是.996600
,并且 - 对于
.9966667
,输出将是.996666700
。
以下是摘录自OffsetDateTime#toString
:
输出将是以下 ISO-8601 格式之一:
- uuuu-MM-dd'T'HH:mmXXXXXX
- uuuu-MM-dd'T'HH:mm:ssXXXXX
- uuuu-MM-dd'T'HH:mm:ss.SSSXXXXXX
- uuuu-MM-dd'T'HH:mm:ss.SSSSSSXXXXXX
- 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
推荐阅读
- postgresql - 是否有系统程序或方法来找出事务日志已满问题?
- html - CSS html段落在悬停时移动
- apache-spark - 在 Pyspark 上将一列拆分为更多列时遇到问题
- flutter - 如何在 Flutter 中启动视图时禁用屏幕键盘?
- android - bitmap.sameAs() 不适用于 Intent Picking 的图像比较
- python - Matplotlib 图不显示图例
- css - Wordpress 菜单都是一种颜色。CSS似乎没有解决它
- javascript - 如何在html中的body和div元素之间没有空格
- python - 熊猫,按月排序并为每年创建新列
- decorator - 在 NestJS 中,如何在自定义方法装饰器中获取执行上下文或请求实例?