在Java中解析ISO 8601日期格式,如2015-06-27T13:16:37.363Z [复制]

问题描述 投票:7回答:2

这个问题在这里已有答案:

我试图用String解析SimpleDateFormat

这是我目前的代码:

public String getCreatedDateTime() {
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-ddEHH:mm:ss.zzzz");
    try {
        Date date = simpleDateFormat.parse("2015-06-27T13:16:37.363Z");
        return date.toString();
    } catch (ParseException e) {
        return "Error parsing date";
    }
}

如您所见,我只是在parse()方法中放置一个常量用于测试目的。

所以,这就是我要解析的内容:

2015-06-27t 13:16:37.attaz

这是我使用的SimpleDateFormat模式:

YYYY-MM-ddEHH:MM:ss.zzzz

我一直得到ParseException。

我知道这可能是因为最后的.zzzz,但我不知道.363Z可能代表什么,所以我只是用了一些随机字母。馊主意。

我会非常感谢你的帮助。谢谢!

java date simpledateformat iso8601
2个回答
8
投票

试试这种模式(注意末尾的X和中间的'T'):

"yyyy-MM-dd'T'HH:mm:ss.SSSX"

来自Java的SimpleDateFormat's documentation

ISO 8601时区:

...

对于解析,“Z”被解析为UTC时区指示符。

并且,从描述不同角色的部分:

X - 时区 - ISO 8601时区

编辑

如果使用Android,则不支持“X”。

您可以使用此模式(注意Z现在是文字):

"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"

但是,您将获得当前时区的日期,并在需要时将其转换为UTC。


9
投票

tl;dr

跳过格式化模式。默认使用标准ISO 8601格式。

Instant.parse( "2015-06-27T13:16:37.363Z" )

ISO 8601

您的字符串格式由ISO 8601标准正式定义。

基本上你的问题是这个问题的重复,Converting ISO 8601-compliant String to java.util.Date

Alternatives

The Answereugenioy是正确的。

但是你应该知道与Java捆绑在一起的旧的java.util.Date/.Calendar/java.text.SimpleDateFormat类是非常麻烦的,应该避免。

Outmoded Classes

那些旧的类现在已经过时了,首先是第三方Joda-Time库,现在由新的java.time packageTutorial)构建到Java 8及更高版本中(受Jaz-Time启发,由JSR 310定义,由ThreeTen-Extra项目扩展)。

在解析/生成日期时间值的字符串表示时,java.time和Joda-Time都使用ISO 8601标准作为其默认值。因此代码很简单,不需要自定义格式化程序对象。不需要那些导致你的例外的格式错误。

Time Zone

java.time和Joda-Time都有一个分区日期时间类,它可以理解分配的时区(与java.util.Date不同)。如果未指定一个,则分配JVM的当前默认时区。

请注意JVM的当前默认时区可以随时更改。它可以在部署时更改,默认为主机操作系统设置。当JVM中任何应用程序的任何线程中的任何代码调用TimeZone.setDefault时,它可以在运行时期间随时更改。因此,最好明确指定期望/预期的时区。

java.time

你的字符串末尾的Z是Zulu的缩写,意思是UTC。 Instant类可以直接解析该格式,以UTC为单位表示时间轴上的时刻,分辨率为纳秒。

String input = "2015-06-27T13:16:37.363Z";
Instant instant = Instant.parse( input );

将时区从UTC更改为某个所需/预期时区。

ZoneID zone = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdtMontréal = instant.atZone( zone ) ;

如果您确实需要java.util.Date来实现互操作性,请转换。

java.util.Date utilDate = Date.from( zdtMontréal.toInstant() ) ;

Joda-Time

Joda-Time项目现在处于维护模式,团队建议迁移到java.time类:

请注意,从Java SE 8开始,用户被要求迁移到java.time(JSR-310) - 这是JDK的核心部分,它取代了这个项目。

使用Joda-Time 2.8.1的示例代码。

String input = "2015-06-27T13:16:37.363Z" ;
DateTimeZone zone = DateTimeZone.UTC ;  //  Or: DateTimeZone.forID( "America/Montreal" ) ;
DateTime dateTime = new DateTime( input, zone ) ;

如果您确实需要java.util.Date来实现互操作性,请转换。

java.util.Date date = dateTime.toDate();
© www.soinside.com 2019 - 2024. All rights reserved.