2017-10-18 707 views
-2

我想用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$1.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) 
+1

这工作对我来说 – Jerry06

+0

在这里工作很好Java 1.8 – MadProgrammer

+0

我的不好,更新了问题,它是打印,不解析 – yegor256

回答

0

这是如何工作的:

String text = DateTimeFormatter.ISO_LOCAL_DATE 
    .withZone(ZoneId.of("UTC")) 
    .format(date.toInstant()); 
+2

而不是'ZoneId.of(“UTC”)',你也可以使用内置常量'ZoneOffset.UTC'。根据[javadoc](https://docs.oracle.com/javase/8/docs/api/java/time/ZoneId.html#of-java.lang.String-),它们是等效的:*“If区域ID等于'GMT','UTC'或'UT',那么结果是ZoneId具有相同的ID和等同于ZoneOffset.UTC的规则。* – 2017-10-18 10:51:28

1

这是因为Instant类表示时间轴上的一点:unix时代以来的纳秒数(1970-01-01T00:00Z),没有任何时区概念 - 因此它没有特定日期/时间(日/月/年,小时/分钟utes /秒),因为它可以代表不同时区的不同日期和时间。

设置格式化程序中的特定区域like you did可将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(); 

这回同样的事情your formatter。当然对于其他格式,您应该使用格式化程序,但专门用于ISO8601,则可以使用toString()方法。


你也可以转换Instant到你想要的时区(在这种情况下,UTC)并将其直接传递到格式:

String text = DateTimeFormatter.ISO_LOCAL_DATE.format(
    date.toInstant().atZone(ZoneOffset.UTC) 
); 

唯一的区别是,当你设置格式化程序中的区域,日期在格式化时转换为该区域(当您未设置时,日期不转换)。