Это происходит из-за неявного преобразования даты - при условии, что date_created
на самом деле является DATE
столбцом, а не строкой. Если в настройках NLS отображаются даты с двузначными годами, например формат по умолчанию 'DD-Mon-RR'
, преобразование значения даты в строку и обратно теряет столетие. В качестве демонстрации укажите значение даты через CTE:
alter session set nls_date_format = 'DD-Mon-RR';
with your_table (date_created) as (
select date '2019-01-07' from dual
)
select
to_char(date_created) as nls_date,
to_char(date_created, 'YYYY-MM-DD') as iso_date,
to_char(to_date(to_char(date_created), 'DD/MM/YYYY'), 'YYYY-MM-DD') as conv_date,
to_number(to_char(to_date(date_created,'DD/MM/YYYY'),'IW')) as WEEK_PRODUCED
from your_table;
NLS_DATE ISO_DATE CONV_DATE WEEK_PRODUCED
--------- ---------- ---------- -------------
07-Jan-19 2019-01-07 0019-01-07 1
Обратите внимание, что conv_date
, который был преобразован в строку с использованием двухзначной модели года NLS, а затем обратно к дате с использованием четырехзначной модели года, потерял свой век; с литералами ты выглядишь так же:
select to_char(to_date('01/07/19', 'DD/MM/YYYY'), 'YYYY-MM-DD') from dual;
TO_CHAR(TO
----------
0019-07-01
потому что 19 год, ну 19 год; здесь нет ни намека, ни механизма, чтобы предположить, что вы имели в виду этот век. (Вот для чего нужна модель формата RRRR
.)
Итак, вы получаете номер недели ISO для 7 января 19 года, а не 2019 года, и в этом году это была неделя 1 ISO.
Если бы ваша сессия имела четырехзначную модель года, она бы работала:
alter session set nls_date_format = 'DD/MM/YYYY';
with your_table (date_created) as (
select date '2019-01-07' from dual
)
select
to_char(date_created) as nls_date,
to_char(date_created, 'YYYY-MM-DD') as iso_date,
to_char(to_date(to_char(date_created), 'DD/MM/YYYY'), 'YYYY-MM-DD') as conv_date,
to_number(to_char(to_date(date_created,'DD/MM/YYYY'),'IW')) as WEEK_PRODUCED
from your_table;
NLS_DATE ISO_DATE CONV_DATE WEEK_PRODUCED
---------- ---------- ---------- -------------
07/01/2019 2019-01-07 2019-01-07 2
Неявно сгенерированная строка теперь имеет четырехзначный год, поэтому преобразование ее обратно сохраняет первоначальный век. (Конечно, у вас все еще будут проблемы с датами BCE ...)
Но вы вообще не должны конвертировать исходную дату. Просто сделай:
to_number(to_char(date_created,'IW')) as WEEK_PRODUCED
как и в том же CTE:
with your_table (date_created) as (
select date '2019-01-07' from dual
)
select
to_number(to_char(date_created,'IW')) as WEEK_PRODUCED
from your_table;
WEEK_PRODUCED
-------------
2
, который будет работать независимо от ваших настроек NLS, так как больше не будет никакого неявного преобразования.