比如我的数据中用某年某周表示时间段
现在我想用此获得那一周的确切时间(可以前后相差一周)
即:
1005表示2010年的第5周,可以大概为2010-2-1左右(允许误差7天左右)
0905表示2009年第5周,可以转换为2009-2-1左右(允许误差)另外类似于09,10这样可以在前面添加'20'来判断为2009和2010年,但是如果是99,应该判断为1999年,应该如何写代码?

解决方案 »

  1.   

    http://topic.csdn.net/u/20100721/21/26d708a6-8941-40b4-bd33-d8522f3cc805.html-- 这个函数,略加修改,就OK啦:---------在存储过程中,我需要得到每个月第三个星期的星期三,该怎么写?刚学oracle,好多不懂,帮帮忙详细点,谢谢!-- (你原来的意思,函数如下:) create or replace function week_day_asc(
    i_cdate date, 
    i_week number default 1,  -- 本月第几周
    i_day number default 1    -- 本月的星期几
    )
    return date
    as
      v_cdate date;
      v_week number;
    begin
      v_week := to_char(trunc(last_day(sysdate),'D'),'w');
      if i_week >0 and i_week <=5 and i_day>=0 and i_day<=7 then
        v_cdate := trunc(trunc(i_cdate,'mm')+7-i_day,'D')+i_week*7-7+i_day-1;    if trunc(i_cdate,'mm') <> trunc(v_cdate,'mm') then -- 跨月份啦
          v_cdate := null;
        end if;
      else
        v_cdate := null;
      end if;
      return v_cdate;
    end;
    /----------------------------------  测试  -------------------------------------------
    select t.id, t.cdate, 
           week_day_asc(t.cdate,1,1), -- 第一周的星期日(是第一周的第一天)
           to_char(week_day_asc(t.cdate,1,1),'w'), -- 查看用函数出来的结果是本月第几周
           to_char(week_day_asc(t.cdate,1,1),'Day') -- 查看用函数出来的结果是本月的星期几
    from t;select t.id, t.cdate, 
           week_day_asc(t.cdate,1,2), -- 第一周的星期一(是第一周的第二天)
           to_char(week_day_asc(t.cdate,1,2),'w'), -- 查看用函数出来的结果是本月第几周
           to_char(week_day_asc(t.cdate,1,2),'Day') -- 查看用函数出来的结果是本月的星期几
    from t;select t.id, t.cdate, 
           week_day_asc(t.cdate,1,3), -- 第一周的星期二(是第一周的第三天)
           to_char(week_day_asc(t.cdate,1,3),'w'), -- 查看用函数出来的结果是本月第几周
           to_char(week_day_asc(t.cdate,1,3),'Day') -- 查看用函数出来的结果是本月的星期几
    from t;select t.id, t.cdate, 
           week_day_asc(t.cdate,1,4), -- 第一周的星期三(是第一周的第四天)
           to_char(week_day_asc(t.cdate,1,4),'w'), -- 查看用函数出来的结果是本月第几周
           to_char(week_day_asc(t.cdate,1,4),'Day') -- 查看用函数出来的结果是本月的星期几
    from t;select t.id, t.cdate, 
           week_day_asc(t.cdate,1,5), -- 第一周的星期四(是第一周的第五天)
           to_char(week_day_asc(t.cdate,1,5),'w'), -- 查看用函数出来的结果是本月第几周
           to_char(week_day_asc(t.cdate,1,5),'Day') -- 查看用函数出来的结果是本月的星期几
    from t;select t.id, t.cdate, 
           week_day_asc(t.cdate,1,7), -- 第一周的星期六(是第一周的第七天)
           to_char(week_day_asc(t.cdate,1,7),'w'), -- 查看用函数出来的结果是本月第几周
           to_char(week_day_asc(t.cdate,1,7),'Day') -- 查看用函数出来的结果是本月的星期几
    from t;select t.id, t.cdate, 
           week_day_asc(t.cdate,3,4),               -- 第三周的星期三(是第三周的第四天)
           to_char(week_day_asc(t.cdate,3,4),'w'),  -- 查看用函数出来的结果是本月第几周
           to_char(week_day_asc(t.cdate,3,4),'Day') -- 查看用函数出来的结果是本月的星期几
    from t;select t.id, t.cdate, 
           week_day_asc(t.cdate,5,4),               -- 第五周的星期三(是第五周的第四天,由于有的月份天数不够,应该有很多空值)
           to_char(week_day_asc(t.cdate,5,4),'w'),  -- 查看用函数出来的结果是本月第几周
           to_char(week_day_asc(t.cdate,5,4),'Day') -- 查看用函数出来的结果是本月的星期几
    from t;
            ID CDATE               WEEK_DAY_ASC(T.CDAT TO TO_CHAR(WEEK_DAY_ASC(T.C
    ---------- ------------------- ------------------- -- ------------------------
             1 2010-01-01 00:00:00
             2 2010-02-01 00:00:00
             3 2010-03-01 00:00:00 2010-03-31 00:00:00 5  星期三
             4 2010-04-01 00:00:00
             5 2010-05-01 00:00:00
             6 2010-06-01 00:00:00 2010-06-30 00:00:00 5  星期三
             7 2010-07-01 00:00:00
             8 2010-08-01 00:00:00
             9 2010-09-01 00:00:00 2010-09-29 00:00:00 5  星期三
            10 2010-10-01 00:00:00
            11 2010-11-01 00:00:00
            12 2010-12-01 00:00:00 2010-12-29 00:00:00 5  星期三已选择12行。--///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////-- 我题目意思搞混了,比如这个月是7月,我要得到7月21号,就是这个月的倒数第2星期的星期三,
    -- 如果是8月,则是8月18号。如果是9月,则是9月22号。
    -- (你现在的意思,函数如下:)
    create or replace function week_day_desc(
    i_cdate date, 
    i_week number default 1, -- 本月的倒数第几周
    i_day number default 1   -- 本月的星期几
    )
    return date
    as
      v_cdate date;
      v_week number;
    begin
      v_week := to_char(trunc(last_day(sysdate),'D'),'w');
      if i_week >0 and i_week <=5 and i_day>=0 and i_day<=7 then
        v_cdate := trunc(last_day(i_cdate)-i_day,'D')-i_week*7+7+i_day-1;    if trunc(i_cdate,'mm') < trunc(v_cdate,'mm') then -- 跨月份啦
          v_cdate := v_cdate - 7;
        end if;    if trunc(i_cdate,'mm') > trunc(v_cdate,'mm') then -- 跨月份啦
          v_cdate := null;
        end if;  else
        v_cdate := null;
      end if;
      return v_cdate;
    end;
    /
      

  2.   

    嗯,是按"年"的"周",谢谢楼上!
    可不可以多提一个要求,因为我这些代码是要放在VBA中调用,好像用不起自定义函数吧?能不能只用Oracle自带的函数实现?允许偏差7天或许可以少考虑些东西?
      

  3.   

    create or replace function year_week_fnc2(i_year varchar2, i_week varchar2)
    return date
    is
      v_date varchar2(10);
      v_return date;
    begin
      v_return := null;  if is_number(i_year)=1 and is_number(i_week)=1  then -- 如果传来的两个参数都可以转换成数值型
        -- 一年最多:53周
        if length(i_year)=2 and i_week>=1 and i_week<=53 then -- 如果输入日期中 年份 只有两位
          v_date := i_year||'0101';
          v_return := to_date(v_date,'yymmdd');
          v_return := trunc(v_return+i_week*7-1,'WW');
        elsif length(i_year)=4 and i_week>=1 and i_week<=53 then  -- 如果输入日期中 年份 有四位
          v_date := i_year||'0101';
          v_return := to_date(v_date,'yyyymmdd');
          v_return := trunc(v_return+i_week*7-1,'WW');
        else
          v_return := null;
        end if;
      end if;  return v_return;
    end;
    /drop table t purge;create table t(cdate varchar2(6));insert into t(cdate) values('1005');
    insert into t(cdate) values('0905');commit;select year_week_fnc2(substr(cdate,1,2),substr(cdate,3,4))
     from t;
      

  4.   

    -- 如果你的日期字段 的年份 既存在两位的,又存在四位的,查询语句如下:insert into t(cdate) values('200805');
    commit;--  select substr(cdate,1,length(cdate)-2),substr(cdate,-2,2) from t;select year_week_fnc2(substr(cdate,1,length(cdate)-2),substr(cdate,-2,2))
     from t;scott@SZTYORA> select year_week_fnc2(substr(cdate,1,length(cdate)-2),substr(cdate,-2,2))
      2   from t;YEAR_WEEK_FNC2(SUBS
    -------------------
    2010-01-29 00:00:00
    2009-01-29 00:00:00
    2008-01-29 00:00:00已用时间:  00: 00: 00.00
      

  5.   


    -- VBA中应该可以用Oracle 自定义函数吧? 如果不能的话,我也无能为力啦!
      

  6.   

    -- 验证函数正确性:scott@SZTYORA> select cdate,
      year_week_fnc2(substr(cdate,1,length(cdate)-2),substr(cdate,-2,2)) as cdate, 
      to_char(year_week_fnc2(substr(cdate,1,length(cdate)-2),substr(cdate,-2,2)),'WW') as week
    from t;CDATE        CDATE               WEEK
    ------------ ------------------- ----
    1005         2010-01-29 00:00:00 05
    0905         2009-01-29 00:00:00 05
    200805       2008-01-29 00:00:00 05
      

  7.   

    嗯,我用VBA的时间比较久,Oracle和SQL我接触时间不久,不过根据我的理解似乎是不大好实现在VBA中用Oracle的自定义函数吧.
    不过真的非常感谢!我先看看思路,然后对于我的数据特殊看看能否变通一些.
    再次感谢!