【问题标题】:Parsing string to date: Illegal pattern character 'T'.解析字符串到日期:非法模式字符'T'。
【发布时间】:2014-12-11 11:32:39
【问题描述】:

我需要在 java 中解析一个字符串到日期。我的字符串格式如下:

2014-09-17T12:00:44.0000000Z

但是 java 在尝试解析这种格式时会抛出以下异常...java.lang.IllegalArgumentException: Illegal pattern character 'T'

关于如何解析它的任何想法?

谢谢!

【问题讨论】:

  • current_date=formatter.parse(date)
  • 将格式化程序对象也添加到此处
  • 是的,当然,抱歉:SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-ddTHH:mm:ss.SSS");
  • 使用 'T' 而不是只使用 T

标签: java string date simpledateformat


【解决方案1】:

java.time

现在是现代答案的时候了:始终使用现代 Java 日期和时间 API java.time 来处理日期和时间工作。当被问到这个问题时,java.time 已经使用 Java 8 7 个月了。今天(2020 年)没有人应该使用 SimpleDateFormat 类,这似乎是问题中的麻烦。它出了名的麻烦和过时。

使用 java.time 我们不需要显式格式化程序:

    String str = "2014-09-17T12:00:44.0000000Z";
    Instant i = Instant.parse(str);
    System.out.println("As Instant: " + i);

输出是:

即时:2014-09-17T12:00:44Z

您的格式是 ISO 8601(链接在底部)。 java.time 的类通常将 ISO 8601 解析为其默认值,并从其toString 方法中打印回 ISO 8601。在 ISO 8601 中,秒的小数部分是可选的。

如果您需要 Date 对象用于尚未升级到 java.time 的旧版 API:

    Date oldfashionedDate = Date.from(i);
    System.out.println("As old-fashioned Date: " + oldfashionedDate);

在我的时区输出:

作为老式日期:2014 年 9 月 17 日星期三 14:00:44 CEST

输出会因时区而异,因为 Date.toString() 容易混淆地采用 JVM 的默认时区并将其用于呈现字符串。

你出了什么问题?

您没有向我们展示您的代码,但我们已经可以看出有几处是错误的:

  1. SimpleDateFormat 无法正确解析秒上有 7 个小数的字符串。它仅支持毫秒,精确到小数点后三位。
  2. 在您的格式模式字符串中,您需要通过将文字 T 括在单引号中来转义它,'T'SimpleDateFormat 会将其理解为模式字母,并且没有格式模式字母 T .这就是您的异常消息的含义。

链接

【讨论】:

    【解决方案2】:

    试试这个。

    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class DateClass {
        public static void main(String[] args) throws ParseException {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
            Date d = sdf.parse("2014-09-17T12:00:44.0000000Z");
            System.out.println(d); //output Wed Sep 17 12:00:44 IST 2014
        }
    }
    

    【讨论】:

      【解决方案3】:

      鉴于您输入的2014-09-17T12:00:44.0000000Z,仅转义字母T 是不够的。您还必须处理尾随的Z。但请注意,这个Z 不是文字,而是根据ISO-8601-standard 具有UTC+00:00 时区偏移量的含义。所以转义Z 是不正确的。

      SimpleDateFormat 通过模式符号 X 处理这个特殊字符 Z。所以最终的解决方案是这样的:

       SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSX");
       Date d = sdf.parse("2014-09-17T12:00:44.0000000Z");
       System.out.println(d); // output: Wed Sep 17 14:00:44 CEST 2014
      

      请注意,不同的时钟时间适用于时区CESTtoString() 使用系统时区),结果等价于UTC-time 12:00:44。此外,我必须插入七个符号 S 才能正确处理您的输入,该输入假装精度低至 100ns(尽管 Java pre 8 只能处理毫秒)。

      【讨论】:

      • 但有一条评论,您需要在构造函数 SimpleDateFormat 中将最后一个 X 字符替换为“Z”。很好的解决方案,对我有用
      • @VictorPonomarenko 符号字母 X 是在 Java 7 中引入的。对于 Java 6,如果解析的文字“Z”将被识别为 UTC+00,我不确定 Z 是否可以作为替换含义!也许最好使用 Java 6 的解决方法来转义 Z(仅将其解释为文字)并将SimpleDateFormat-object 上的区域设置为“GMT”。
      • 在 android 上我得到运行时异常,当离开 X 字符时,但在替换为 'Z' 后效果很好(android 现在可以在 java 7 上运行)
      • @VictorPonomarenko Z 似乎是Android 的正确符号,虽然文档不是很详细,但请记住:Android != Java(和SimpleDateFormat-API 确实不同在两个世界中)。
      【解决方案4】:

      您必须转义“T”字符:

          SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
          format.setTimeZone(TimeZone.getTimeZone("UTC"));
          Date parse = format.parse("2014-09-17T12:00:44.0000000Z");
      

      使用答案:What is this date format? 2011-08-12T20:17:46.384Z

      【讨论】:

      • 感谢您的回答,现在我没有得到同样的异常,但是这个:“java.text.ParseException: Unparseable date: "Date"”。我认为日期格式还没有很好的定义......
      猜你喜欢
      • 2011-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-21
      相关资源
      最近更新 更多