【问题标题】:Java SimpleDateFormat does not parse correctly (I am using the correct uppercase/lowercase letters..)Java SimpleDateFormat 无法正确解析(我使用的是正确的大写/小写字母..)
【发布时间】:2017-11-23 10:54:36
【问题描述】:

我知道这个问题已经被问过好几次了,我冒着被否决/重复关闭的风险,但是这里发布的大多数问题都是通过将 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

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

【问题讨论】:

  • 月份中的某天用小写的d表示
  • 使用 dd 代替 DD
  • 搜索“How to use SimpleDateFormat Java"”会有所帮助。
  • 我更新了问题
  • SSS 是毫秒。您正在尝试解析微秒。您可以改用 java.time.* 吗?

标签: java parsing time simpledateformat


【解决方案1】:

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

SimpleDateFormat 格式字符串中的S 始终表示毫秒 - 而不仅仅是您目前假设的“秒的分数”。

您的“新”块被解析为增加 79481 毫秒,而“旧”块有 608960。

这解释了结果,但没有为您提供前进的方向。这里有两种选择:

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

【讨论】:

  • @InDaPond:它是一个比 java.util.Date/Calendar 更简洁的 API...我强烈建议您尽可能使用它:)
【解决方案2】:

使用java.time 跟进Jon Skeet’s knowledgable answer 并不难。 JSON 块中的日期时间格式是 ISO 8601,这是用于交换日期和时间数据的标准格式,java.time 类将此格式解析为默认格式,也就是说,不需要显式格式:

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

如果您尝试打印生成的 dateTime,您将再次看到其默认格式 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]

【讨论】:

    【解决方案3】:

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

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

    这有望解决您的问题。

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

    谢谢

    【讨论】:

    • 这解决了错误月份的问题,但现在时间戳仍然不正确
    • InDaPond,编辑了上面的评论。请检查并验证。
    • JavaDoc 之外:H 表示一天中的小时(0-23),h 表示上午/下午的小时。所以大写H应该是正确的?
    • 不,OP 绝对想去hh。没有 am/pm 说明符。
    • 格式是 ISO 8601。它使用 24 小时制,所以大写 HH 是正确的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    • 1970-01-01
    • 2010-09-18
    • 1970-01-01
    相关资源
    最近更新 更多