Oracle中的CONVERT_TZ()等效项

时间:2020-06-07 14:31:11

标签: sql oracle timezone

我正在尝试将格式为YYYY-MM-DDTHH24:MI:SS的时间戳值转换为另一个时区值YYYY-MM-DD HH24:MI:SS.SSSSSS。我可以使用CONVERT_TZ(date, from_tz, to_tz)函数在MySql中做到这一点,

timestamp (varchar): `2018-06-08T23:00:00`
offset (varchar): `+00:00`

convert_tz(timestamp, offset, '+00:00') = 2018-06-08 23:00:00工作正常

我如何在Oracle中做同样的事情?

我想传递这3个值(时间戳,偏移量,'+ 00:00'),并尝试在Oracle中使用from_tz(),但能够仅传递两个值(时间戳,偏移量),我如何传递第三个值('+00:00')?

这是我的查询

INSERT INTO CLIENTTABLE(id, timestamp, orgId) SELECT NULL, from_tz(to_timestamp('2018-06-08T23:00:00', 'YYYY-MM-DD"T"HH24:MI:SS') ,'+00:00'), '1010' FROM IMPORTDATA;

这给出了:08-JUN-18 11.00.00.000000000 PM +00:00

所需的输出2018-06-08 23:00:00.000000

感谢您的帮助。谢谢!

2 个答案:

答案 0 :(得分:1)

您可以分别转换字符串和偏移量; to_timestamp()为您提供了简单的时间戳记(无时区),您可以声明它来自特定的时间戳记,这基本上就是您已经在执行的操作。结果是带有时区的时间戳。然后,您使用at time zone转换为另一个。最后,您可以将其转换回字符串:

我将使用其他偏移量使其更清晰:

select to_timestamp('2018-06-08T23:00:00', 'YYYY-MM-DD"T"HH24:MI:SS') as ts,
  from_tz(
    to_timestamp('2018-06-08T23:00:00', 'YYYY-MM-DD"T"HH24:MI:SS'),
    '+05:30'
  ) as tstz_local,
  from_tz(
    to_timestamp('2018-06-08T23:00:00', 'YYYY-MM-DD"T"HH24:MI:SS'),
    '+05:30'
  ) at time zone 'UTC' as tstz_utc,
  to_char(
    from_tz(
      to_timestamp('2018-06-08T23:00:00', 'YYYY-MM-DD"T"HH24:MI:SS'),
      '+05:30'
    ) at time zone 'UTC',
    'YYYY-MM-DD HH24:MI:SS.FF6'
  ) as str_utc
from dual;

您当然不需要那些单独的结果,我只是在显示工作原理。

要结束使用UTC,可以使用内置函数稍微简化一下:

select to_char(
  sys_extract_utc(
    from_tz(
      to_timestamp('2018-06-08T23:00:00', 'YYYY-MM-DD"T"HH24:MI:SS'),
      '+05:30'
    )
  ), 'YYYY-MM-DD HH24:MI:SS.FF6') as str_utc
  as tstz_utc,
from dual;


STR_UTC
--------------------------
2018-06-08 17:30:00.000000

db<>fiddle

或者,您可以将两个字符串连接在一起,然后将它们直接转换为带有时区的时间戳:

select to_char(
  sys_extract_utc(
    to_timestamp_tz('2018-06-08T23:00:00' || '+05:30',
      'YYYY-MM-DD"T"HH24:MI:SS TZH:TZM')
  ), 'YYYY-MM-DD HH24:MI:SS.FF6') as str_utc
from dual;

db<>fiddle

日期或时间戳(带有或不带有时区)没有任何实际可识别的格式; Oracle根据上下文使用几种内部表示形式。如果您没有使用to_char()显式转换为字符串,那么客户端将通过自己的设置或更通常通过会话NLS参数NLS_DATE_FORMATNLS_TIMESTAMP_FORMAT决定使用哪种格式。等

尽管如此,您只应该显示该内容。在表中存储数据时,请为列使用正确的本机数据类型-在这种情况下为时间戳。不要将其存储为字符串。假设您的目标表列实际上是一个时间戳,并且源登台表具有字符串,那么您将执行以下操作:

INSERT INTO CLIENTTABLE(id, timestamp, orgId)
SELECT
  NULL,
  sys_extract_utc(
    from_tz(
      to_timestamp(timestamp, 'YYYY-MM-DD"T"HH24:MI:SS'),
      offset
    )
  ),
  '1010'
FROM IMPORTDATA;

具有与数据类型相同的名称的列会令人困惑,就像在源表和目标表中具有相同的名称一样。

答案 1 :(得分:0)

我认为这可能是因为您使用的会话时间格式。您也可以通过这种方式进行检查。

alter session set nls_Date_format = 'YYYY-MM-DD HH24:MI:SS';
SELECT NULL valun, cast(from_tz(to_timestamp('2018-06-08T23:00:00', 'YYYY-MM-DD"T"HH24:MI:SS') ,'+00:00') as date) timen, '1010' idn FROM dual;

输出: enter image description here