Ваш текущий запрос:
select to_CHAR(TO_DATE(MyColumn, 'DDD'),'MM/DD/YYYY') from MyTable;
по умолчанию используется текущий год. Все преобразованные значения будут показывать 2018 год:
-- CTE for dummy values (<= 365)
with mytable(mycolumn) as (
select 1 from dual
union all select 60 from dual
union all select 365 from dual
)
select to_CHAR(TO_DATE(MyColumn, 'DDD'),'MM/DD/YYYY') from MyTable;
TO_CHAR(TO
----------
01/01/2018
03/01/2018
12/31/2018
Поскольку 2018 год не високосный, 366-й день недействителен. Вы можете заставить его использовать произвольный жестко закодированный високосный год:
select to_CHAR(TO_DATE('2000' || MyColumn, 'YYYYDDD'),'MM/DD/YYYY') from MyTable;
Демо:
-- CTE for dummy values
with mytable(mycolumn) as (
select 1 from dual
union all select 60 from dual
union all select 365 from dual
union all select 366 from dual
)
select to_CHAR(TO_DATE('2000' || MyColumn, 'YYYYDDD'),'MM/DD/YYYY') from MyTable;
TO_CHAR(TO
----------
01/01/2000
02/29/2000
12/30/2000
12/31/2000
Но если исходная дата не была из високосного года, тогда значения будут отсутствовать на день, а также, конечно, отображаться против неправильного года.
Вы можете отфильтровать значения со значениями> 365 и придерживаться текущего года, но опять же вы, вероятно, получите нереалистичные/бесполезные преобразованные даты. Или вы можете использовать синтаксис 12c default ... on conversion error
, чтобы получить, скажем, нулевой результат, когда он не будет преобразован, но опять же другие даты будут несовместимы.
Если вы не знаете год, который представляет каждое значение DDD
, вы не сможете получить точную конверсию.
Если у вас есть другой столбец, содержащий год, соедините их вместе, например. если этот столбец года называется MyYear
:
select to_CHAR(TO_DATE(MyYear || MyColumn, 'YYYYDDD'),'MM/DD/YYYY') from MyTable;
Демонстрация, показывающая различные результаты:
-- CTE for dummy values
with mytable(mycolumn, myyear) as (
select 1, 2018 from dual
union all select 60, 2016 from dual
union all select 60, 2017 from dual
union all select 365, 2016 from dual
union all select 366, 2016 from dual
union all select 365, 2017 from dual
)
select MyColumn, MyYear,
to_CHAR(TO_DATE(MyColumn default null on conversion error, 'DDD'),'MM/DD/YYYY') as Y2018,
to_CHAR(TO_DATE('2000' || MyColumn, 'YYYYDDD'),'MM/DD/YYYY') as Y2000,
to_CHAR(TO_DATE(MyYear || MyColumn, 'YYYYDDD'),'MM/DD/YYYY') as OK
from MyTable;
MYCOLUMN MYYEAR Y2018 Y2000 OK
---------- ---------- ---------- ---------- ----------
1 2018 01/01/2018 01/01/2000 01/01/2018
60 2016 03/01/2018 02/29/2000 02/29/2016
60 2017 03/01/2018 02/29/2000 03/01/2017
365 2016 12/31/2018 12/30/2000 12/30/2016
366 2016 12/31/2000 12/31/2016
365 2017 12/31/2018 12/30/2000 12/31/2017
person
Alex Poole
schedule
17.01.2018