Reputation: 1010
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
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
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
Reputation: 167962
If you are using the ISO standard for weeks then you can do:
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
| 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