TO_DATE 函数不适用于时区信息。

TO_DATE function is not working with timezone info.

我在下面尝试:

SELECT TO_CHAR( TO_DATE('Wed May 18 00:00:00 IST 2016', 'DY MON DD HH24:MI:SS TZR YYYY'),'DD-MM-YYYY') FROM DUAL;

期待18-05-2016

但它说 - 01821.00000 - "date format not recognized"

如果我删除 IST 和相应的 TZR,效果很好。

怎么了?

Oracle DATE 数据类型does not have a time zone component。普通的 TIMESTAMP 也没有。您需要转换为 TIMESTEMP WITH TIME ZONE:

SELECT TO_CHAR(TO_TIMESTAMP_TZ('Wed May 18 00:00:00 IST 2016',
  'DY MON DD HH24:MI:SS TZR YYYY', 'NLS_DATE_LANGUAGE=ENGLISH'),
  'DD-MM-YYYY')
FROM DUAL;

但 IST 不是可识别的时区区域,因此仍然会得到 ORA-01882: timezone region not found。您可能必须明确地将其替换为已知区域,例如:

SELECT TO_CHAR(TO_TIMESTAMP_TZ(REPLACE('Wed May 18 00:00:00 IST 2016',
  'IST', 'Asia/Calcutta'), 'DY MON DD HH24:MI:SS TZR YYYY', 'NLS_DATE_LANGUAGE=ENGLISH'),
  'DD-MM-YYYY')
FROM DUAL;

TO_CHAR(TO
----------
18-05-2016

或者,如果您不想对其进行任何操作并且无论如何都想要 IST 年份,您可以直接从字符串中提取日期组件,或者将 IST 视为固定值而不是尝试在全部:

SELECT TO_CHAR(TO_DATE('Wed May 18 00:00:00 IST 2016',
  'DY MON DD HH24:MI:SS "IST" YYYY', 'NLS_DATE_LANGUAGE=ENGLISH'),
  'DD-MM-YYYY')
FROM DUAL;

TO_CHAR(TO
----------
18-05-2016

...但这可能不适合你的实际情况。