将周日期转换为日历日期

时间:2015-10-12 08:51:50

标签: oracle plsql

我的格式为日期列:

year/number_of_week_in_year/number_of_day_of_the_week, for example:

2015015 = 01.01.2015

如何编写将此日期转换为RRRRmmdd格式的查询?

我使用Oracle 10g。

3 个答案:

答案 0 :(得分:2)

如果您使用ISO标准数周,那么您可以:

SQL Fiddle

Oracle 11g R2架构设置

CREATE FUNCTION TO_ISO_WEEK_DATE(
  year      NUMBER,
  week      NUMBER,
  dayofweek NUMBER DEFAULT 1
) RETURN DATE DETERMINISTIC
IS
BEGIN
  RETURN NEXT_DAY(
          TO_DATE( TO_CHAR( year, '0000' ) || '0104', 'YYYYMMDD' )
            - INTERVAL '7' DAY, 'MONDAY'
         )
         + ( week - 1 ) * 7
         + ( dayofweek - 1 );
EXCEPTION
  WHEN OTHERS THEN
    RETURN NULL;
END TO_ISO_WEEK_DATE;
/

查询1

WITH dates (value ) AS (
  SELECT DATE '2015-01-01' + LEVEL - 1
  FROM   DUAL
  CONNECT BY LEVEL < 366
),
data ( value, iso_week_day ) AS (
  SELECT value,
         TO_CHAR( value, 'IYYY/IW/' ) || TO_CHAR( value - TRUNC( value, 'IW' ) + 1 )
  FROM   dates
)
SELECT value,
       iso_week_day,
       TO_ISO_WEEK_DATE(
         SUBSTR( iso_week_day, 1, 4 ),
         SUBSTR( iso_week_day, 6, 2 ),
         SUBSTR( iso_week_day, 9, 1 )
       ) AS CONVERTED_DATE
FROM data

<强> Results

|                       VALUE | ISO_WEEK_DAY |              CONVERTED_DATE |
|-----------------------------|--------------|-----------------------------|
|   January, 01 2015 00:00:00 |    2015/01/4 |   January, 01 2015 00:00:00 |
|   January, 02 2015 00:00:00 |    2015/01/5 |   January, 02 2015 00:00:00 |
|   January, 03 2015 00:00:00 |    2015/01/6 |   January, 03 2015 00:00:00 |
|   January, 04 2015 00:00:00 |    2015/01/7 |   January, 04 2015 00:00:00 |
|   January, 05 2015 00:00:00 |    2015/02/1 |   January, 05 2015 00:00:00 |
   ...
|    August, 23 2015 00:00:00 |    2015/34/7 |    August, 23 2015 00:00:00 |
   ...
|  December, 30 2015 00:00:00 |    2015/53/3 |  December, 30 2015 00:00:00 |
|  December, 31 2015 00:00:00 |    2015/53/4 |  December, 31 2015 00:00:00 |

答案 1 :(得分:1)

如果我理解你的话,这就是你想要的:

SELECT TO_CHAR(NEXT_DAY(
NEXT_DAY( to_date('01.01.'||SUBSTR('2015015',1,4),'dd.mm.yyyy')-7,1) +      
(SUBSTR('2015015',5,2)-1)*7,TO_NUMBER(SUBSTR('2015015',7,1))),'rrrrmmdd')
FROM dual;

答案 2 :(得分:1)

如果您尝试撤消Oracle的yyyywwd格式掩码,下面的代码可能会有用。但是 - 它不是通用的,取决于您的NLS设置(天的名称以及哪一天被视为一周的第一天SUN / MON)。

但奇怪的是,to_date()不接受'ww'作为格式。

select dt,
       dt_ywd,
       next_day(to_date(substr(dt_ywd,1,4)||'0101','yyyymmdd') +
                  7*(to_number(substr(dt_ywd,5,2))-1) -
                  1,
                decode(substr(dt_ywd,7,1),'1','SUN',
                                          '2','MON',
                                          '3','TUE',
                                          '4','WED',
                                          '5','THU',
                                          '6','FRI',
                                          '7','SAT')) tst_revert
  from(select dt, 
              to_char(dt,'yyyywwd') dt_ywd
         from (select to_date('01/01/2015','dd/mm/yyyy')+level-1 dt
                 from dual
              connect by level < 500))

这给了我以下输出:

DT          DT_YWD  TST_REVERT
----------- ------- -----------
01/01/2015  2015015 01/01/2015
02/01/2015  2015016 02/01/2015
03/01/2015  2015017 03/01/2015
04/01/2015  2015011 04/01/2015
05/01/2015  2015012 05/01/2015
06/01/2015  2015013 06/01/2015
07/01/2015  2015014 07/01/2015
08/01/2015  2015025 08/01/2015
09/01/2015  2015026 09/01/2015
10/01/2015  2015027 10/01/2015