ORA-01839:日期对于指定的月份无效,如何避免leap年问题

时间:2019-01-28 00:56:26

标签: sql oracle oracle11g

我有一个表,用于存储每个人的有效“自定义日期”。该日期可能合理地是a年的2月29日。事情是在我的报表SQL中,我需要从该自定义日期字段中提取该雇员最近一年的“最后” mm / dd。该日期永远不会在将来,因此我可以比较日期中的年份以及当前年份是否按原样拉。但是,如果是前一年(可以追溯到1900年),则我需要改为从去年起开始使用MM / DD。因此您可以看到这将是一个问题,因为没有2018年2月29日。

我正在寻找有关如何解决此问题的最佳解决方案。我在我的选择部分和条件块中都需要它,我要导出的这个日期必须> = applydtm日期。这是复制错误的示例查询。只需将2月29日的日期更改为2月28日,即可显示它可以正常工作,因为它没有遇到无效的leap年日期。只要代码有效,我就可以将所有2月29日的日期“转换”为3月1日。数据库= Oracle 11g

WITH sampledata (actualcustomdtm, textfield, applydtm)  AS  (
SELECT
TO_DATE('02/29/2012 00:00:00','mm/dd/yyyy hh24:mi:ss'),
'Leap Year',
sysdate
FROM dual
UNION
SELECT
TO_DATE('01/15/2019 00:00:00','mm/dd/yyyy hh24:mi:ss'),
'Non-Leap Year',
sysdate
FROM dual
)
SELECT
actualcustomdtm,
CASE WHEN TO_CHAR(actualcustomdtm, 'YYYY') = TO_CHAR(SYSDATE, 'YYYY')
     THEN TO_CHAR(actualcustomdtm, 'MM/DD/YYYY')
     ELSE TO_CHAR(actualcustomdtm, 'MM/DD')||'/'||TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE), -12), 'YYYY')
     END AS "LASTACTCSTMDATE",
textfield,
applydtm
FROM sampledata
WHERE applydtm >=
    TO_DATE(CASE WHEN TO_CHAR(actualcustomdtm, 'YYYY') = TO_CHAR(SYSDATE, 'YYYY')
    THEN TO_CHAR(actualcustomdtm, 'MM/DD/YYYY')
    ELSE TO_CHAR(actualcustomdtm, 'MM/DD')||'/'||TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE), -12), 'YYYY')
    END, 'MM/DD/YYYY')

1 个答案:

答案 0 :(得分:3)

我相信这种逻辑可以满足您的要求-使最近的周年纪念日达到或包括今天的日期:

select dte, add_months(dte, 12),
       (case when to_char(dte, 'MMDD') > to_char(sysdate, 'MMDD')
             then add_months(dte, 12 * (extract(year from sysdate) - extract(year from dte) - 1))
             else add_months(dte, 12 * (extract(year from sysdate) - extract(year from dte)))
        end)
from (select date '2016-02-29' as dte from dual union all
      select date '2018-01-03' from dual
     ) x;