Java,将字符串 'yyyy-MM-dd'T'HH:mm:ss' 解析为 ZonedDateTime 而不更改时间

ano*_*432 4 java timezone simpledateformat spring-boot zoneddatetime

我有一个字符串“2018-07-24T01:30:27”。我想在不更改时间的情况下将其解析为带有 EST 时区的 ZonedDateTime。

我有代码...

String foo = "2018-07-24T01:30:27";
ZoneId zone = ZoneId.of("America/New_York");

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
return simpleDateFormat.parse(foo).toInstant().atZone(zone);
Run Code Online (Sandbox Code Playgroud)

返回值是

2018-07-24T02:30:27-04:00[America/New_York]
Run Code Online (Sandbox Code Playgroud)

我也试过创建这个类,但它没有帮助

@Configuration
public class TimeZoneConfig {

    @PostConstruct
    public void init() {

        TimeZone.setDefault(TimeZone.getTimeZone("EST"));

        System.out.println("Date in UTC: " + new Date().toString());
    }
}
Run Code Online (Sandbox Code Playgroud)

我能得到一些建议吗?

Bas*_*que 9

tl;博士

LocalDateTime                               // Represents a date with a time-of-day, but lacks a time zone or offset-from-UTC.
.parse( "2018-07-24T01:30:27" )             // Returns a `LocalDateTime`.
.atZone( ZoneId.of( "America/New_York" ) )  // Returns a `ZonedDateTime` object. 
Run Code Online (Sandbox Code Playgroud)

Java 中的日期时间类型表,现代和传统

使用具体的类 java.time 中

michalk答案是正确的,但有点迟钝。它TemporalAccessor显式地使用接口。通常在 Java 中,这将是一件好事。但是java.time类是为应用程序作者设计的,可以调用具体的类而不是接口。引用 Javadoc:

此接口是框架级接口,不应在应用程序代码中广泛使用。相反,应用程序应该创建并传递具体类型的实例,例如 LocalDate。造成这种情况的原因有很多,部分原因是该接口的实现可能在 ISO 以外的日历系统中。有关这些问题的更全面讨论,请参阅 ChronoLocalDate。

LocalDateTime

所以让我们这样做。首先,将输入解析为LocalDateTime. 这个类不代表一个时刻,也不是时间线上的一个点,因为它缺少时区或偏移量的上下文。

String input = "2018-07-24T01:30:27" ;
LocalDateTime ldt = LocalDateTime.parse( input ) ;
Run Code Online (Sandbox Code Playgroud)

ZonedDateTime

提供时区的上下文。

ZoneId zone = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = ldt.atZone( zone ) ;
Run Code Online (Sandbox Code Playgroud)

Instant

如果您想看到调整为 UTC 的同一时刻,请提取一个Instant对象。

Instant instant = zdt.toInstant() ;
Run Code Online (Sandbox Code Playgroud)

不要弄乱默认时区

TimeZone.setDefault

除非万不得已,否则不要设置 JVM 的当前默认时区。这样做会影响该 JVM 中所有应用程序的所有线程中的所有代码。

相反,编写您的java.time代码以明确指定所需/预期的时区。切勿在各种方法中省略可选时区或偏移量。


关于 java.time

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, &SimpleDateFormat

要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310

现在处于维护模式Joda-Time项目建议迁移到java.time类。

您可以直接与您的数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。Hibernate 5 & JPA 2.2 支持java.timejava.sql.*

从哪里获得 java.time 类?