您的代码中存在三个主要问题:
- 您已经使用
.SSSSSS
了几分之一秒,而SimpleDateFormat
不支持超过毫秒 ( .SSS
) 的精度。这也意味着您需要将几分之一秒的数字限制为三个。
- 您已经习惯于
Z
解析时区偏移量,-05:00
而正确的模式是XXX
.
- 您已经使用
hh
了 24 小时格式的时间,而正确的模式是HH
. 该符号hh
用于 12 小时制(即上午/下午)格式的时间。
除此之外,我建议您始终使用Locale
日期解析/格式化 API,因为日期时间字符串的某些部分在不同Locale
的 s 中以不同的方式表示。
演示:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ENGLISH);
Date date = sdf.parse("2011-04-11T22:27:18.491-05:00");
// Print the default string i.e. Date#toString
System.out.println(date);
// Print the date-time in a custom format
sdf.setTimeZone(TimeZone.getTimeZone("GMT-05:00"));
System.out.println(sdf.format(date));
}
}
输出:
Tue Apr 12 04:27:18 BST 2011
2011-04-11T22:27:18.491-05:00
关于遗留日期时间 API 的一些事实:
- 该
java.util.Date
对象不是像现代日期时间类型那样的真实日期时间对象;相反,它表示自称为“纪元” January 1, 1970, 00:00:00 GMT
(或 UTC)的标准基准时间以来的毫秒数。当您打印 的对象时java.util.Date
,其toString
方法会返回 JVM 时区中的日期时间,根据此毫秒值计算得出。如果您需要在不同的时区打印日期时间,则需要将时区设置为SimpleDateFormat
并从中获取格式化字符串。
java.util
日期时间 API 及其格式化 API已SimpleDateFormat
过时且容易出错。建议完全停止使用它们并切换到现代日期时间 API *。
使用现代日期时间 API:
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
OffsetDateTime odt = OffsetDateTime.parse("2011-04-11T22:27:18.491726-05:00");
// Print the default string i.e. OffsetDateTime#toString
System.out.println(odt);
// Print the date-time in a custom format. Note: OffsetDateTime#toString drops
// seconds if it is zero
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSSSSXXX");
System.out.println(dtf.format(odt));
}
}
输出:
2011-04-11T22:27:18.491726-05:00
2011-04-11T22:27:18.491726-05:00
注意:对于DateTimeFormatter
,符号,u
表示年份,而符号,y
表示年代。在 [AD][2] 时代,这一年没有任何区别,但在 BC 时代,这一年很重要。检查此答案以了解更多信息。
从Trail: Date Time了解有关现代日期时间 API 的更多信息。
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,则可以使用ThreeTen-Backport,它将大部分java.time功能向后移植到 Java 6 和 7。如果您正在为 Android 项目和 Android API 工作level 仍然不符合 Java-8,请检查Java 8+ APIs available through desugaring和How to use ThreeTenABP in Android Project。