对于给定的Date对象,获取与GMT时区相关的值

时间:2019-09-05 15:11:42

标签: java java-8 zoneddatetime sql-timestamp

在运行于Java 8上的应用程序中,我有一个Date对象。该对象的时区取决于客户端的位置。

在某个特定的时刻,我需要将此日期转换为GMT,以便它可以与我从数据库访问的值相当。

我尝试了SimpleDateFormat和ZonedDateTime,但是有一个痛点。这些API为我提供了String值的GMT时间,这非常好。但是,一旦我将其解析并分配给Date对象,它就会回到我的本地时区!

例如:

public class TimeZoneDemo {
    public static void main(String[] args) throws ParseException {
        Date istDate = Calendar.getInstance().getTime();

        ZonedDateTime gmtTime = istDate.toInstant().atZone(ZoneId.of("GMT"));
        System.out.println(gmtTime);

        Date gmtDate = Date.from(gmtTime.toInstant());
        System.out.println(gmtDate);
    }
}

在上面的代码中, gmtTime 显示与GMT时区相关的正确值,但 gmtDate (日期对象)在当地时区打印值。

PS:我的最终目标是在java.sql.TimeStamp对象中具有GMT值。

如何实现?

更新1: 经过评论和回复后,我了解到Date对象仅包含一个包含毫秒的长值。 但是,我的期望是在执行此行时:

Date gmtDate = Date.from(gmtTime.toInstant());

无论对象 gmtTime 包含什么时间,我都需要在TimeStamp或Date对象中捕获该时间。这样做的目的是能够与数据库中保留的值进行比较。我正在将日期作为参数传递给SQL查询。

有人可以帮我理解如何实现吗?

3 个答案:

答案 0 :(得分:2)

首先Date类是旧的过时(无双关语)基础结构的一部分。如果有可能,请摆脱它,而使用java.time包。但是,如果必须使用Date,那么时区问题就不成问题了。您的行System.out.println(gmtDate);仅使用您当地的时区进行打印,因为系统认为这是最佳选择。但是,无论Date处于格林尼治标准时间1970年1月1日00:00:00以来的特定时刻(以毫秒为单位)。类Date的方法compareTo()after()before()可以比较2个日期。此外,Date还具有方法getTime(),该方法返回自该日期表示的格林尼治标准时间1970年1月1日00:00:00以来的毫秒数。因此,您可以比较long的值。但是同样,最好的选择是切换到java.time包,并且类InstantZonedDateTime(以及其他类)具有compareTo(),isAfter()和isBefore()方法。

答案 1 :(得分:2)

java.time和JDBC 4.2

答案在@BasilBourque的评论中:使用OffsetDateTime

    PreparedStatement yourPreparedStatement = yourDatabaseConnection.prepareStatement(
            "select smth from your_table where your_time_stamp_col < ?;");
    OffsetDateTime gmtTime = OffsetDateTime.now(ZoneOffset.UTC);
    yourPreparedStatement.setObject(1, gmtTime);

这需要兼容JDBC 4.2的JDBC驱动程序,我认为到目前为止我们所有人都在使用该驱动程序。这样做很好,因为它允许我们绕过java.sql.Timestamp中的java.sql和其他日期时间类型。它们的设计都不好,而且已经过时了。

正如其他人所说,过时的类DateTimestamp都没有任何时区或与UTC / GMT偏移。

一些相关问题

答案 2 :(得分:0)

您误解了日期时间类的语义。 transform(df, group = with(rle(is.na(df$x)), rep(seq_along(values), lengths))) # x y group #1 1 1 1 #2 2 2 1 #3 3 3 1 #4 4 4 1 #5 NA NA 2 #6 NA NA 2 #7 NA NA 2 #8 8 8 3 #9 9 9 3 #10 10 10 3 是特定的时间点,即瞬间,没有与之关联的时区。但是,如果您有时区,则可以向时区询问该java.util.Date的时间。

java.util.Date等效于java.sql.TimeStamp。它不是瞬间,也没有与之关联的时区。