【问题标题】:Could not find the format for this date: "2018-09-09T09:04:47+00:00"找不到此日期的格式:“2018-09-09T09:04:47+00:00”
【发布时间】:2018-09-09 11:14:47
【问题描述】:

出错

java.text.ParseException: Unparseable date: "2018-09-09T09:04:47+00:00"

这是什么日期格式?

【问题讨论】:

  • ISO 时间与 UTC 时区?但要成为真正的 ISO,它应该以 Z 结尾
  • 如果他已经阅读了问题的问题,我找不到格式是什么,那么我只能编写格式化程序。
  • 是的@Antoniossss,但是这个值我是通过服务获得的,我需要解析它以转换为时间戳。
  • @drowny 好的。谢谢。
  • 服务使用自定义时间格式不是我的问题。

标签: date


【解决方案1】:

这个日期格式好像有些混乱,我来解释一下。

  1. 这是一个带有时区偏移的 ISO 8601 日期时间值。

    参考资料:

    • 维基百科中的ISO 8601 页面准确且非常全面。
    • W3 联盟已在 TR 中记录; here
    • 官方版本可从ISO获得; here
  2. Z 是 ISO 标准时区说明符。它与+00.00 含义相同,在某些圈子(例如军队)中称为“祖鲁时间”。

  3. ISO 8601 日期/时间不必“必须”以 Z 结尾。还有其他形式的时区规范,实际上日期/时间根本不需要时区。

  4. 您不需要将其从 Z 中删除。 Java 的数据时间解析器可以解析 Z 时区说明符并赋予其正确的含义……如果您使用正确的模式。

  5. 如果 ISO 日期时间“无法解析”,则意味着您(显式或隐式)使用了错误的格式来解析它。

  6. 不幸的是,不同的国家(地区)有不同的默认日期/时间格式,更糟糕的是,没有可靠的方法(通常)知道哪个是正确的......如果你不知道它来自哪里。

  7. 幸运的是……ISO 8601 是一个国际标准。如果您看到符合 ISO 8601 语法的日期/时间,您就会知道它的含义。

  8. W3 联盟TR 中解释了多种 ISO 8601 日期和日期/时间表示。可以毫不含糊地区分不同的种类。

  9. 如果您使用java.text.SimpleDateFormat 进行解析,则此ISO 8601 变体的正确模式是"yyyy-MM-dd'T'HH:mm:ssX"。与java.time.format.DateTimeFormatter 一起使用的模式也是"yyyy-MM-dd'T'HH:mm:ssX"

  10. DateTimeFormatter 类还将许多标准格式定义为常量。这种 ISO 8601 日期/时间的格式是DateTimeFormatter.ISO_OFFSET_DATE_TIME。其他种类也有定义。

  11. DateCalendar 类和关联的类是遗留类。建议在新代码中使用新的 java.time 类。

【讨论】:

    【解决方案2】:

    您应该使用“X”作为时区:

    String pattern = "yyyy-MM-dd'T'HH:mm:ssX";
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
    Date date = simpleDateFormat.parse("2018-09-09T09:04:47+00:00");
    System.out.println(date);
    

    【讨论】:

    • 谢谢@Rahim,这正是我想要的。完美运行。
    • 最好使用新的java.time.* 类而不是DateSimpleDateFormat
    【解决方案3】:

    使用此转换方法转换为String to date,即ISO format。但通常 ISO 格式以 Z 结尾,但如果不是没有问题。这个方法返回日期,然后从这个返回值中做任何你想做的事情。

    public static Date toCalendar( String isoDate)
                throws ParseException {
            String s = isoDate.replace("Z", "+00:00");
            try {
                s = s.substring(0, 22) + s.substring(23);  // to get rid of the ":"
            } catch (IndexOutOfBoundsException e) {
                throw new ParseException("Invalid length", 0);
            }
            return  new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(s);
    
        }
    

    Java8 TimeApi或以后的版本有这个用法,试试看;

    OffsetDateTime offsetDateTime = OffsetDateTime.parse( "2018-09-09T09:04:47+01:00" );
    Instant instant = offsetDateTime.toInstant();
    java.util.Date date = java.util.Date.from( instant );
    

    或者只使用这个模式yyyy-MM-dd'T'HH:mm:ssX

    【讨论】:

    • 谢谢,@drowny,但它不起作用。另外,我不能硬编码像“+00:00”这样的值,因为这些是我将从 API 接收到的动态值。
    • 我添加了替代方法来解决,如果您使用的是 java8 或更高版本,请尝试一下。您的字符串将在“+00:00”或其他字符串结尾处动态显示。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多