zoukankan      html  css  js  c++  java
  • [转] SQL日期函数dayadd/datediff/datepart

      1 函数一:
      2 
      3 CREATE OR REPLACE FUNCTION dayadd(p_Component varchar2,
      4                                   p_Number    number,
      5                                   p_Date      date) RETURN DATE IS
      6   /****************************************************************/
      7   /*      该函数为日期计算函数主要是计算〕                              */
      8   /*     从当前日期开始经过多少日、季、月、年等后的日期。                 */
      9   /*     入参说明:p_Component         时间元件,如年月日季度等等       */
     10   /*                 p_Number        加数, 注意:应该为整数(可正可负) */
     11   /*                 p_Date                基准时间                */
     12   /*  注意:其他日期元件,如世纪等等,暂时未考虑                         */
     13   /***************************************************************/
     14  
     15   v_Component       varchar2(10);
     16   v_MiddleNumber    number;
     17   v_ReturnValue_Str varchar2(20); --字符串日期格式
     18   v_ReturnValue     date; --返回日期
     19  
     20 BEGIN
     21   v_Component := upper(ltrim(rtrim(p_Component)));
     22   if v_Component in ('Y', 'YY', 'YEAR', 'YYYY') then
     23     --年情况
     24     v_ReturnValue := add_months(p_Date, p_Number * 12);
     25   elsif v_Component in ('M', 'MM', 'MONTH', 'MON') then
     26     --月情况
     27     v_ReturnValue := add_months(p_Date, p_Number);
     28   elsif v_Component in ('D', 'DD', 'DAY') then
     29     --日情况
     30     v_ReturnValue := p_Date + p_Number;
     31   elsif v_Component in ('H', 'HH', 'HOUR') then
     32     --时情况
     33     v_ReturnValue := p_Date + p_Number / 24;
     34   elsif v_Component in ('MI', 'MINUTE') then
     35     --分情况
     36     v_ReturnValue := p_Date + p_Number / 1440;
     37   elsif v_Component in ('S', 'SS', 'SECOND') then
     38     --秒情况
     39     v_ReturnValue := p_Date + p_Number / 86400;
     40   elsif v_Component in ('Q', 'QQ', 'QUARTER') then
     41     --季度情况
     42     v_ReturnValue := p_Date + p_Number * 3;
     43   elsif v_Component in ('W', 'WW', 'WK', 'WEEK') then
     44     --周情况
     45     v_ReturnValue := p_Date + p_Number * 7;
     46   else
     47     v_ReturnValue := to_date('1-1-1', 'yyyy-mm-dd');
     48   end if;
     49   RETURN v_ReturnValue;
     50 EXCEPTION
     51   WHEN OTHERS THEN
     52     RETURN to_date('1-1-1', 'yyyy-mm-dd'); --例外处理
     53  
     54 END;
     55  
     56  
     57 
     58 函数二:
     59 
     60  
     61 
     62 create or replace function datediff(p_Component   varchar2,
     63                                     p_Subtranhend date,
     64                                     p_Minuend     date) RETURN NUMBER IS
     65   /*************************************************************************/
     66   /*      功    能:返回两个日期之间的天、周、月、年等数量。               */
     67   /*      入参说明: p_Component    时间元件,如年月日季度等等             */
     68   /*                 p_Subtrahend   减数时间                               */
     69   /*                 p_Minuend     被减数时间                              */
     70   /*************************************************************************/
     71  
     72   v_ReturnValue   number; -- 结果数值
     73   v_Component     varchar2(10); --日期组件中间转换形式,截取空格并且转为大写
     74   v_YearNum1      number; --减数年份数
     75   v_YearNum2      number; --被减数年份数
     76   v_MonthNum1     number; --减数月份数
     77   v_MonthNum2     number; --被减数月份数
     78   v_HourNum1      number; --减数时数
     79   v_HourNum2      number; --被减数时数
     80   v_MinuteNum1    number; --减数分钟数
     81   v_MinuteNum2    number; --被减数分钟数
     82   v_SecondNum1    number; --减数秒钟数
     83   v_SecondNum2    number; --减数秒钟数
     84   v_QuarterValue1 number; --减数季度数
     85   v_QuarterValue2 number; --被减数季度数
     86   v_WeekNum1      number; --减数与标准时间周差
     87   v_WeekNum2      number; --被减数与标准时间周差
     88 BEGIN
     89   v_Component := upper(ltrim(rtrim(p_Component)));
     90   if v_Component in ('Y', 'YY', 'YEAR', 'YYYY') then
     91     --年情况 
     92     v_YearNum1    := to_number(to_char(p_Subtranhend, 'YYYY'));
     93     v_YearNum2    := to_number(to_char(p_Minuend, 'YYYY'));
     94     v_ReturnValue := v_YearNum2 - v_YearNum1;
     95   elsif v_Component in ('M', 'MM', 'MONTH', 'MON') then
     96     --月情况
     97     --请注意,这个部分与Oracle内置日期函数MONTH_BETWEEN()不同,忽略了日因素
     98     --而后者的两个日期如都是所在月的最后一天,才返回整数,否则,返回分数
     99     --而且这个分数是以31天作为一个月进行计算的结果
    100     v_YearNum1    := to_number(to_char(p_Subtranhend, 'YYYY'));
    101     v_YearNum2    := to_number(to_char(p_Minuend, 'YYYY'));
    102     v_MonthNum1   := to_number(to_char(p_Subtranhend, 'MM'));
    103     v_MonthNum2   := to_number(to_char(p_Minuend, 'MM'));
    104     v_ReturnValue := (v_YearNum2 - v_YearNum1) * 12 +
    105                      (v_MonthNum2 - v_MonthNum1);
    106   elsif v_Component in ('D', 'DD', 'DAY') then
    107     --日情况
    108     --这里与两个日期直接相减的oracle日期算术也不同,只返回整数天数;
    109     --而后者可以返回一天的几分之几(以小数形式表达)
    110     v_ReturnValue := to_date(to_char(p_Minuend, 'yyyy-mm-dd'), 'YYYY-MM-DD') -
    111                      to_date(to_char(p_Subtranhend, 'yyyy-mm-dd'),
    112                              'YYYY-MM-DD');
    113   elsif v_Component in ('H', 'HH', 'HOUR') then
    114     --时情况
    115     --第一步:求出天数
    116     v_ReturnValue := (to_date(to_char(p_Minuend, 'yyyy-mm-dd'),
    117                               'YYYY-MM-DD') -
    118                      to_date(to_char(p_Subtranhend, 'yyyy-mm-dd'),
    119                               'YYYY-MM-DD'));
    120     --第二步:求出时数
    121     v_HourNum1    := to_number(to_char(p_Subtranhend, 'HH24'));
    122     v_HourNum2    := to_number(to_char(p_Minuend, 'HH24'));
    123     v_ReturnValue := v_ReturnValue * 24 + (v_HourNum2 - v_HourNum1);
    124   elsif v_Component in ('MI', 'MINUTE') then
    125     --分情况
    126     --第一步:求出天数
    127     v_ReturnValue := (to_date(to_char(p_Minuend, 'yyyy-mm-dd'),
    128                               'YYYY-MM-DD') -
    129                      to_date(to_char(p_Subtranhend, 'yyyy-mm-dd'),
    130                               'YYYY-MM-DD'));
    131     --第二步:求出时数
    132     v_HourNum1    := to_number(to_char(p_Subtranhend, 'HH24'));
    133     v_HourNum2    := to_number(to_char(p_Minuend, 'HH24'));
    134     v_ReturnValue := v_ReturnValue * 24 + (v_HourNum2 - v_HourNum1);
    135     --第三步:求出分钟数
    136     v_MinuteNum1  := to_number(to_char(p_Subtranhend, 'MI'));
    137     v_MinuteNum2  := to_number(to_char(p_Minuend, 'MI'));
    138     v_ReturnValue := v_ReturnValue * 60 + (v_MinuteNum2 - v_MinuteNum1);
    139   elsif v_Component in ('S', 'SS', 'SECOND') then
    140     --秒情况
    141     --第一步:求出天数
    142     v_ReturnValue := (to_date(to_char(p_Minuend, 'yyyy-mm-dd'),
    143                               'YYYY-MM-DD') -
    144                      to_date(to_char(p_Subtranhend, 'yyyy-mm-dd'),
    145                               'YYYY-MM-DD'));
    146     --第二步:求出时数
    147     v_HourNum1    := to_number(to_char(p_Subtranhend, 'HH24'));
    148     v_HourNum2    := to_number(to_char(p_Minuend, 'HH24'));
    149     v_ReturnValue := v_ReturnValue * 24 + (v_HourNum2 - v_HourNum1);
    150     --第三步:求出分钟数
    151     v_MinuteNum1  := to_number(to_char(p_Subtranhend, 'MI'));
    152     v_MinuteNum2  := to_number(to_char(p_Minuend, 'MI'));
    153     v_ReturnValue := v_ReturnValue * 60 + (v_MinuteNum2 - v_MinuteNum1);
    154     --第四步:求出秒钟数
    155     v_SecondNum1  := to_number(to_char(p_Subtranhend, 'SS'));
    156     v_SecondNum2  := to_number(to_char(p_Minuend, 'SS'));
    157     v_ReturnValue := v_ReturnValue * 60 + (v_SecondNum2 - v_SecondNum1);
    158   elsif v_Component in ('Q', 'QQ', 'QUARTER') then
    159     --季度情况
    160     v_YearNum1      := to_number(to_char(p_Subtranhend, 'YYYY'));
    161     v_YearNum2      := to_number(to_char(p_Minuend, 'YYYY'));
    162     v_QuarterValue1 := to_number(to_char(p_Subtranhend, 'Q'));
    163     v_QuarterValue2 := to_number(to_char(p_Minuend, 'Q'));
    164     v_ReturnValue   := (v_YearNum2 - v_YearNum1) * 4 +
    165                        (v_QuarterValue2 - v_QuarterValue1);
    166   elsif v_Component in ('W', 'WW', 'WK', 'WEEK') then
    167     --周情况
    168     --一周的起始日期应当为星期日
    169     --关于周差的计算,尝试采用中间日期的方法
    170     --经查,‘1-1-2’即公元一年1月2日为周日,我们就可以用两个时间分别与其相减求周差
    171     --两个结果再相减,即可得到正确的数值
    172     v_WeekNum1    := floor((to_date(to_char(p_Subtranhend, 'YYYY-MM-DD'),
    173                                     'YYYY-MM-DD') -
    174                            to_date('1-1-2', 'YYYY-MM-DD')) / 7);
    175     v_WeekNum2    := floor((to_date(to_char(p_Minuend, 'YYYY-MM-DD'),
    176                                     'YYYY-MM-DD') -
    177                            to_date('1-1-2', 'YYYY-MM-DD')) / 7);
    178     v_ReturnValue := v_WeekNum2 - v_WeekNum1;
    179   else
    180     v_ReturnValue := -88888;
    181   end if;
    182   RETURN v_ReturnValue;
    183 EXCEPTION
    184   WHEN OTHERS THEN
    185     RETURN - 99999; --例外处理
    186 END datediff;
    187  
    188 函数三:
    189 
    190  
    191 
    192 create or replace function datepart(p_Component varchar2, p_Date date)
    193   RETURN NUMBER IS
    194   /*************************************************************************/
    195   /*       功   能:获取某个日期中的部分时间元件(日、月、年、分、秒、等) */
    196   /*       入参说明:        p_Component 时间元件,如年月日季度等等        */
    197   /*                          p_Date            需要解析的时间             */
    198   /*************************************************************************/
    199   v_Component   varchar2(10);
    200   v_ReturnValue NUMBER;
    201 BEGIN
    202   v_Component := upper(ltrim(rtrim(p_Component)));
    203   if v_Component in ('Y', 'YY', 'YEAR', 'YYYY') then
    204     --年情况
    205     v_ReturnValue := to_number(to_char(p_Date, 'YYYY'));
    206   elsif v_Component in ('M', 'MM', 'MONTH', 'MON') then
    207     --月情况
    208     v_ReturnValue := to_number(to_char(p_Date, 'MM'));
    209   elsif v_Component in ('D', 'DD', 'DAY') then
    210     --日情况
    211     v_ReturnValue := to_number(to_char(p_Date, 'DD'));
    212   elsif v_Component in ('H', 'HH', 'HOUR', 'HH24') then
    213     --时情况
    214     v_ReturnValue := to_number(to_char(p_Date, 'HH24'));
    215   elsif v_Component in ('MI', 'MINUTE') then
    216     --分情况
    217     v_ReturnValue := to_number(to_char(p_Date, 'MI'));
    218   elsif v_Component in ('S', 'SS', 'SECOND') then
    219     --秒情况
    220     v_ReturnValue := to_number(to_char(p_Date, 'SS'));
    221   elsif v_Component in ('Q', 'QQ', 'QUARTER') then
    222     --季度情况
    223     v_ReturnValue := to_number(to_char(p_Date, 'Q'));
    224   elsif v_Component in ('W', 'WW', 'WK', 'WEEK') then
    225     --周几情况(周日为第一天)
    226     v_ReturnValue := to_number(to_char(p_Date, 'D'));
    227   elsif v_Component in ('WEEK_NO') then
    228     -- 第几周情况
    229     v_ReturnValue := to_number(to_char(p_Date, 'IW'));
    230   else
    231     v_ReturnValue := -88888;
    232   end if;
    233  
    234   RETURN v_ReturnValue;
    235 EXCEPTION
    236   WHEN OTHERS THEN
    237     RETURN - 99999; --例外处理
    238  
    239 END datepart;
  • 相关阅读:
    微信公众号Markdown编辑器, 适合代码排版
    Java8-如何构建一个Stream
    Java8-Stream之数值流
    Java8学习(4)-Stream流
    Dubbo学习1-Hello world
    深入理解JVM垃圾收集机制(JDK1.8)
    持久层框架JPA与Mybatis该如何选型
    淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log Server.鏈嶅姟鍣
    Apache Tomcat下载、安装、配置图文教程
    IIS8.0 配置应用程序初始化功能
  • 原文地址:https://www.cnblogs.com/yuan1164345228/p/6044185.html
Copyright © 2011-2022 走看看