CREATE OR REPLACE FUNCTION FN_ISDATE(V_DATESTR VARCHAR2 --日期入参
) RETURN NUMBER – 返回1为正确,0为错误。
AS
/------------------------------------------------------------------------
公用函数:日期检查函数
调用范例: SELECT FN_ISDATE(‘20140501’) FROM DUAL;
------------------------------------------------------------------------/
V2_DATESTR VARCHAR(20);
I_YEAR NUMBER; --年
I_MONTH NUMBER; --月
I_DAY NUMBER; --日
D_TJRQ DATE; --日期类型的日期
BEGIN
IF REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, ‘年月日*’, ‘’), ‘[[:punct:]]*’, ‘’) IS NULL
THEN
RETURN 0;
END IF;
– 判断日期由数字组成
IF REGEXP_SUBSTR(TRIM(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, ‘年月日*’, ‘’), ‘[[:punct:]]*’, ‘’)), ‘[[:digit:]]+’) IS NULL
THEN
RETURN 0;
END IF;
IF LENGTH(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, ‘年月日*’, ‘’), ‘[[:punct:]]’, ‘’), ’ ', ‘’)) > 8
OR
LENGTH(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, '年月日’, ‘’), ‘[[:punct:]]*’, ‘’), ’ ', ‘’)) < 6
THEN
RETURN 0;
ELSIF LENGTH(TRIM(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, ‘年月日*’, ‘’), ‘[[:punct:]]’, ‘’))) = 6
THEN
V2_DATESTR := SUBSTR(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, '年月日’, ‘’), ‘[[:punct:]]’, ‘’), ’ ', ‘’), 1, 4) || ‘0’ ||
SUBSTR(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, '年月日’, ‘’), ‘[[:punct:]]’, ‘’), ’ ', ‘’), 5, 1) || ‘0’ ||
SUBSTR(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, '年月日’, ‘’), ‘[[:punct:]]*’, ‘’), ’ ', ‘’), 6, 1);
ELSIF LENGTH(TRIM(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, ‘年月日*’, ‘’), ‘[[:punct:]]’, ‘’))) = 8
THEN
V2_DATESTR := RTRIM(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, '年月日’, ‘’), ‘[[:punct:]]*’, ‘’));
ELSIF LENGTH(TRIM(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, ‘年月日*’, ‘’), ‘[[:punct:]]’, ‘’))) = 7
AND
INSTR(TRIM(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, '年月日’, ‘-’), ‘[[:punct:]]’, ‘-’)), ‘-’, 2) -
INSTR(TRIM(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, '年月日’, ‘-’), ‘[[:punct:]]’, ‘-’)), ‘-’, 1) = 1
THEN
V2_DATESTR := SUBSTR(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, '年月日’, ‘’), ‘[[:punct:]]’, ‘’), ’ ', ‘’), 1, 4) || ‘0’ ||
SUBSTR(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, '年月日’, ‘’), ‘[[:punct:]]’, ‘’), ’ ', ‘’), 5, 1) ||
SUBSTR(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, '年月日’, ‘’), ‘[[:punct:]]’, ‘’), ’ ', ‘’), 6, 2);
ELSIF LENGTH(TRIM(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, '年月日’, ‘’), ‘[[:punct:]]’, ‘’))) = 7
AND
INSTR(TRIM(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, '年月日’, ‘-’), ‘[[:punct:]]’, ‘-’)), ‘-’, 2) -
INSTR(TRIM(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, '年月日’, ‘-’), ‘[[:punct:]]’, ‘-’)), ‘-’, 1) = 2
THEN
V2_DATESTR := SUBSTR(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, '年月日’, ‘’), ‘[[:punct:]]’, ‘’), ’ ', ‘’), 1, 4) ||
SUBSTR(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, '年月日’, ‘’), ‘[[:punct:]]’, ‘’), ’ ', ‘’), 5, 2) || ‘0’ ||
SUBSTR(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(V_DATESTR, '年月日’, ‘’), ‘[[:punct:]]*’, ‘’), ’ ', ‘’), 6, 1);
END IF;
– 截取出年份
I_YEAR := TO_NUMBER(SUBSTR(V2_DATESTR, 1, 4));
– 截取出月份
I_MONTH := TO_NUMBER(SUBSTR(V2_DATESTR, 5, 2));
– 截取出日期
I_DAY := TO_NUMBER(SUBSTR(V2_DATESTR, 7, 2));
– 对月份进行判断,必须在1月到12月范围之内
IF I_MONTH NOT BETWEEN 1 AND 12
THEN
BEGIN
RETURN 0;
END;
END IF;
– 对日期的判断,1,3,5,7,8,10,12月最大日为31,4,6,9,11月最大日为30,2月若为闰年则为29,其它年则为28.
IF I_DAY BETWEEN 1 AND 31
THEN
BEGIN
IF I_DAY = 31
AND I_MONTH NOT IN (1, 3, 5, 7, 8, 10, 12)
THEN
BEGIN
RETURN 0;
END;
END IF;
IF I_MONTH = 2
THEN
BEGIN
– RULES 1:普通年能被4整除且不能被100整除的为闰年。
– RULES 2:世纪年能被400整除的是闰年。
– RULES 3:对于数值很大的年份,这年如果能整除3200,并且能整除172800则是闰年。如172800年是闰年,86400年不是闰年。
IF ((MOD(I_YEAR, 4) = 0 AND MOD(I_YEAR, 100) <> 0) OR
MOD(I_YEAR, 400) = 0 OR
(MOD(I_YEAR, 3200) = 0 AND MOD(I_YEAR, 172800) = 0))
THEN
BEGIN
–若为闰年,则2月份最大日为29
IF I_DAY > 29
THEN
BEGIN
RETURN 0;
END;
END IF;
END;
ELSE
BEGIN
–若不为闰年,则2月份最大日为28
IF I_DAY > 28
THEN
BEGIN
RETURN 0;
END;
END IF;
END;
END IF;
END;
END IF;
RETURN 1;
END;
ELSE
RETURN 0;
END IF;
END;