如何将2013-03-13T20:59:31+0000日期字符串解析为日期格式

33
如何将这种格式的日期字符串2013-03-13T20:59:31+0000解析为Date对象?
我尝试了以下方式,但没有成功。
DateFormat df = new SimpleDateFormat("YYYY-MM-DDThh:mm:ssTZD");
Date result =  df.parse(time);
                    

我从第一行得到了以下异常信息:

java.lang.IllegalArgumentException: 非法的模式字符'T'


1
对于这个问题的新读者,我建议不要使用DateFormatSimpleDateFormatDate。这些类非常麻烦且过时。相反,使用来自java.time,现代Java日期和时间APIOffsetDateTimeDateTimeFormatter。请参见Arvind Kumar Avinash的好答案 - Ole V.V.
7个回答

57

尝试:

DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

请查看 http://developer.android.com/reference/java/text/SimpleDateFormat.html

具体而言:

                 yyyy-MM-dd 1969-12-31
                 yyyy-MM-dd 1970-01-01
           yyyy-MM-dd HH:mm 1969-12-31 16:00
           yyyy-MM-dd HH:mm 1970-01-01 00:00
          yyyy-MM-dd HH:mmZ 1969-12-31 16:00-0800
          yyyy-MM-dd HH:mmZ 1970-01-01 00:00+0000
   yyyy-MM-dd HH:mm:ss.SSSZ 1969-12-31 16:00:00.000-0800
   yyyy-MM-dd HH:mm:ss.SSSZ 1970-01-01 00:00:00.000+0000
 yyyy-MM-dd'T'HH:mm:ss.SSSZ 1969-12-31T16:00:00.000-0800
 yyyy-MM-dd'T'HH:mm:ss.SSSZ 1970-01-01T00:00:00.000+0000

1
尝试使用DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); - Nermeen
7
“2020-03-30T07:37:02.282+01:00”是一个时间戳,表示在格林威治标准时间上午7点37分02.282秒的基础上加1小时。 - Ankita Singh
@user3475052 yyyy-MM-dd'T'hh:mm:ss.SSSZ - Ahmad Shahwaiz

47

DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZ");

年份用小写字母y。 输入中与日期无关的任何字符(例如2013-03-13T20:59:31+0000中的“T”)应在''中引用。

有关已定义的模式字母列表,请参见文档

解析检查给定日期是否符合指定格式。要在检查后以特定格式打印日期,请参见下文:

DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZ");
Date result;
try {
    result = df.parse("2013-03-13T20:59:31+0000");
    System.out.println("date:"+result); //prints date in current locale
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
    System.out.println(sdf.format(result)); //prints date in the format sdf
}

@HarisDautović 你是否使用了正确的单引号来包围 T?这是 Alt+39,而不是其他撇号,如 `。 - msam
1
Date.toString() 使用本地时区,println 使用 toString(),因此您会得到本地时区。 - msam
@msam,在你的回答中提到了“输入中与日期无关的任何字符都应该用 '' 引起来”。但是在你最初的例子中,Z 没有被“''”包围,这样可以吗?我只是添加了 'Z',现在一切都正常了。 - Mike
@MikeB。Z是日期的一部分 - 它是+0000格式的时区。'Z'表示要解析的字符串具有“Z”字符。 - msam
@MikeB. 你确定被解析的字符串符合指定的格式吗?DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ", Locale.ENGLISH); LocalDateTime ldt = LocalDateTime.parse("2013-03-13T20:59:31+0000",formatter); 这段代码是正确的 - 将 Z 用 '' 包围会抛出异常。 - msam
显示剩余4条评论

8

java.time

java.util日期时间API及其格式化APISimpleDateFormat已过时且易出错。建议完全停止使用它们,改用现代日期时间API*

使用java.time现代日期时间API的解决方案:您的输入字符串带有时区偏移量,因此应将其解析为OffsetDateTime

演示:

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssxx", Locale.ENGLISH);
        OffsetDateTime odt = OffsetDateTime.parse("2013-03-13T20:59:31+0000", dtf);
        System.out.println(odt);
    }
}

输出:

2013-03-13T20:59:31Z

在线演示

输出中的Z是零时区偏移的时区指示器。它代表了Zulu并指定了Etc/UTC时区(该时区具有+00:00小时的时差)。

Trail: 日期时间中学习更多关于现代Date-Time API的内容。查看此回答此回答,了解如何使用JDBC与java.time API。

如果确实需要java.util.Date

您可以使用Date#from来获取java.util.Date的实例,如下所示:

Date date = Date.from(odt.toInstant());

* 如果您正在从事Android项目,而您的Android API级别仍不符合Java-8,请查看透过解糖可用的Java 8+ API。请注意,Android 8.0 Oreo已经提供了对java.time支持


1
关于这个经常被查看的问题得到一个当前(非过时)的答案,真是时候了!非常感谢! - Ole V.V.

4

对于这种日期格式2017-02-08 06:23:35 +0000,我使用以下格式:

SimpleDateFormat formatDate;
formatDate= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ZZZ");

我的情况下这个方法可行。其他答案对我没有用。


3

java.time

ZonedDateTime.parse("2020-05-08T11:12:13+0001", DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ"))

我正在使用现代Java日期和时间API——java.time中的ZonedDateTime类。 ZonedDateTime是带有时区的日期和时间。如果您要在Android Oreo(API级别26)之前使用java.time,则需要核心库去雕饰
我用单引号括起来将T,以便格式化程序知道它不是一个模式字母。问题中没有引号的T是您遇到异常的原因,但格式模式字符串中还存在其他问题。yyyy-MM-dd'T'HH:mm:ssZ可行。

4
欢迎来到SO。我们不鼓励仅包含代码的回答。最好能够描述这个回答如何解决与其他现有回答不同的8年前的问题。 - jwvh
你能否更详细地解释一下答案的细节,让它更有意义和清晰明了。 - Raksha Saini

3
请尝试以下方法:
SimpleDateFormat formatDate;
formatDate= new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

2

它也可以帮助

LocalDateTime dateTime = LocalDateTime.parse(time, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ"));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接