Oracle中有两种周号:
TO_CHAR(sysdate, 'ww'):以某年的1月1日作为第一周的星期一,以此类推。
TO_CHAR(sysdate, 'iw'):返回真实周号,但以星期一作为一周的第一天。按这种办法,有时1月1日被放在当年的最后一周。有时12月31日又被放在当年的第一周。现在客户要求以星期天作为一周的第一天,而且1月1日所在的周为第35周,以此类推到52或53周以后又变成第1、2、3……周。因此我编了一个函数,将Oracle里面的复杂周号转换成我们习惯上的真实周号(然后再在java程序里转换为客户需要的周号),即:以星期天作为一周的第一天,1月1日所在的周一定是当年的第一周;然后如果当年的最后一周不满七天,则转为下一年的第一周。说实话这个函数真不好写,昨天磨了一下午,测试再测试才弄出来。我想请问各位大侠:PLSQL中的周号转换是不是真的这么麻烦?大家碰上这种情况,是怎么处理的?谢谢!
附我写的函数:
CREATE OR REPLACE FUNCTION toweek(
d IN DATE, yformat IN NUMBER )
RETURN VARCHAR2 IS
v_yy VARCHAR2(6);
v_day NUMBER(1);
v_md VARCHAR2(4);
v_d1 DATE;
v_return VARCHAR(6);
v_year VARCHAR2(4);
BEGIN
IF yformat=4 THEN
v_yy := to_char(d, 'yyyy');
ELSE
v_yy := to_char(d, 'yy');
END IF;
v_md := to_char(d, 'mmdd');
v_year := to_char(d, 'yyyy');
v_d1 := to_date(v_year || '0101', 'yyyymmdd');
IF (to_char(v_d1,'d')='7') THEN
IF v_md='0101' THEN
v_return := v_yy || '01';
ELSE
v_return := v_yy || trim(to_char(to_number(to_char(d+1,'iw'))+1, '00'));
END IF;
ELSIF (to_char(v_d1,'d')='6') THEN
IF v_md='0101' OR v_md='0102' THEN
v_return := v_yy || '01';
ELSE
v_return := v_yy || trim(to_char(to_number(to_char(d+1,'iw'))+1, '00'));
END IF;
ELSE
v_return := v_yy || TO_char(d+1,'iw');
END IF;
v_day := to_number(to_char(to_date(v_year || '1231', 'yyyymmdd'),'d'));
IF (v_year != to_char(d+7,'yyyy') AND v_day < 7
AND to_number(to_char(d, 'd')) <= v_day) THEN
v_return := to_char(to_number(v_year)+1) || '01';
END IF;
RETURN v_return; END;测试:SQL> SELECT bweek(SYSDATE,4),bweek(SYSDATE,2) FROM dual
2 ;BWEEK(SYSDATE,4) BWEEK(SYSDATE,2)
----------------------------------
200546 0546
TO_CHAR(sysdate, 'ww'):以某年的1月1日作为第一周的星期一,以此类推。
TO_CHAR(sysdate, 'iw'):返回真实周号,但以星期一作为一周的第一天。按这种办法,有时1月1日被放在当年的最后一周。有时12月31日又被放在当年的第一周。现在客户要求以星期天作为一周的第一天,而且1月1日所在的周为第35周,以此类推到52或53周以后又变成第1、2、3……周。因此我编了一个函数,将Oracle里面的复杂周号转换成我们习惯上的真实周号(然后再在java程序里转换为客户需要的周号),即:以星期天作为一周的第一天,1月1日所在的周一定是当年的第一周;然后如果当年的最后一周不满七天,则转为下一年的第一周。说实话这个函数真不好写,昨天磨了一下午,测试再测试才弄出来。我想请问各位大侠:PLSQL中的周号转换是不是真的这么麻烦?大家碰上这种情况,是怎么处理的?谢谢!
附我写的函数:
CREATE OR REPLACE FUNCTION toweek(
d IN DATE, yformat IN NUMBER )
RETURN VARCHAR2 IS
v_yy VARCHAR2(6);
v_day NUMBER(1);
v_md VARCHAR2(4);
v_d1 DATE;
v_return VARCHAR(6);
v_year VARCHAR2(4);
BEGIN
IF yformat=4 THEN
v_yy := to_char(d, 'yyyy');
ELSE
v_yy := to_char(d, 'yy');
END IF;
v_md := to_char(d, 'mmdd');
v_year := to_char(d, 'yyyy');
v_d1 := to_date(v_year || '0101', 'yyyymmdd');
IF (to_char(v_d1,'d')='7') THEN
IF v_md='0101' THEN
v_return := v_yy || '01';
ELSE
v_return := v_yy || trim(to_char(to_number(to_char(d+1,'iw'))+1, '00'));
END IF;
ELSIF (to_char(v_d1,'d')='6') THEN
IF v_md='0101' OR v_md='0102' THEN
v_return := v_yy || '01';
ELSE
v_return := v_yy || trim(to_char(to_number(to_char(d+1,'iw'))+1, '00'));
END IF;
ELSE
v_return := v_yy || TO_char(d+1,'iw');
END IF;
v_day := to_number(to_char(to_date(v_year || '1231', 'yyyymmdd'),'d'));
IF (v_year != to_char(d+7,'yyyy') AND v_day < 7
AND to_number(to_char(d, 'd')) <= v_day) THEN
v_return := to_char(to_number(v_year)+1) || '01';
END IF;
RETURN v_return; END;测试:SQL> SELECT bweek(SYSDATE,4),bweek(SYSDATE,2) FROM dual
2 ;BWEEK(SYSDATE,4) BWEEK(SYSDATE,2)
----------------------------------
200546 0546
纠正:SQL> SELECT toweek(SYSDATE,4),toweek(SYSDATE,2) FROM dual
2 ;TOWEEK(SYSDATE,4) TOWEEK(SYSDATE,2)
----------------------------------
200546 0546
if d<v_d2-to_char(v_d2,'d')+1 then
当年的to_char(d+v_d1-1,'ww')周
else
第二年的第一周
end if
RETURN NUMBER IS
w_date date;
BEGIN
w_date := p_date + 1;
RETURN to_number(to_char(w_date,'IYYYIW'));
END date_to_yw;
/