将Oracle DB中的时区偏移存储为单独的字段

时间:2017-06-08 08:25:05

标签: java oracle hibernate timezone timezone-offset

我正在开发航空飞行Java应用程序,需要在Oracle DB中存储带有时区信息的本地时间。

DATE / TIMESTAMP类型的问题比WITH TIME ZONE类似物少。

如果我在DATE字段中存储本地日期,我应该为Oracle DB和Java / Hibernate映射中的单独字段分配哪种类型的偏移量?我希望日期算法在Java和Oracle本机SQL查询中都很容易。

我只能成像INT(6)以秒为单位存储偏移量。本机Oracle SQL查询可以使用算术运算:

departure_date + departure_off/(24*60*60)

在Java中:

departureDate.atOffset(ZoneOffset.ofTotalSeconds(departureOff))

更新我没有关于TZ区域的信息,例如“美国/太平洋”,只有数字偏移。

2 个答案:

答案 0 :(得分:3)

我首先建议使用TIMESTAMP WITH TIME ZONE,resp。 TIMESTAMP WITH LOCAL TIME ZONE,我认为这是最简单的方式。

否则我会根据ISO-8601存储时区偏移量,即VARCHAR(6)值为+05:00

然后,您可以非常简单地转换为TIMESTAMP WITH TIME ZONE

SELECT FROM_TZ(departure_date, departure_off)
FROM ...

答案 1 :(得分:1)

唐'吨。将所有时间转换为公共时区(即UTC),然后,当前端想要在其本地时区显示时,它可以从UTC进行转换。

INSERT INTO your_table ( departure_date )
VALUES (
  FROM_TZ(
    CAST( :your_date AS TIMESTAMP ),
    TO_CHAR( TRUNC( :your_offset / 60 ), 'FMS00' )
      || ':' || TO_CHAR( MOD( :your_offset, 60 ), 'FM00' )
  ) AT TIME ZONE 'UTC'
);

或者您可以使用TIMESTAMP WITH TIME ZONE

CREATE TABLE departures (
  departure_date   TIMESTAMP WITH TIME ZONE
);

INSERT INTO your_table ( departure_date )
VALUES (
  FROM_TZ(
    CAST( :your_date AS TIMESTAMP ),
    TO_CHAR( TRUNC( :your_offset / 60 ), 'FMS00' )
      || ':' || TO_CHAR( MOD( :your_offset, 60 ), 'FM00' )
  )
);

但是,如果您真的想分别存储日期和偏移量,请使用INTERVAL DAY TO SECOND

CREATE TABLE departures (
  departure_date   DATE,
  departure_offset INTERVAL DAY TO SECOND
);

INSERT INTO departures VALUES (
  :your_date,
  NUMTODSINTERVAL( :your_offset, 'SECOND' )
);