将日期字符串解析为 java.util.Date 时出现非法模式字符“T" [英] Illegal pattern character 'T' when parsing a date string to java.util.Date

查看:32
本文介绍了将日期字符串解析为 java.util.Date 时出现非法模式字符“T"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个日期字符串,我想使用java Date API将其解析为正常日期,以下是我的代码:

public static void main(String[] args) {字符串日期="2010-10-02T12:23:23Z";字符串模式="yyyy-MM-ddThh:mm:ssZ";SimpleDateFormat sdf=new SimpleDateFormat(pattern);尝试 {日期 d=sdf.parse(date);System.out.println(d.getYear());} catch (ParseException e) {//TODO 自动生成的 catch 块e.printStackTrace();}}

但是我得到了一个异常:java.lang.IllegalArgumentException: Illegal pattern character 'T'

所以我想知道我是否必须拆分字符串并手动解析它?

顺便说一句,我试图在 T 的任一侧添加一个单引号字符:

String pattern="yyyy-MM-dd'T'hh:mm:ssZ";

它也不起作用.

解决方案

Java 8 及更高版本更新

您现在可以简单地执行 Instant.parse("2015-04-28T14:23:38.521Z") 并立即获得正确的结果,尤其是因为您应该使用 Instant 而不是使用最新版本的 Java 损坏的 java.util.Date.

您也应该使用 DateTimeFormatter 而不是 SimpleDateFormatter.

原答案:

<块引用>

下面的解释作为格式所代表的内容仍然有效.但它是在 Java 8 普及之前编写的,所以它使用了旧的如果您使用的是 Java 8 或更高.

这适用于带有尾随 Z 的输入,如下所示:

<块引用>

在模式中,T 被转义为 ' 两边.

最后的 Z 模式实际上是 XXX 文档在 SimpleDateFormat 的 JavaDoc 中,它不是很清楚实际上如何使用它,因为 Z 是旧的标记TimeZone 信息.

Q2597083.java

import java.text.SimpleDateFormat;导入 java.util.Calendar;导入 java.util.Date;导入 java.util.GregorianCalendar;导入 java.util.TimeZone;公开课 Q2597083{/*** 所有日期均已标准化为 UTC,由客户端代码转换为适当的时区.*/公共静态最终时区 UTC;/*** @see <a href="http://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations">组合日期和时间表示</a>*/public static final String ISO_8601_24H_FULL_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";/*** 0001-01-01T00:00:00.000Z*/公共静态最终日期BEGINNING_OF_TIME;/*** 292278994-08-17T07:12:55.807Z*/公共静态最终日期END_OF_TIME;静止的{UTC = TimeZone.getTimeZone("UTC");TimeZone.setDefault(UTC);最终日历 c = new GregorianCalendar(UTC);c.set(1, 0, 1, 0, 0, 0);c.set(Calendar.MILLISECOND, 0);BEGINNING_OF_TIME = c.getTime();c.setTime(新日期(Long.MAX_VALUE));END_OF_TIME = c.getTime();}public static void main(String[] args) 抛出异常{最终 SimpleDateFormat sdf = new SimpleDateFormat(ISO_8601_24H_FULL_FORMAT);sdf.setTimeZone(UTC);System.out.println("sdf.format(BEGINNING_OF_TIME) = " + sdf.format(BEGINNING_OF_TIME));System.out.println("sdf.format(END_OF_TIME) = " + sdf.format(END_OF_TIME));System.out.println("sdf.format(new Date()) = " + sdf.format(new Date()));System.out.println("sdf.parse("2015-04-28T14:23:38.521Z") = " + sdf.parse("2015-04-28T14:23:38.521Z"));System.out.println("sdf.parse("0001-01-01T00:00:00.000Z") = " + sdf.parse("0001-01-01T00:00:00.000Z"));System.out.println("sdf.parse("292278994-08-17T07:12:55.807Z") = " + sdf.parse("292278994-08-17T07:12:55.807Z"));}}

产生以下输出:

sdf.format(BEGINNING_OF_TIME) = 0001-01-01T00:00:00.000Zsdf.format(END_OF_TIME) = 292278994-08-17T07:12:55.807Zsdf.format(new Date()) = 2015-04-28T14:38:25.956Zsdf.parse("2015-04-28T14:23:38.521Z") = 2015 年 4 月 28 日星期二 14:23:38 UTCsdf.parse("0001-01-01T00:00:00.000Z") = 周六 1 月 1 日 00:00:00 UTC 1sdf.parse("292278994-08-17T07:12:55.807Z") = 8 月 17 日星期日 07:12:55 UTC 292278994

I have a date string and I want to parse it to normal date use the java Date API,the following is my code:

public static void main(String[] args) {
    String date="2010-10-02T12:23:23Z";
    String pattern="yyyy-MM-ddThh:mm:ssZ";
    SimpleDateFormat sdf=new SimpleDateFormat(pattern);
    try {
        Date d=sdf.parse(date);
        System.out.println(d.getYear());
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

However I got an exception: java.lang.IllegalArgumentException: Illegal pattern character 'T'

So I wonder if I have to split the string and parse it manually?

BTW, I have tried to add a single quote character on either side of the T:

String pattern="yyyy-MM-dd'T'hh:mm:ssZ";

It also does not work.

解决方案

Update for Java 8 and higher

You can now simply do Instant.parse("2015-04-28T14:23:38.521Z") and get the correct thing now, especially since you should be using Instant instead of the broken java.util.Date with the most recent versions of Java.

You should be using DateTimeFormatter instead of SimpleDateFormatter as well.

Original Answer:

The explanation below is still valid as as what the format represents. But it was written before Java 8 was ubiquitous so it uses the old classes that you should not be using if you are using Java 8 or higher.

This works with the input with the trailing Z as demonstrated:

In the pattern the T is escaped with ' on either side.

The pattern for the Z at the end is actually XXX as documented in the JavaDoc for SimpleDateFormat, it is just not very clear on actually how to use it since Z is the marker for the old TimeZone information as well.

Q2597083.java

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

public class Q2597083
{
    /**
     * All Dates are normalized to UTC, it is up the client code to convert to the appropriate TimeZone.
     */
    public static final TimeZone UTC;

    /**
     * @see <a href="http://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations">Combined Date and Time Representations</a>
     */
    public static final String ISO_8601_24H_FULL_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";

    /**
     * 0001-01-01T00:00:00.000Z
     */
    public static final Date BEGINNING_OF_TIME;

    /**
     * 292278994-08-17T07:12:55.807Z
     */
    public static final Date END_OF_TIME;

    static
    {
        UTC = TimeZone.getTimeZone("UTC");
        TimeZone.setDefault(UTC);
        final Calendar c = new GregorianCalendar(UTC);
        c.set(1, 0, 1, 0, 0, 0);
        c.set(Calendar.MILLISECOND, 0);
        BEGINNING_OF_TIME = c.getTime();
        c.setTime(new Date(Long.MAX_VALUE));
        END_OF_TIME = c.getTime();
    }

    public static void main(String[] args) throws Exception
    {

        final SimpleDateFormat sdf = new SimpleDateFormat(ISO_8601_24H_FULL_FORMAT);
        sdf.setTimeZone(UTC);
        System.out.println("sdf.format(BEGINNING_OF_TIME) = " + sdf.format(BEGINNING_OF_TIME));
        System.out.println("sdf.format(END_OF_TIME) = " + sdf.format(END_OF_TIME));
        System.out.println("sdf.format(new Date()) = " + sdf.format(new Date()));
        System.out.println("sdf.parse("2015-04-28T14:23:38.521Z") = " + sdf.parse("2015-04-28T14:23:38.521Z"));
        System.out.println("sdf.parse("0001-01-01T00:00:00.000Z") = " + sdf.parse("0001-01-01T00:00:00.000Z"));
        System.out.println("sdf.parse("292278994-08-17T07:12:55.807Z") = " + sdf.parse("292278994-08-17T07:12:55.807Z"));
    }
}

Produces the following output:

sdf.format(BEGINNING_OF_TIME) = 0001-01-01T00:00:00.000Z
sdf.format(END_OF_TIME) = 292278994-08-17T07:12:55.807Z
sdf.format(new Date()) = 2015-04-28T14:38:25.956Z
sdf.parse("2015-04-28T14:23:38.521Z") = Tue Apr 28 14:23:38 UTC 2015
sdf.parse("0001-01-01T00:00:00.000Z") = Sat Jan 01 00:00:00 UTC 1
sdf.parse("292278994-08-17T07:12:55.807Z") = Sun Aug 17 07:12:55 UTC 292278994

这篇关于将日期字符串解析为 java.util.Date 时出现非法模式字符“T"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