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

For a given Date object, capture it's value relevant to GMT timezone

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

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

我尝试了 SimpleDateFormat 和 ZonedDateTime,但有一个痛点。这些 API 以字符串值的形式向我提供 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(日期对象)打印本地时区的值。

P.S.: 我的最终目标是在 java.sql.TimeStamp 对象中有一个 GMT 值。

这是如何实现的?

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

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

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

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

您误解了日期时间的语义类。 java.util.Date 是一个特定的时间点,一个瞬间,它没有与之关联的时区。但是,如果您有时区,则可以向时区询问 java.util.Date.

的时间

java.sql.TimeStamp 等价于 java.time.LocalDateTime。它不是瞬间,也没有与之关联的时区。

首先,Date class 是旧式(无双关语)基础设施的一部分。如果有可能摆脱它并使用 java.time 包。但是如果你必须使用 Date 那么你的时区问题就不是问题了。您的行 System.out.println(gmtDate); 仅使用您当地的时区打印它,因为系统假定它是最佳选择。但是,尽管 Date 保持自 1970 年 1 月 1 日以来的特定时刻(以毫秒为单位),00:00:00 GMT。 Class Date 有方法 compareTo(), after() and before() that allow you to compare 2 Dates. Also Date has method getTime() that returns you the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this date. So you can compare the long values. But again, The best option is to switch to java.time package and classes Instant and ZonedDateTime (和其他)有方法 compareTo()、isAfter() 和 isBefore()。

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.Timestampjava.sql 中的其他日期时间类型。它们都设计得很差,而且早就过时了。

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

一些相关问题

  • Get GMT Time in Java
  • SimpleDateFormat returns wrong time zone during parse