java.time
java.util
日期时间 API 及其格式化 API已SimpleDateFormat
过时且容易出错。建议完全停止使用它们并切换到现代 Date-Time API *。
另外,下面引用的是来自Joda-Time主页的通知:
请注意,从 Java SE 8 开始,用户被要求迁移到 java.time (JSR-310) - JDK 的核心部分,它取代了这个项目。
使用java.time
现代日期时间 API 的解决方案:太平洋时区最大的城市是洛杉矶,其时区名称为America/Los_Angeles。使用ZoneId.of("America/Los_Angeles")
,您可以创建一个实例, ZonedDateTime
该实例旨在在DST转换时自动调整时区偏移。
如果您需要时区偏移量但不需要时区名称,您可以将 a 转换ZonedDateTime
为OffsetDateTime
using ZonedDateTime#toOffsetDateTime
。的其他一些用途OffsetDateTime
是创建具有固定时区偏移量的日期时间实例(例如Instant.now().atOffset(ZoneOffset.of("+05:30"))
,以及解析具有时区偏移量的日期时间字符串。
演示:
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
public class Main {
public static void main(String[] args) {
ZoneId zoneIdLosAngeles = ZoneId.of("America/Los_Angeles");
ZonedDateTime zdtNowLosAngeles = ZonedDateTime.now(zoneIdLosAngeles);
System.out.println(zdtNowLosAngeles);
// With zone offset but without time zone name
OffsetDateTime odtNowLosAngeles = zdtNowLosAngeles.toOffsetDateTime();
System.out.println(odtNowLosAngeles);
// Truncated up to seconds
odtNowLosAngeles = odtNowLosAngeles.truncatedTo(ChronoUnit.SECONDS);
System.out.println(odtNowLosAngeles);
// ################ A winter date-time ################
ZonedDateTime zdtLosAngelesWinter = ZonedDateTime
.of(LocalDateTime.of(LocalDate.of(2021, 11, 20), LocalTime.of(10, 20)), zoneIdLosAngeles);
System.out.println(zdtLosAngelesWinter); // 2021-11-20T10:20-08:00[America/Los_Angeles]
System.out.println(zdtLosAngelesWinter.toOffsetDateTime()); // 2021-11-20T10:20-08:00
// ################ Parsing a date-time string with zone offset ################
String strDateTime = "2008-11-13T13:23:30-08:00";
OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
System.out.println(odt); // 2008-11-13T13:23:30-08:00
}
}
示例运行的输出:
2021-07-18T03:27:15.578028-07:00[America/Los_Angeles]
2021-07-18T03:27:15.578028-07:00
2021-07-18T03:27:15-07:00
2021-11-20T10:20-08:00[America/Los_Angeles]
2021-11-20T10:20-08:00
2008-11-13T13:23:30-08:00
ONLINE DEMO
您一定已经注意到我没有使用 aDateTimeFormatter
来解析您问题的日期时间字符串。这是因为您的日期时间字符串符合 ISO-8601 标准。现代日期时间 API 基于ISO 8601DateTimeFormatter
,只要日期时间字符串符合 ISO 8601 标准,就不需要明确使用对象。
从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。