为什么Instant.now()有时格式不同?

时间:2018-05-25 19:52:10

标签: java java-8 java-time java-date

我的代码如下:

String PROPER_DATE_FORMAT = "yyyy-MM-dd";
String format = "yyyy-MM-dd'T'HH:mm:ss.SSSX";

SimpleDateFormat sdf = new SimpleDateFormat(format);
Date d = sdf.parse(Instant.now().toString());
SimpleDateFormat properFormat = new SimpleDateFormat(PROPER_DATE_FORMAT);
String formatterDate = properFormat.format(d);

现在,大多数情况下,这段代码可以正常工作,但偶尔会有Instant.now()返回2018-05-25T18:56:09Z,然后它会抛出一个格式不匹配的异常。

为什么它有时会不一致?

例外是java.lang.RuntimeException: java.text.ParseException: Unparseable date: "2018-05-25T18:56:09Z"

通常,当Instant.now().toString()确实返回具有上述格式的String时。同样,这段代码大部分时间都可以工作,但有几次没有,我很困惑为什么。

我想是否是因为最后有一个零但是没有显示但是我不相信因为我能够获得2018-05-25T20:06:58.900Z的值of Instant.now()。toString()

3 个答案:

答案 0 :(得分:4)

您的代码失败,因为Instant.toString()被记录为

  

使用的格式与DateTimeFormatter.ISO_INSTANT相同。

根据DateTimeFormatter.html#ISO_INSTANT

  

纳秒级根据需要输出零,三,六或九位数字

所以你有千分之一的机会获得一个即时毫秒000并且你的代码失败的瞬间。

无论如何,您的代码不必要复杂,可以替换为

String formattedDate = DateTimeFormatter.ofPattern("yyyy-MM-dd")
    .withZone(ZoneId.systemDefault())
    .format(Instant.now());

无需将Instant转换为字符串,只需将其解析为日期,然后再将其转换为字符串。

答案 1 :(得分:3)

当纳秒为零时,它不包含在格式化字符串中。因此输出格式为“yyyy-MM-dd'T'HH:mm:ssX”

你可以看到与以下区别:

public static void main(String[] args) throws ParseException {
        final Instant now = Instant.now();
        System.out.println("Now:\t" +  now);

        final Instant zeroedNow = now.with(ChronoField.NANO_OF_SECOND, 0);
        System.out.println("Zeroed:\t" + zeroedNow);
} 

输出看起来像

Now:    2018-05-25T20:23:54.208Z
Zeroed: 2018-05-25T20:23:54Z

答案 2 :(得分:1)

要回答您的问题:" Instant.now()有时格式不同?"。让我们看看如何实现Instance.now()。toString():

Instant.now()。toString()来源

public String toString() {
    return DateTimeFormatter.ISO_INSTANT.format(this);
}

的Javadoc
  

DateTimeFormatter.ISO_INSTANT

https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_INSTANT

 When formatting, the second-of-minute is always output.
 The nano-of-second outputs zero, three, six or nine digits digits as necessary.

从这个javadoc,我们知道Instance.now.toString()并不总是24长

如果毫秒是000 - >它将生成您所拥有的格式:

  

2018-05-25T18:56:09Z - 20长度

不是

  

2018-05-25T18:56:09.000Z - 24长度

一切都清楚了吗?