You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何阿拉伯回历1446年2月29日转日期报错,30日却正常?

ORA-01839错误:回历1446年2月29日转换失败,30日却正常的原因

核心原因

Oracle的DATE类型本身存储的是绝对日期值(与具体日历无关),仅在输入解析、输出格式化时受NLS_CALENDAR等参数控制。你的转换语句存在关键问题:最后一步调用TO_DATE时未指定NLS_CALENDAR='Arabic Hijrah',导致Oracle用默认的**公历(Gregorian)**规则解析回历格式的日期字符串,从而引发矛盾。

具体场景分析

  1. 回历1446年2月29日转换报错
    当执行TO_DATE('1446/2/29', 'YYYY/MM/DD')时,Oracle默认用公历解析:公历1446年是平年,2月仅有28天,29日属于无效日期,因此触发ORA-01839: date not valid for month specified错误。

  2. 回历1446年2月30日看似转换成功
    当解析'1446/2/30'时,Oracle默认的宽松日期解析规则会自动修正无效日期:将公历2月30日滚动为同年3月2日。而该公历日期对应的回历日期恰好是1446年2月30日,因此输出时(受NLS_CALENDAR设置影响)显示为30/02/1446,让你误以为是成功解析了回历日期,实际是解析过程中发生了日期滚动,并非正确遵循回历规则解析。

正确的转换方法

要正确解析回历日期,必须在TO_DATE中明确指定NLS_CALENDAR='Arabic Hijrah'参数,确保用回历规则解析字符串:

简化版(直接解析回历日期)

SELECT TO_DATE('1446/2/29', 'YYYY/MM/DD', 'NLS_CALENDAR=''Arabic Hijrah''') 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', 
    'NLS_CALENDAR=''Arabic Hijrah'''
) as HijriDate from dual;

以上两种写法都能正确解析回历1446年2月29日,不会触发错误。


内容的提问来源于stack exchange,提问作者shady

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 20:05:23