当尝试将日期 ('1446/2/29') 转换为阿拉伯希吉拉历法,并将其与公历 ('2024/9/4') 相对应时,它会返回 ORA-01839:日期对于指定的月份无效错误。这...
当尝试将日期 ('1446/2/29') 转换为 Arabic Hijrah
对应于公历 ('2024/9/4') 的日历时,它会返回 ORA-01839: d日历对应e not valid for month specified
错误。而将更大的日期 ('1446/2/30') 转换为 Arabic Hijrah
对应于公历 ('2024/9/5') 的日历则可以正常工作。以下三个查询解释了 28,29,30 /2/1446
at Arabic Hijrah
于公历的 3,4,5 /9/2024
情况
SELECT TO_DATE(TO_CHAR(TO_DATE('2024/9/3', 'YYYY/MM/DD'), 'YYYY/MM/DD', 'NLS_CALENDAR=''Arabic Hijrah'''), 'YYYY/MM/DD') as HijriDate from dual;
SELECT TO_DATE(TO_CHAR(TO_DATE('2024/9/4', 'YYYY/MM/DD'), 'YYYY/MM/DD', 'NLS_CALENDAR=''Arabic Hijrah'''), 'YYYY/MM/DD') as HijriDate from dual;
SELECT TO_DATE(TO_CHAR(TO_DATE('2024/9/5', 'YYYY/MM/DD'), 'YYYY/MM/DD', 'NLS_CALENDAR=''Arabic Hijrah'''), 'YYYY/MM/DD') as HijriDate from dual;
与阿拉伯希吉拉历法日期相同的查询
SELECT TO_DATE(TO_CHAR(TO_DATE('1446/2/28', 'YYYY/MM/DD', 'NLS_CALENDAR=''Arabic Hijrah'''), 'YYYY/MM/DD', 'NLS_CALENDAR=''Arabic Hijrah'''), 'YYYY/MM/DD') as HijriDate from dual
SELECT TO_DATE(TO_CHAR(TO_DATE('1446/2/29', 'YYYY/MM/DD', 'NLS_CALENDAR=''Arabic Hijrah'''), 'YYYY/MM/DD', 'NLS_CALENDAR=''Arabic Hijrah'''), 'YYYY/MM/DD') as HijriDate from dual
SELECT TO_DATE(TO_CHAR(TO_DATE('1446/2/30', 'YYYY/MM/DD', 'NLS_CALENDAR=''Arabic Hijrah'''), 'YYYY/MM/DD', 'NLS_CALENDAR=''Arabic Hijrah'''), 'YYYY/MM/DD') as HijriDate from dual
相应结果
28/02/1446
ORA-01839: date not valid for month specified
30/02/1446
为什么 (29/2/1446) 会出现该错误,而 (30/2/1446) 却不会出现该错误?
TO_DATE(string, format_model, nls_settings)
将字符串转换为 DATE
并假定输入和输出都使用公历。
如果您输入的字符串采用不同的日历,则需要在参数中指定日历 nls_settings
。 DATE
输出将始终采用公历。
当您使用 Hijrah 日历将日期转换为字符串时,您会得到值 1446-02-28
, 1446-02-29
, 1446-03-01
而当您使用未指定日历将其转换回日期 TO_DATE
时,则会使用公历,而公历 1446 年不是闰年,因此 1446-02-29
无效。
DATE
,则它们将存储在公历中,并且您需要将日历指定为第三个参数,以便 TO_DATE
从其他日历(Hijrah)转换为公历 DATE
.
像这样:
WITH dates (dt) AS (
SELECT DATE '2024-09-03' FROM DUAL UNION ALL
SELECT DATE '2024-09-04' FROM DUAL UNION ALL
SELECT DATE '2024-09-05' FROM DUAL UNION ALL
SELECT TO_DATE('1446/2/28', 'YYYY/MM/DD', 'NLS_CALENDAR=''Arabic Hijrah''') FROM DUAL UNION ALL
SELECT TO_DATE('1446/2/29', 'YYYY/MM/DD', 'NLS_CALENDAR=''Arabic Hijrah''') FROM DUAL UNION ALL
SELECT TO_DATE('1446/2/30', 'YYYY/MM/DD', 'NLS_CALENDAR=''Arabic Hijrah''') FROM DUAL
)
SELECT dt,
TO_CHAR(dt, 'YYYY/MM/DD', 'NLS_CALENDAR=''Arabic Hijrah''') AS HijriStr,
TO_DATE(
TO_CHAR(dt, 'YYYY/MM/DD', 'NLS_CALENDAR=''Arabic Hijrah''')
DEFAULT NULL ON CONVERSION ERROR,
'YYYY/MM/DD'
) AS NoCalendar,
TO_DATE(
TO_CHAR(dt, 'YYYY/MM/DD', 'NLS_CALENDAR=''Arabic Hijrah'''),
'YYYY/MM/DD',
'NLS_CALENDAR=''Arabic Hijrah'''
) as WithCalendar
FROM dates;
输出:
DT | 希吉里斯特 | 无日历 | 带日历 |
---|---|---|---|
2024-09-03 00:00:00 | 1446/02/28 | 1446-02-28 00:00:00 | 2024-09-03 00:00:00 |
2024-09-04 00:00:00 | 1446/02/29 | p8 | 2024-09-04 00:00:00 |
2024-09-05 00:00:00 | 1446/03/01 | 1446-03-01 00:00:00 | 2024-09-05 00:00:00 |
2024-09-03 00:00:00 | 1446/02/28 | 1446-02-28 00:00:00 | 2024-09-03 00:00:00 |
2024-09-04 00:00:00 | 1446/02/29 | p9 | 2024-09-04 00:00:00 |
2024-09-05 00:00:00 | 1446/03/01 | 1446-03-01 00:00:00 | 2024-09-05 00:00:00 |
小提琴