tl;博士
跳过格式化模式。默认使用标准ISO 8601 格式。
Instant.parse( "2015-06-27T13:16:37.363Z" )
ISO 8601
您的字符串格式由ISO 8601 标准正式定义。
基本上你的问题是这个问题的副本,Converting ISO 8601-compliant String to java.util.Date。
替代方案
The Answer by eugenioy 是正确的。
但是您应该知道,与 Java 捆绑在一起的旧 java.util.Date/.Calendar/java.text.SimpleDateFormat 类非常麻烦,应该避免使用。
过时的类
那些旧类现在已经过时了,首先是第三方 Joda-Time 库,现在是 Java 8 及更高版本中内置的新 java.time package (Tutorial)(受 Joda-Time 启发,由 @ 定义) 987654329@,由ThreeTen-Extra 项目扩展)。
在解析/生成日期时间值的字符串表示时,java.time 和 Joda-Time 都使用 ISO 8601 标准作为它们的默认值。所以代码很简单,不需要自定义格式化对象。 不需要所有导致异常的格式。
时区
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 项目现在处于维护模式,团队建议迁移到 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();
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。
从哪里获得 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可能会在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。