在数据库中以 AEST 时区存储日期

Store date in AEST timezone in database

我们在 oracle 数据库中有两个表,如下所示,

表 A => 列 DateA(类型 DATE)

TableB => 列 DateB(类型 DATE)

TableA 中的 DateA 列具有以 UTC 格式存储的日期。 TableB 中的 DateB 列的日期存储在 AEST 中。

当我检查这些表中存储日期的代码(在 java 中)时,两者都只是实例化 Date 类型,如下所示。

现在日期 = 新日期();

当他们使用相同的代码时,他们如何在不同的时区设置日期? 我想知道其他地方是否还有其他配置?

请多多指教。最后,我需要更新代码,以便所有日期都存储在 AEST 中。

DateA column in TableA has dates stored in UTC. DateB column in TableB has dates stored in AEST.

不,没有列以 UTC 或 AEST 格式存储。 Oracle 数据库中的 DATE 类型仅存储日期和时间。该数据类型故意缺少任何时区或与 UTC 的偏移量的概念。您在该列中输入的任何日期和时间都会被保存,但如果没有 zone/offset,我们将无法确定时刻(时间线上的一个点)。

Date now = new Date();

切勿在 Java 中使用 Date class。这些可怕的 classes 是由不了解日期时间处理的人设计的。这些 classes 现在是遗留的,多年前被 JSR 310 中定义的现代 java.time classes 取代。

Ultimately, I need to update code so all dates are stored in AEST.

由于您在现有存储数据中丢失了 zone/offset 的上下文,我看不出有什么方法可以清理这些混乱。

但是,仅供参考,我可以展示存储此类数据的正确方法。

首先,将您的数据库列定义为类似于 SQL 标准类型 TIMESTAMP WITH TIME ZONE 的数据类型(相对于 WITHOUT)。根据我对 this doc 的阅读,对于 Oracle Database 21 那将是同名的 TIMESTAMP WITH TIME ZONE.

在Java中指定所需的时区。

AEST 不是时区。它指示是否启用夏令时 (DST)。切勿在您的业务逻辑和存储的数据中使用此类值。在 Continent/Region.

的新格式中仅使用 real time zone names
ZoneId z = ZoneId.of( "Australia/Sydney" ) ;

捕获与 UTC 零小时-分钟-秒的偏移量的当前时刻。

Instant instant = Instant.now() ;

适应您的时区。

ZonedDateTime zdt = instant.atZone( z ) ;

不幸的是,SQL 标准不处理时区。所以我们必须转换为偏移量而不是区域,以便与数据库交换值。

OffsetDateTime odt = zdt.toOffsetDateTime() ;

通过 JDBC 4.2 或更高版本。

myPreparedStatement.setObject( … , odt ) ;

检索。

OffsetDateTime odt = myResultSet( … , OffsetDateTime.class ) ;

适应您的时区。

ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;