Java 如何从Oracle获取时区ID而不是时区偏移量
有没有办法从oracle获取时区id而不是时区偏移量? 当我执行Java 如何从Oracle获取时区ID而不是时区偏移量,java,oracle,timezone,Java,Oracle,Timezone,有没有办法从oracle获取时区id而不是时区偏移量? 当我执行时,从DUAL中选择SYSTIMESTAMP作为时区返回的结果是13-JAN-21 10.19.52.936031000 AM+05:30 当我使用rs.getObject(“TIMEZONE”,zoneDateTime.class)从Java中检索这个时,zoneDateTime对象的偏移量和分区ID都设置为+05:30 但我希望看到的是,从DUAL中选择SYSTIMESTAMP作为时区应返回04-JAN-21 02.40.50.
时,从DUAL中选择SYSTIMESTAMP作为时区代码>返回的结果是13-JAN-21 10.19.52.936031000 AM+05:30
当我使用rs.getObject(“TIMEZONE”,zoneDateTime.class)
从Java中检索这个时,zoneDateTime对象的偏移量和分区ID都设置为+05:30
但我希望看到的是,从DUAL中选择SYSTIMESTAMP作为时区
应返回04-JAN-21 02.40.50.000000000 PM ASIA/COLOMBO
,查询的Java ZoneDateTime应将偏移量设置为+05:30
,并将zoneID
设置为ASIA/COLOMBO
有没有一种方法可以在DB级或Java级进行设置?当前DBTIMEZONE
设置为+05:30
您可以使用ALTER database
命令在数据库级别设置时区,如下所示:
alter database set time_zone = '+05:30';
请注意,这将在重新启动数据库后生效
shutdown immediate
startup
Oracle TZ_OFFSET()函数返回有效时区名称或SESSIONTIMEZONE或DBTIMEZONE函数名称相对于UTC的时区偏移量
TZ_OFFSET(value)
TZ_OFFSET()函数接受一个参数,该参数可以是有效的时区名称,例如“Europe/London”、SESSIONTIMEZONE或DBTIMEZONE的函数名,或者UTC的时区偏移量(它只返回自身)
结果将是+01:00这是获取时区的方式
SELECT systimestamp AS DBTime,
systimestamp at time zone 'Europe/London',
systimestamp at time zone 'America/Sao_Paulo'from dual;
从某种意义上说,你运气不好SYSTIMESTAMP
只返回操作系统报告的内容。时区是承载数据库的计算机系统的时区。它不是数据库时区(可能与数据库实际驻留的位置完全无关)或会话时区或诸如此类的东西。如果可以,您需要在db主机操作系统本身中进行更改
如果您确信托管您的数据库的系统位于斯里兰卡,那么您可以通过以下方式间接获得您想要的:
select systimestamp AT TIME ZONE 'ASIA/COLOMBO' from dual;
如果数据已经在Oracle SQL表中,并且必须转换为带时区的时间戳(例如,在同一表中创建的新列中),则不需要显式转到操作系统,也不需要使用Java或Oracle数据库本身以外的任何其他东西
您的问题不清楚您是否必须假定“日期”在服务器时区(您提到的“数据库”通常指服务器)或客户端时区(您提到的“会话”指客户端)。无论哪种方式:
update <your_table>
set <timestamp_with_time_zone_col> =
from_tz(cast<date_col> as timestamp, dbtimezone)
;
作为参考,您可以检查此链接,该链接在数据库操作系统的时区中返回,因此无法在数据库中更改
不要将数据库操作系统的时区与DBTIMEZONE
混用,它们是不同的
另请注意,尽管(目前)具有相同的UTC偏移量,但亚洲/科伦坡时区与时区+05:30
不同
时区亚洲/科伦坡
考虑了夏令时,以防其适用,它还包括。例如,亚洲/科伦坡在2006年从UTC+06:00改为UTC+05:30。因此TZ_OFFSET(时间戳'2020-01-01 12:00:00 Asia/Colombo')
返回的偏移量不同于TZ_OFFSET(例如,时间戳'2000-01-01 12:00:00 Asia/Colombo')
时区+05:30
始终在UTC前5:30
你的问题不是很清楚,你想得到什么?正如我在问题中所说的,从DUAL中选择DBTIMEZONE代码>返回+05:30
。但我希望这是亚洲/科伦坡
。实际上,只要查询从DUAL中选择SYSTIMESTAMP作为时区,我就不关心这个查询返回什么
retunrs04-JAN-21 02.40.50.000000000 PM ASIA/COLOMBO
而不是04-JAN-21 02.40.50.000000000 PM+05:30
systimestamp
报告托管数据库的计算机操作系统的时区。数据库时区与此无关。实际上,我将我的数据库时区设置为+00:00,由从dual
选择dbtimezone确认systimestamp
的时区为-08:00
,这是我的机器上Unix操作系统的时区,位于美国西海岸。更改DBTIMEZONE
对systimestamp
没有影响,请参阅其他答案。很明显,不需要创建从偏移量到名称的转换函数,您就可以得到想要的东西。您可能希望尝试从v$timezone\u名称中选择。问题是有不少于8个时区具有该偏移量。看,我想从ZoneOffset中获取ZoneID。这就提供了另一种方式,即已经有两票领先。。。对于一个根本不回答问题的答案(事实上,似乎回答者一开始就不理解问题)-这是如何回答问题的?这是如何回答OP的问题的?已经有两票了。。。哇-请看一看这个:您需要正确设置Java时区,例如,使用环境变量Java\u TOOL\u OPTIONS=-Duser.timezone=Asia/Colombo
当我查询rs.getObject(“时区”)时,我希望得到ZoneID
和ZoneOffset
,ZonedDateTime.class
来自Java。假设列TIMEZONE
具有SYSTIMESTAMP
作为值,那么Java中的ZonedDateTime
对象将ZoneID
和ZoneOffset设置为+05:30
。但我希望ZoneID
成为Asia/Colombo
和ZoneOffset
>在ZoneDateTime
对象中为+05:30
。写入的SYSTIMESTAMP
在
select systimestamp AT TIME ZONE 'ASIA/COLOMBO' from dual;
update <your_table>
set <timestamp_with_time_zone_col> =
from_tz(cast<date_col> as timestamp, dbtimezone)
;
with
my_table ( dt ) as (
select to_date('2018-06-20 14:30:00', 'yyyy-mm-dd hh24:mi:ss') from dual
)
select dt,
from_tz(cast(dt as timestamp), sessiontimezone) as ts_with_tz
from my_table
;
DT TS_WITH_TZ
------------------- -------------------------------------------------
2018-06-20 14:30:00 2018-06-20 14:30:00.000000000 AMERICA/LOS_ANGELES