函数一:
CREATE OR REPLACE FUNCTION dayadd(
p_Component varchar2,
p_Number number,
p_Date date)
RETURN DATE
IS
/****************************************************************/
/* 该函数为日期计算函数主要是计算〕 */
/* 从当前日期开始经过多少日、季、月、年等后的日期。 */
/* 入参说明:p_Component 时间元件,如年月日季度等等 */
/* p_Number 加数, 注意:应该为整数(可正可负) */
/* p_Date 基准时间 */
/* 注意:其他日期元件,如世纪等等,暂时未考虑 */
/****************************************************************/
v_Component varchar2(10);
v_MiddleNumber number;
v_ReturnValue_Str varchar2(20); --字符串日期格式
v_ReturnValue date; --返回日期
BEGIN
v_Component := upper(ltrim(rtrim(p_Component)));
if v_Component in ('Y','YY','YEAR','YYYY') then --年情况
v_ReturnValue := add_months(p_Date,p_Number*12);
elsif v_Component in ('M','MM','MONTH','MON') then --月情况
v_ReturnValue := add_months(p_Date,p_Number);
elsif v_Component in ( 'D', 'DD', 'DAY') then --日情况
v_ReturnValue := p_Date + p_Number;
elsif v_Component in ('H', 'HH', 'HOUR') then --时情况
v_ReturnValue := p_Date + p_Number/24;
elsif v_Component in ('MI','MINUTE') then --分情况
v_ReturnValue := p_Date + p_Number/1440;
elsif v_Component in('S', 'SS', 'SECOND') then --秒情况
v_ReturnValue := p_Date + p_Number/86400;
elsif v_Component in ('Q','QQ','QUARTER') then --季度情况
v_ReturnValue := p_Date + p_Number*3;
elsif v_Component in ('W','WW','WK','WEEK') then --周情况
v_ReturnValue := p_Date + p_Number*7;
else
v_ReturnValue := to_date('1-1-1','yyyy-mm-dd');
end if;
RETURN v_ReturnValue;
EXCEPTION
WHEN OTHERS THEN
RETURN to_date('1-1-1','yyyy-mm-dd'); --例外处理
END;
函数二:
create or replace function datediff
(p_Component varchar2 ,
p_Subtranhend date,
p_Minuend date)
RETURN NUMBER
IS
/*************************************************************************/
/* 功 能:返回两个日期之间的天、周、月、年等数量。 */
/* 入参说明: p_Component 时间元件,如年月日季度等等 */
/* p_Subtrahend 减数时间 */
/* p_Minuend 被减数时间 */
/*************************************************************************/
v_ReturnValue number ; -- 结果数值
v_Component varchar2(10); --日期组件中间转换形式,截取空格并且转为大写
v_YearNum1 number; --减数年份数
v_YearNum2 number; --被减数年份数
v_MonthNum1 number; --减数月份数
v_MonthNum2 number; --被减数月份数
v_HourNum1 number; --减数时数
v_HourNum2 number; --被减数时数
v_MinuteNum1 number; --减数分钟数
v_MinuteNum2 number; --被减数分钟数
v_SecondNum1 number; --减数秒钟数
v_SecondNum2 number; --减数秒钟数
v_QuarterValue1 number; --减数季度数
v_QuarterValue2 number; --被减数季度数
v_WeekNum1 number; --减数与标准时间周差
v_WeekNum2 number; --被减数与标准时间周差
BEGIN
v_Component := upper(ltrim(rtrim(p_Component)));
if v_Component in ('Y','YY','YEAR','YYYY') then --年情况
v_YearNum1 := to_number(to_char(p_Subtranhend,'YYYY'));
v_YearNum2 := to_number(to_char(p_Minuend,'YYYY')) ;
v_ReturnValue := v_YearNum2 - v_YearNum1;
elsif v_Component in ('M', 'MM','MONTH', 'MON') then --月情况
--请注意,这个部分与oracle内置日期函数MONTH_BETWEEN()不同,忽略了日因素
--而后者的两个日期如都是所在月的最后一天,才返回整数,否则,返回分数
--而且这个分数是以31天作为一个月进行计算的结果
v_YearNum1 := to_number(to_char(p_Subtranhend,'YYYY'));
v_YearNum2 := to_number(to_char(p_Minuend,'YYYY')) ;
v_MonthNum1 := to_number(to_char(p_Subtranhend,'MM'));
v_MonthNum2 := to_number(to_char(p_Minuend,'MM'));
v_ReturnValue := (v_YearNum2 - v_YearNum1)*12 + (v_MonthNum2 - v_MonthNum1);
elsif v_Component in ( 'D', 'DD', 'DAY') then --日情况
--这里与两个日期直接相减的oracle日期算术也不同,只返回整数天数;
--而后者可以返回一天的几分之几(以小数形式表达)
v_ReturnValue := to_date(to_char(p_Minuend,'yyyy-mm-dd'),'YYYY-MM-DD')
- to_date(to_char(p_Subtranhend,'yyyy-mm-dd'),'YYYY-MM-DD');
elsif v_Component in ('H', 'HH', 'HOUR') then --时情况
--第一步:求出天数
v_ReturnValue := (to_date(to_char(p_Minuend,'yyyy-mm-dd'),'YYYY-MM-DD')
- to_date(to_char(p_Subtranhend,'yyyy-mm-dd'), 'YYYY-MM-DD'));
--第二步:求出时数
v_HourNum1 := to_number(to_char(p_Subtranhend,'HH24'));
v_HourNum2 := to_number(to_char(p_Minuend,'HH24'));
v_ReturnValue := v_ReturnValue*24 + (v_HourNum2 - v_HourNum1);
elsif v_Component in ('MI','MINUTE') then --分情况
--第一步:求出天数
v_ReturnValue := (to_date(to_char(p_Minuend,'yyyy-mm-dd'),'YYYY-MM-DD')
- to_date(to_char(p_Subtranhend,'yyyy-mm-dd'), 'YYYY-MM-DD'));
--第二步:求出时数
v_HourNum1 := to_number(to_char(p_Subtranhend,'HH24'));
v_HourNum2 := to_number(to_char(p_Minuend,'HH24'));
v_ReturnValue := v_ReturnValue*24 + (v_HourNum2 - v_HourNum1);
--第三步:求出分钟数
v_MinuteNum1 := to_number(to_char(p_Subtranhend,'MI'));
v_MinuteNum2 := to_number(to_char(p_Minuend,'MI'));
v_ReturnValue := v_ReturnValue*60 + (v_MinuteNum2 - v_MinuteNum1);
elsif v_Component in('S', 'SS', 'SECOND') then --秒情况
--第一步:求出天数
v_ReturnValue := (to_date(to_char(p_Minuend,'yyyy-mm-dd'),'YYYY-MM-DD')
- to_date(to_char(p_Subtranhend,'yyyy-mm-dd'),
'YYYY-MM-DD'));
--第二步:求出时数
v_HourNum1 := to_number(to_char(p_Subtranhend,'HH24'));
v_HourNum2 := to_number(to_char(p_Minuend,'HH24'));
v_ReturnValue := v_ReturnValue*24 + (v_HourNum2 - v_HourNum1);
--第三步:求出分钟数
v_MinuteNum1 := to_number(to_char(p_Subtranhend,'MI'));
v_MinuteNum2 := to_number(to_char(p_Minuend,'MI'));
v_ReturnValue := v_ReturnValue*60 + (v_MinuteNum2 - v_MinuteNum1);
--第四步:求出秒钟数
v_SecondNum1 := to_number(to_char(p_Subtranhend,'SS'));
v_SecondNum2 := to_number(to_char(p_Minuend,'SS'));
v_ReturnValue := v_ReturnValue*60 + (v_SecondNum2 - v_SecondNum1);
elsif v_Component in ('Q','QQ','QUARTER') then --季度情况
v_YearNum1 := to_number(to_char(p_Subtranhend,'YYYY'));
v_YearNum2 := to_number(to_char(p_Minuend,'YYYY')) ;
v_QuarterValue1 := to_number(to_char(p_Subtranhend,'Q'));
v_QuarterValue2 := to_number(to_char(p_Minuend,'Q'));
v_ReturnValue := (v_YearNum2 - v_YearNum1)*4 + (v_QuarterValue2 - v_QuarterValue1);
elsif v_Component in ('W','WW','WK','WEEK') then --周情况
--一周的起始日期应当为星期日
--关于周差的计算,尝试采用中间日期的方法
--经查,‘1-1-2’即公元一年1月2日为周日,我们就可以用两个时间分别与其相减求周差
--两个结果再相减,即可得到正确的数值
v_WeekNum1 := floor( (to_date(to_char(p_Subtranhend,'YYYY-MM-DD'),'YYYY-MM-DD') -
to_date('1-1-2','YYYY-MM-DD'))/7);
v_WeekNum2 := floor( (to_date(to_char(p_Minuend,'YYYY-MM-DD'),'YYYY-MM-DD') -
to_date('1-1-2','YYYY-MM-DD'))/7);
v_ReturnValue := v_WeekNum2 - v_WeekNum1;
else
v_ReturnValue := -88888;
end if;
RETURN v_ReturnValue;
EXCEPTION
WHEN OTHERS THEN
RETURN -99999;--例外处理
END datediff;
函数三:
create or replace function datepart(
p_Component varchar2,
p_Date date)
RETURN NUMBER
IS
/*************************************************************************/
/* 功 能:获取某个日期中的部分时间元件(日、月、年、分、秒、等) */
/* 入参说明: p_Component 时间元件,如年月日季度等等 */
/* p_Date 需要解析的时间 */
/*************************************************************************/
v_Component varchar2(10);
v_ReturnValue NUMBER;
BEGIN
v_Component := upper(ltrim(rtrim(p_Component)));
if v_Component in ('Y','YY','YEAR','YYYY') then --年情况
v_ReturnValue := to_number(to_char(p_Date,'YYYY')) ;
elsif v_Component in ('M', 'MM','MONTH', 'MON') then --月情况
v_ReturnValue := to_number(to_char(p_Date,'MM')) ;
elsif v_Component in ( 'D', 'DD', 'DAY') then --日情况
v_ReturnValue := to_number(to_char(p_Date,'DD')) ;
elsif v_Component in ('H', 'HH', 'HOUR', 'HH24') then --时情况
v_ReturnValue := to_number(to_char(p_Date,'HH24')) ;
elsif v_Component in ('MI','MINUTE') then --分情况
v_ReturnValue := to_number(to_char(p_Date,'MI')) ;
elsif v_Component in('S', 'SS', 'SECOND') then --秒情况
v_ReturnValue := to_number(to_char(p_Date,'SS')) ;
elsif v_Component in ('Q','QQ','QUARTER') then --季度情况
v_ReturnValue := to_number(to_char(p_Date,'Q')) ;
elsif v_Component in ('W','WW','WK','WEEK') then --周几情况(周日为第一天)
v_ReturnValue := to_number(to_char(p_Date,'D')) ;
elsif v_Component in ('WEEK_NO') then -- 第几周情况
v_ReturnValue := to_number(to_char(p_Date,'IW')) ;
else
v_ReturnValue := -88888;
end if;
RETURN v_ReturnValue;
EXCEPTION
WHEN OTHERS THEN
RETURN -99999;--例外处理
END datepart;
http://tiantainanhai.blog.163.com/blog/static/3708591120107910261762/
[导入]Oracle常用函数:DateDiff()
/*
--功能:将字符串转为年月日格式,删除时分秒.
--来源:http://jorkin.reallydo.com/article.asp?id=529
--参数:
Datechar Varchar2
--Oracle9i测试通过
*/
Create Or Replace Function CDate(Datechar In Varchar2) Return Date Is
ReallyDo Date;
Begin
Select to_date(to_char(to_date(to_char(Datechar), 'YYYY-MM-DD HH24:MI:SS'),
'YYYY-MM-DD'),
'YYYY-MM-DD')
Into ReallyDo
From Dual;
Return(ReallyDo);
End CDate;
/*
--功能:将字符串转为年月日时分秒格式.
--来源:http://jorkin.reallydo.com/article.asp?id=529
--参数:
Datechar Varchar2
--Oracle9i测试通过
*/
Create Or Replace Function CDateTime(Datechar In Varchar2) Return Date Is
ReallyDo Date;
Begin
Select to_date(to_char(to_date(to_char(Datechar), 'YYYY-MM-DD HH24:MI:SS'),
'YYYY-MM-DD HH24:MI:SS'),
'YYYY-MM-DD HH24:MI:SS')
Into ReallyDo
From Dual;
Return(ReallyDo);
End CDateTime;
/*
--功能:类似MSSQL的日期比较函数
--来源:http://jorkin.reallydo.com/article.asp?id=529
--更新时间:20080721
--参数:
Datepart Varchar2 -- 比较年?月?日?
StartDate Varchar2 -- 起始日期
EndDate Varchar2 -- 结束日期
--Oracle9i测试通过
*/
Create Or Replace Function Datediff
(
Datepart In Varchar2,
StartDate In Varchar2,
EndDate In Varchar2
) Return Number Is
ReallyDo Numeric;
Begin
Select Case Upper(Datepart)
When 'YYYY' Then
Trunc(Extract(Year From CDate(EndDate)) -
Extract(Year From CDate(StartDate)))
When 'M' Then
Datediff('YYYY', StartDate, EndDate) * 12 +
(Extract(Month From CDate(EndDate)) -
Extract(Month From CDate(StartDate)))
When 'D' Then
Trunc(CDate(EndDate) - CDate(StartDate))
When 'H' Then
Datediff('D', StartDate, EndDate) * 24 +
(to_Number(to_char(CDateTime(EndDate), 'HH24')) -
to_Number(to_char(CDateTime(StartDate), 'HH24')))
When 'N' Then
Datediff('D', StartDate, EndDate) * 24 * 60 +
(to_Number(to_char(CDateTime(EndDate), 'MI')) -
to_Number(to_char(CDateTime(StartDate), 'MI')))
When 'S' Then
Datediff('D', StartDate, EndDate) * 24 * 60 * 60 +
(to_Number(to_char(CDateTime(EndDate), 'SS')) -
to_Number(to_char(CDateTime(StartDate), 'SS')))
Else
-29252888
End
Into ReallyDo
From Dual;
Return(ReallyDo);
End Datediff;
http://www.cnblogs.com/pboy2925/archive/2008/07/03/1248019.html