【问题标题】:Timezone offset is not considered with Calendar日历不考虑时区偏移
【发布时间】:2021-12-26 10:38:56
【问题描述】:

我想将时间戳列数据插入 MySQL 列。我所在位置的时区是 GMT+3。以下是我为考虑这个时区所做的事情:

Calendar now = Calendar.getInstance();
TimeZone timeZone = now.getTimeZone();
int differenceUTCms = timeZone.getRawOffset();
int differenceHeureUTC = Integer.parseInt(String.valueOf(TimeUnit.MILLISECONDS.toHours(Long.valueOf(String.valueOf(differenceUTCms)))));
now.setTime(new Date());
if (differenceUTCms <= 0) {
    now.add(Calendar.HOUR, Math.abs(differenceHeureUTC) + 3);
} else {
    now.add(Calendar.HOUR, Math.abs(3 - differenceHeureUTC));
}
query.setParameter(i, now.getTime());

但在运行时我仍然得到 07:24:32 而不是 10:24:32 的小时部分!那么有什么问题呢?

【问题讨论】:

  • 我建议你不要使用CalenderTimeZone。这些课程设计不良且早已过时。而是使用例如OffsetDateTimeZoneId,两者都来自java.time, the modern Java date and time API
  • 它们可以与 Java 8 一起使用吗?
  • 是的。它们完全是在 Java 8 中引入的,所以是内置的。
  • 是的,数据类型是timestampquery 是本机查询:javax.persistence.Query query = entityManager.createNativeQuery(sql);
  • 无关:不要使用字符串将long 转换为int。写int differenceHeureUTC = (int) TimeUnit.MILLISECONDS.toHours(differenceUTCms);

标签: java timezone timezone-offset


【解决方案1】:

正如其他人所说,您可以使用 OffsetDateTime:

https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html

Connection connection = DriverManager.getConnection(DB_Connection.url, DB_Connection.user, DB_Connection.password);

Instant instant = Instant.now();

OffsetDateTime offsetDateTime = OffsetDateTime.ofInstant(instant, ZoneId.systemDefault());
        
String update = "update schedule set timestamp = ? where id = 1";
try (PreparedStatement preparedStatement = connection.prepareStatement(update)){
    preparedStatement.setObject(1, offsetDateTimeUTC);
    preparedStatement.executeUpdate();
}

如果您想要 UTC:

OffsetDateTime offsetDateTimeUTC = instant.atOffset(ZoneOffset.UTC);

=== 已编辑 ===

如果 MySQL 不支持带 Zone 的 TimeStamp,您可以获取 UTC 时间,并转换为 LocateDateTime:

    Instant instant = Instant.now();

    OffsetDateTime time = OffsetDateTime.ofInstant(instant, ZoneId.of("UTC"));

    LocalDateTime timeStampInUTC = time.toLocalDateTime();

    System.out.println(timeStampInUTC); //2021-11-15T11:00:51.670151200

    

【讨论】:

  • JDBC 规范说 SQL 时间戳类型对应于 LocalDateTime。 OffsetDateTime 适用于 TIMESTAMP_WITH_TIMEZONE 类型的列(我认为 MySQL 不支持)。
  • @VGR MySQL timestamp 数据类型的行为类似于其他系统中的 timestamp with time zone,因为它始终采用 UTC。我自己没有尝试过,但我认为驱动程序对这样的列或值的OffsetDateTime 很满意。这绝对是有道理的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-06
  • 2021-08-28
  • 1970-01-01
  • 2022-11-18
  • 2010-11-06
  • 1970-01-01
  • 2014-05-06
相关资源
最近更新 更多