如何使用 DateTimeFormatter.ISO_LOCAL_DATE 打印日期?
How to print a date using DateTimeFormatter.ISO_LOCAL_DATE?
我想使用 DateTimeFormatter.ISO_LOCAL_DATE
来打印和解析日期。这就是我正在做的打印工作:
Date date;
String text = DateTimeFormatter.ISO_LOCAL_DATE.format(
date.toInstant()
);
这就是我得到的:
java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: Year
at java.time.Instant.getLong(Instant.java:603)
at java.time.format.DateTimePrintContext.getLong(DateTimePrintContext.java:205)
at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298)
at java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(DateTimeFormatterBuilder.java:2543)
at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2182)
at java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1744)
at java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1718)
这是它的工作原理:
String text = DateTimeFormatter.ISO_LOCAL_DATE
.withZone(ZoneId.of("UTC"))
.format(date.toInstant());
发生这种情况是因为 Instant
class 代表时间轴中的一个点:自 unix 纪元 (1970-01-01T00:00Z
) 以来的纳秒数,没有任何时区概念 - 所以它不没有特定的 date/time(day/month/year、hours/minutes/seconds),因为它可以代表不同时区的不同日期和时间。
在格式化程序中设置特定区域,,将 Instant
转换为该区域(因此自纪元以来的纳秒数可以转换为特定日期和时间),使其成为可以格式化。
对于这种特定情况,您只需要 ISO8601 format 中的日期部分(日、月和年),因此一种替代方法是将 Instant
转换为 LocalDate
并且调用 toString()
方法。当您在格式化程序中设置 UTC 时,我使用相同的格式来转换它:
String text = date.toInstant()
// convert to UTC
.atZone(ZoneOffset.UTC)
// get the date part
.toLocalDate()
// toString() returns the date in ISO8601 format
.toString();
这 return 与 相同。当然对于其他格式,你应该使用格式化程序,但具体对于 ISO8601,你可以使用 toString()
方法。
您还可以将 Instant
转换为您想要的时区(在本例中为 UTC)并将其直接传递给格式化程序:
String text = DateTimeFormatter.ISO_LOCAL_DATE.format(
date.toInstant().atZone(ZoneOffset.UTC)
);
唯一的区别是,当您在格式化程序中设置区域时,格式化时会将日期转换为该区域(当您不设置时,日期不转换)。
我想使用 DateTimeFormatter.ISO_LOCAL_DATE
来打印和解析日期。这就是我正在做的打印工作:
Date date;
String text = DateTimeFormatter.ISO_LOCAL_DATE.format(
date.toInstant()
);
这就是我得到的:
java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: Year
at java.time.Instant.getLong(Instant.java:603)
at java.time.format.DateTimePrintContext.getLong(DateTimePrintContext.java:205)
at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298)
at java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(DateTimeFormatterBuilder.java:2543)
at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2182)
at java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1744)
at java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1718)
这是它的工作原理:
String text = DateTimeFormatter.ISO_LOCAL_DATE
.withZone(ZoneId.of("UTC"))
.format(date.toInstant());
发生这种情况是因为 Instant
class 代表时间轴中的一个点:自 unix 纪元 (1970-01-01T00:00Z
) 以来的纳秒数,没有任何时区概念 - 所以它不没有特定的 date/time(day/month/year、hours/minutes/seconds),因为它可以代表不同时区的不同日期和时间。
在格式化程序中设置特定区域,Instant
转换为该区域(因此自纪元以来的纳秒数可以转换为特定日期和时间),使其成为可以格式化。
对于这种特定情况,您只需要 ISO8601 format 中的日期部分(日、月和年),因此一种替代方法是将 Instant
转换为 LocalDate
并且调用 toString()
方法。当您在格式化程序中设置 UTC 时,我使用相同的格式来转换它:
String text = date.toInstant()
// convert to UTC
.atZone(ZoneOffset.UTC)
// get the date part
.toLocalDate()
// toString() returns the date in ISO8601 format
.toString();
这 return 与 toString()
方法。
您还可以将 Instant
转换为您想要的时区(在本例中为 UTC)并将其直接传递给格式化程序:
String text = DateTimeFormatter.ISO_LOCAL_DATE.format(
date.toInstant().atZone(ZoneOffset.UTC)
);
唯一的区别是,当您在格式化程序中设置区域时,格式化时会将日期转换为该区域(当您不设置时,日期不转换)。