Kulis
Kulis

Reputation: 1010

Converting week date into calendar date

I have column with dates in format:

year/number_of_week_in_year/number_of_day_of_the_week, for example:

2015015 = 01.01.2015

How to write query which convert this date to RRRRmmdd format?

I use Oracle 10g.

Upvotes: 0

Views: 256

Answers (3)

Peter Alexeev
Peter Alexeev

Reputation: 218

In case you're trying to reverse Oracle's yyyywwd format mask, the code below might be of use. However - it is not universal and depends on your NLS settings (names for days and which day is considered first day of week SUN/MON).

It is strange though, that to_date() does not accept 'ww' as a format.

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))

This gives me the following output:

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

Upvotes: 1

Tatiana
Tatiana

Reputation: 1499

If I understand you right, this is what you want:

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;

Upvotes: 1

MT0
MT0

Reputation: 167962

If you are using the ISO standard for weeks then you can do:

SQL Fiddle

Oracle 11g R2 Schema Setup:

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;
/

Query 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 |

Upvotes: 2

Related Questions