java.time
您不需要使用DateTimeFormatter
来解析给定的日期时间字符串。
Java SE 8 日期时间 API(java.time
API或现代日期时间 API)基于ISO 8601,只要日期时间字符串符合 ISO 8601 标准,就不需要显式地使用 DateTimeFormatter
对象。
字符串中的Z
是表示零时区偏移量的时区标识符。它代表Zulu,并指定了Etc/UTC
时区(其时区偏移量为+00:00
小时)。
字符串中的T
只是根据 ISO-8601 标准的日期时间分隔符。
演示:
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
String strDateTime = "2011-08-12T20:17:46.384Z";
Instant instant = Instant.parse(strDateTime);
OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
ZonedDateTime zdt = ZonedDateTime.parse(strDateTime);
System.out.println(instant);
System.out.println(odt);
System.out.println(zdt);
}
}
输出:
2011-08-12T20:17:46.384Z
2011-08-12T20:17:46.384Z
2011-08-12T20:17:46.384Z
了解更多关于
java.time
,
现代日期时间API*的信息,请参考
教程:日期时间。
传统日期时间API
传统的日期时间API(java.util
日期时间API及其格式化APISimpleDateFormat
)已经过时且容易出错。建议完全停止使用它们,并切换到现代日期时间API*。
为了完整起见,我写了一个使用传统API解析此日期时间字符串的解决方案。
在日期时间解析/格式化API中,不要在模式中使用'Z'
。
如上所述,
Z
(不带引号)是零时区偏移的时区标识符,而
'Z'
只是一个字符字面量,它没有任何含义。请使用格式
y-M-d'T'H:m:s.SSSXXX
。查看
文档以了解更多关于这些符号的信息。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
String strDateTime = "2011-08-12T20:17:46.384Z";
SimpleDateFormat sdf = new SimpleDateFormat("y-M-d'T'H:m:s.SSSXXX", Locale.ENGLISH);
Date date = sdf.parse(strDateTime);
}
}
请注意,
java.util.Date
对象并不是类似于
现代日期时间类型的真正日期时间对象;相反,它表示自"纪元"即
1970年1月1日 00:00:00 GMT
(或UTC)起的毫秒数。由于它不包含任何格式和时区信息,它应用了格式
EEE MMM dd HH:mm:ss z yyyy
和JVM的时区来返回基于这个毫秒值导出的
Date#toString
的值。如果您需要以不同的格式和时区打印日期时间,您需要使用带有所需格式和适用时区的
SimpleDateFormat
。
sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"))
String formatted = sdf.format(date)
System.out.println(formatted)
Joda 日期时间 API
下面是在 Joda-Time 主页上引用的通知:
请注意,从 Java SE 8 开始,建议用户迁移到 java.time(JSR-310)- 它是 JDK 的核心部分,取代了该项目。
为了完整起见,我已经编写了一个使用 Joda 日期时间 API 解析此日期时间字符串的解决方案。
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String dateTimeStr = "2011-08-12T20:17:46.384Z";
DateTimeFormatter dtf = DateTimeFormat.forPattern("y-M-d'T'H:m:s.SSSZ").withOffsetParsed();
DateTime dateTime = dtf.parseDateTime(dateTimeStr);
System.out.println(dateTime);
}
}
输出:
2011-08-12T20:17:46.384Z
* 如果由于任何原因,您必须坚持使用Java 6或Java 7,您可以使用
ThreeTen-Backport将大部分
java.time功能回溯到Java 6和7。如果您正在进行一个Android项目,并且您的Android API级别仍不符合Java-8,请查看
通过desugaring可用的Java 8+ API和
如何在Android项目中使用ThreeTenABP。
java.util.Date
、java.util.Calendar
和java.text.SimpleDateFormat
)现在已经不再使用,已被集成到Java 8和Java 9中的Java.time类所取代。请参阅Oracle的教程。 - Basil Bourque