Java SimpleDateFormat 没有正确解析(我使用了正确的 uppercase/lowercase 字母..)

Java SimpleDateFormat does not parse correctly (I am using the correct uppercase/lowercase letters..)

我知道这个问题已经被问过好几次了,我冒着 downvote/duplicate 关闭的风险,但是这里发布的大部分问题都是通过将 YYYY 链接到 yyyy 来解决的。所以,搜索并没有真正帮助:/

这些是区块内给定的时间戳

date new Block: 2017-11-02T06:17:05.079481
date old Block: 2017-11-02T06:17:04.608960

我的转换码:

 public static Date getDate(JSONObject block){
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS");
    try {
       return sdf.parse(block.get("timestamp").toString());
    } catch (ParseException e) {
        e.printStackTrace();
        return new Date(0);
    }
}

这是解析的结果

date new block: Thu Nov 02 06:18:24 KST 2017 
date old block: Thu Nov 02 06:27:12 KST 2017

这怎么可能?如时间戳所示,新块是在旧块之后创建的。但现在情况正好相反

在您的简单日期格式中,您需要将 'DD' 更改为小写 'dd'

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS");

这有望解决您的问题。

编辑:小时也是如此。 ** 将 **'HH' 替换为 'hh'(小写)。

谢谢

How is that possible? The new block was created before the old block, as seen in the timestamp. but now it is the other way around

SSimpleDateFormat 格式字符串中始终表示毫秒 - 而不仅仅是 "fractions of a second",这是您目前假设的。

您的 "new" 块被解析为增加 79481 毫秒,而 "old" 块有 608960。

这解释了结果,但没有给你前进的方向。这里有两个选项:

  • 使用 java.time.* - 这是更现代的 API,具有纳秒精度而不是毫秒精度。
  • 删除输入的最后三个字符,并仅解析到毫秒精度。

跟进 ,使用 java.time 并不难。 JSON 块中的日期时间格式是 ISO 8601,这是日期和时间数据交换的标准格式,java.time 类 将此格式解析为默认格式,即,不需要明确的格式:

    String blockTimestamp = "2017-11-02T06:17:05.079481";
    LocalDateTime dateTime = LocalDateTime.parse(blockTimestamp);

如果您尝试打印生成的日期时间,您将再次看到它的默认格式 ISO 8601,因为这也是其 toString 方法生成的格式:2017-11-02T06:17:05.079481.

LocalDateTime 的潜在缺点是它不代表时间轴上的明确点。因此,如果您知道在哪个时区解释日期和时间,您可能希望将其转换为 ZonedDateTime,例如:

    ZoneId koreaTimeZone = ZoneId.of("Asia/Seoul");
    ZonedDateTime koreaDateTime = dateTime.atZone(koreaTimeZone);

这会产生 2017-11-02T06:17:05.079481+09:00[Asia/Seoul]