简体   繁体   English

如何从 Oracle 获取时区 ID 而不是时区偏移

[英]How to get the timezone ID from Oracle instead timezone offset

Is there a way to get the timezone id instead of the timezone offset from the oracle?有没有办法从 oracle 获取时区 ID 而不是时区偏移量? When I execute SELECT SYSTIMESTAMP AS TIMEZONE FROM DUAL;当我执行SELECT SYSTIMESTAMP AS TIMEZONE FROM DUAL; the returned result is 13-JAN-21 10.19.52.936031000 AM +05:30 .返回的结果是13-JAN-21 10.19.52.936031000 AM +05:30

When I retrieve this from Java using the rs.getObject( "TIMEZONE ", ZonedDateTime.class ) , the ZonedDateTime object has both the offset and zoneID set to +05:30 .当我使用rs.getObject( "TIMEZONE ", ZonedDateTime.class )从 Java 检索此内容时, ZonedDateTime ZA8CFDE6331BD59EB2AC96F8911C4B605Z 的offsetzoneID设置为 +056 +05:30

But what I expect to see is, SELECT SYSTIMESTAMP AS TIMEZONE FROM DUAL;但我希望看到的是, SELECT SYSTIMESTAMP AS TIMEZONE FROM DUAL; should return 04-JAN-21 02.40.50.000000000 PM ASIA/COLOMBO And the Java ZonedDateTime for the query should have the offset set to +05:30 and the zoneID set to Asia/Colombo .应返回04-JAN-21 02.40.50.000000000 PM ASIA/COLOMBO并且查询的 Java ZonedDateTime 应将offset设置为+05:30并将zoneID设置为Asia/Colombo

Is there a way to set up this in DB level or Java level?有没有办法在数据库级别或 Java 级别进行设置? Current DBTIMEZONE is set to +05:30 .当前DBTIMEZONE设置为+05:30

if the data is already in an Oracle SQL table, and you must convert to a timestamp with time zone (for example, in a new column you created in the same table), you do not need to go explicitly to the OS, or to use Java or any other thing, other than the Oracle database itself.如果数据已经在 Oracle SQL 表中,并且您必须转换为带有时区的时间戳(例如,在您在同一个表中创建的新列中),则不需要将 Z34D1F91FB2E7 或 514B867BZFAB 显式转换为 OS1使用 Java 或任何其他东西,除了 Oracle 数据库本身。

It is not clear from your question if you must assume the "date" was meant to be in the server time zone (you mention "the database" which normally means the server) or the client time zone (you mention "session" which means the client).从您的问题中不清楚您是否必须假设“日期”是在服务器时区(您提到“数据库”,通常表示服务器)或客户端时区(您提到“会话”,这意味着客户端)。 Either way:无论哪种方式:

update <your_table>
set <timestamp_with_time_zone_col> = 
            from_tz(cast<date_col> as timestamp, dbtimezone)
;

or use sessiontimezone as the second argument, if that's what you need.或者使用 sessiontimezone 作为第二个参数,如果你需要的话。

This assumes that the database (and/or the session) time zone is set up properly in the db, respectively in the client.这假设数据库(和/或会话)时区在数据库中正确设置,分别在客户端中。 If it isn't / they aren't, that needs to be fixed first.如果不是/它们不是,则需要先修复。 Oracle is perfectly capable of handling daytime savings time, if the parameters are set correctly in the first place.如果首先正确设置参数,Oracle 完全能够处理日间节省时间。 (And if they aren't, it's not clear why you would try to get your operation to be "more correct" than the database supports in the first place.) (如果不是,则不清楚为什么您会尝试让您的操作比数据库最初支持的“更正确”。)

Example: in the WITH clause below, I simulate a table with a column dt in data type date.示例:在下面的 WITH 子句中,我模拟了一个具有数据类型 date 的列 dt 的表。 Then I convert that to be a timestamp with time zone, in my session's (client) time zone.然后我将其转换为带有时区的时间戳,在我的会话(客户端)时区。

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

For Reference You can Check this Link StackOverflow Ref.供参考您可以检查此链接StackOverflow 参考。 Link 关联

