对于给定的 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.Timestamp
和 java.sql
中的其他日期时间类型。它们都设计得很差,而且早就过时了。
正如其他人所说,过时的 类 Date
和 Timestamp
都没有任何时区或与 UTC/GMT 的偏移量。
一些相关问题
- Get GMT Time in Java
- SimpleDateFormat returns wrong time zone during parse
在 运行 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.Timestamp
和 java.sql
中的其他日期时间类型。它们都设计得很差,而且早就过时了。
正如其他人所说,过时的 类 Date
和 Timestamp
都没有任何时区或与 UTC/GMT 的偏移量。
一些相关问题
- Get GMT Time in Java
- SimpleDateFormat returns wrong time zone during parse