【问题标题】:ParseException trying to parse Date from string with + in itParseException 试图从带有 + 的字符串中解析日期
【发布时间】:2018-01-19 07:01:07
【问题描述】:

我无法从字符串中解析我的日期

这是我的约会

String startedFrom = "Fri,+31+Dec+3999+23:00:00+GMT"

DateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss z", Locale.ENGLISH);

Date result =  df.parse(startedFrom);

我做错了什么?

我得到异常

java.text.ParseException: Unparseable date: "Fri,+31+Dec+3999+23:00:00+GMT"

【问题讨论】:

标签: java date datetime-parsing unparseable


【解决方案1】:
DateFormat df = new SimpleDateFormat("EEE,'+'dd'+'MMM'+'yyyy'+'kk:mm:ss'+'z",
        Locale.ENGLISH);

但是,如果 startedFrom 值实际上是添加到 URL 的 URL 编码参数(如在带有 GET 方法的 HTML 表单中),那么 '+' 将作为空格 ' ' 到达,因此您的原始格式将是正确的.

【讨论】:

  • 使用 ' ' 分隔 dd mmm yyyy 。将 + 放在单引号内。 df = new SimpleDateFormat("E, '+'dd'+'MMM'+'yyyy'+'kk:mm:ss'+'z");您也可以将所有 + 替换为空格,然后将其传递给格式化程序
  • @Sweeper,是的,单引号特别适用于不应被解释为格式占位符的字母。谢谢,我不确定+。学到了一些东西。
【解决方案2】:

首先,请为此使用java.time 及其DateTimeFormatter 类。 SimpleDateFormat 是出了名的麻烦,并且与 Date 类一起已经过时了。 java.time 是现代 Java 日期和时间 API,使用起来更方便。

其次,Joop Eggen 在his answer 中是正确的,您的字符串看起来像一个 URL 编码参数,最初是 Fri, 31 Dec 3999 23:00:00 GMT。这听起来更有可能,因为这是一种称为 RFC 1123 的标准格式,通常与 HTTP 一起使用。因此,用于获取 URL 参数的库应该为您对字符串进行 URL 解码。然后很简单,因为已经为您定义了要使用的格式化程序:

    String startedFrom = "Fri, 31 Dec 3999 23:00:00 GMT";
    OffsetDateTime result 
            = OffsetDateTime.parse(startedFrom, DateTimeFormatter.RFC_1123_DATE_TIME);
    System.out.println(result);

打印出来

3999-12-31T23:00Z

如果您无法让您的库进行 URL 解码,请使用 URLDecoder 自行完成:

    String startedFrom = "Fri,+31+Dec+3999+23:00:00+GMT";
    try {
        startedFrom = URLDecoder.decode(startedFrom, StandardCharsets.UTF_16.name());
    } catch (UnsupportedEncodingException uee) {
        throw new AssertionError("UTF_16 is not supported — this should not be possible", uee);
    }

现在按上述方式进行。

您当然也可以定义一个格式化程序来解析带有加号的字符串。不过,我不知道您为什么要这样做。如果你这样做了,你只需要在格式模式字符串中也有它们:

    DateTimeFormatter formatterWithPluses
            = DateTimeFormatter.ofPattern("EEE,+d+MMM+yyyy+H:mm:ss+z", Locale.ROOT);
    ZonedDateTime result = ZonedDateTime.parse(startedFrom, formatterWithPluses);

这一次我们得到了一个ZonedDateTime,时区名称为GMT:

3999-12-31T23:00Z[GMT]

根据您需要的日期时间,您可以通过调用result.toOffsetDateTime()result.toInstant() 将其转换为OffsetDateTimeInstant

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多