In a sense, you are out of luck.从某种意义上说,你运气不好。 SYSTIMESTAMP simply returns what your operating system reports. SYSTIMESTAMP只返回您的操作系统报告的内容。 The time zone is the time zone of the computer system hosting your database.时区是托管数据库的计算机系统的时区。 It is not the database time zone (which may be something completely unrelated to where the DB actually resides) or the session time zone or anything like that.不是数据库时区(可能与数据库实际所在的位置完全无关)或 session 时区或类似的东西。 You will need to make the change in the db host OS itself, if you can.如果可以,您将需要在 db 主机操作系统本身中进行更改。

If you know for sure that the system that hosts your database is in Sri Lanka, then you can get what you want indirectly like so:如果您确定托管您的数据库的系统位于斯里兰卡,那么您可以像这样间接获得您想要的东西:

select systimestamp AT TIME ZONE 'ASIA/COLOMBO' from dual;

You can set the timezone at database level using ALTER database command as follows:您可以使用ALTER database命令在数据库级别设置时区,如下所示:

alter database set time_zone = '+05:30';

Please note that this will take effect after you restart your DB.请注意,这将在您重新启动数据库后生效。

shutdown immediate
startup

SYSTIMESTAMP is returned in the database operating system's time zone - so there is no way to change it within the database. SYSTIMESTAMP在数据库操作系统的时区中返回 - 因此无法在数据库中更改它。

Don't mix the database operating system's time zone with DBTIMEZONE , they are different.不要将数据库操作系统的时区与DBTIMEZONE ,它们是不同的。

Also note, time zone Asia/Colombo is different to time zone +05:30 although they have (currently) the same UTC Offset.另请注意, Asia/Colombo时区与+05:30时区不同,尽管它们(当前)具有相同的 UTC 偏移量。

Time zone Asia/Colombo considers daylight saving times in case it would apply, and it also covers changes .时区Asia/Colombo考虑夏令时以防万一,它还涵盖了更改 For example Asia/Colombo changed in 2006 from UTC+06:00 to UTC+05:30.例如, Asia/Colombo在 2006 年从 UTC+06:00 更改为 UTC+05:30。 Thus TZ_OFFSET(TIMESTAMP '2020-01-01 12:00:00 Asia/Colombo') returns a different offset than TZ_OFFSET(TIMESTAMP '2000-01-01 12:00:00 Asia/Colombo') , for example.例如,因此TZ_OFFSET(TIMESTAMP '2020-01-01 12:00:00 Asia/Colombo')返回与TZ_OFFSET(TIMESTAMP '2000-01-01 12:00:00 Asia/Colombo')不同的偏移量。

Time zone +05:30 is always 5:30h before UTC.时区+05:30始终是 UTC 之前的 5:30。

Your question is not really clear, what do you like to get?你的问题不是很清楚,你想得到什么?

The Oracle TZ_OFFSET() function returns the time zone offset from UTC of a valid time zone name or the SESSIONTIMEZONE or DBTIMEZONE function name. Oracle TZ_OFFSET() function 返回有效时区名称或 SESSIONTIMEZONE 或 DBTIMEZONE ZC1C425268E683854F14ZA 名称的 UTC 的时区偏移量。

TZ_OFFSET(value)

he TZ_OFFSET() function accepts one argument which can be a valid time zone name eg, 'Europe/London', a function name of SESSIONTIMEZONE or DBTIMEZONE, or a time zone offset from UTC (which simply returns itself).他 TZ_OFFSET() function 接受一个参数,该参数可以是有效的时区名称,例如“欧洲/伦敦”、SESSIONTIMEZONE 或 DBTIMEZONE 的 function 名称或与 UTC 的时区偏移量(仅返回自身)。

SELECT
  TZ_OFFSET( 'Europe/London' )
FROM
  DUAL;

The result would be +01:00结果将是 +01:00

This is how you can get timezone.这就是你如何获得时区。

SELECT systimestamp AS DBTime,
       systimestamp at time zone 'Europe/London',
       systimestamp at time zone 'America/Sao_Paulo'from dual;

SELECT
  TZ_OFFSET( DBTIMEZONE )
FROM
  DUAL;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM