如果程序给出的当前时间是 2016-06-01T11:33:54.000Z ,程序有误吗?
格式正确,符合 ISO 8601 标准,但不代表欧洲/伦敦时间。在 2016 年的伦敦,DST 从 3 月 27 日星期日凌晨 1:00 开始,到 10 月 30 日星期日凌晨 2:00 结束,因此,欧洲/伦敦在这段时间内的日期时间表示形式应具有小时数的时区偏移量。at 末尾指定时间,即 UTC 时间,因此具有小时时区偏移量。对于欧洲/伦敦,同一时刻可以表示为 。+01:00
Z
Zulu
+00:00
2016-06-01T12:33:54+01:00
java.time
日期时间 API 及其格式化 API 已过时且容易出错。建议完全停止使用它们,并切换到 现代日期时间 API* 。java.util
SimpleDateFormat
java.time
甚至Joda-Time也不应该再使用。请注意Joda-Time主页上的以下说明
Joda-Time是Java SE 8之前Java事实上的标准日期和时间库。现在要求用户迁移到 java.time (JSR-310)。
java.time
API基于日期时间字符串,可以解析为不需要日期时间解析/格式化类型。ISO 8601
2016-06-01T11:33:54.000Z
java.time.ZonedDateTime
java.time.OffsetDateTime
演示:
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
ZonedDateTime zdt = ZonedDateTime.parse("2016-06-01T11:33:54.000Z");
System.out.println(zdt);
ZoneId zoneId = ZoneId.of("Europe/London");
ZonedDateTime zdtInLondon = zdt.withZoneSameInstant(zoneId);
System.out.println(zdtInLondon);
}
}
输出:
2016-06-01T11:33:54Z
2016-06-01T12:33:54+01:00[Europe/London]
如何处理夏令时 (DST)?
如前所述,日期时间字符串也可以解析为不需要日期时间解析/格式化类型。但是,它被设计为处理固定的时区偏移量,而被设计为处理时区,因此它会自动处理DST。如果需要,您可以使用 ZonedDateTime# 将 a 转换为OffsetDateTime
。2016-06-01T11:33:54.000Z
java.time.OffsetDateTime
OffsetDateTime
ZonedDateTime
ZonedDateTime
OffsetDateTime
import java.time.ZonedDateTime;
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:ss.SSS z", Locale.ENGLISH);
String strDateTime = "2016-03-01T11:33:54.000 Europe/London";
ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, dtf);
System.out.println(zdt);
strDateTime = "2016-06-01T11:33:54.000 Europe/London";
zdt = ZonedDateTime.parse(strDateTime, dtf);
System.out.println(zdt);
}
}
输出:
2016-03-01T11:33:54Z[Europe/London]
2016-06-01T11:33:54+01:00[Europe/London]
请注意时区偏移量如何自动从 更改为 反映 DST 更改。另一方面Z
01:00
import java.time.OffsetDateTime;
public class Main {
public static void main(String[] args) {
String strDateTime = "2016-03-01T11:33:54.000+01:00";
OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
System.out.println(odt);
strDateTime = "2016-06-01T11:33:54.000+01:00";
odt = OffsetDateTime.parse(strDateTime);
System.out.println(odt);
}
}
输出:
2016-03-01T11:33:54+01:00
2016-06-01T11:33:54+01:00
在这种情况下,您不会谈论时区(例如欧洲/伦敦);相反,您谈论的是小时的固定时区偏移量。+01:00
从跟踪:日期时间中了解有关现代日期时间 API 的更多信息。
*出于任何原因,如果你必须坚持使用Java 6或Java 7,你可以使用ThreeTen-Backport,它将大部分java.time功能反向移植到Java 6和7。如果您正在为Android项目工作,并且您的Android API级别仍然不符合Java-8,请查看通过desugaring提供的Java 8 +API和如何在Android项目中使用ThreeTenABP。