ORA-01848: 年中的第几天必须介于 1 和 365 之间(闰年为 366)错误
ORA-01848: day of year must be between 1 and 365 (366 for leap year) error
我有以 DDD 格式存储的一年中的第几天 (1-366) 的现有数据。
现在,当我尝试查询数据并以 MM/DD/YYYY 格式提取报告时,我得到
ORA-01848: day of year must be between 1 and 365 (366 for leap year)
用于以下查询
select to_CHAR(TO_DATE(MyColumn, 'DDD'),'MM/DD/YYYY') from MyTable;
闰年时如何获取MM/DD/YYYY格式的日期?
您当前的查询:
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 的值并坚持使用当前年份,但同样您可能会得到 unrealistic/unhelpful 转换后的日期。或者您可以使用 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
我创建了一个逻辑,可以根据输入的日期计算日期。当它不是闰年时,它会显示日期。如果是闰年,如果天数是 366
,它会显示最后一天。如果不是闰年,如果天数是 366
,它会显示该年的最后一天,因此它永远不会导致您遇到的错误。
with tb(col1) as (Select level
from dual
connect by level < 367)
-- Actual Query ..Col1 is the day number being passed.
Select Case when col1 < 366 then
to_char(TO_DATE(col1, 'DDD'),'MM/DD/YYYY')
else
to_char(LAST_DAY(ADD_MONTHS(TRUNC(SYSDATE , 'Year'),11)),'MM/DD/YYYY')
end col
from tb ;
我有以 DDD 格式存储的一年中的第几天 (1-366) 的现有数据。
现在,当我尝试查询数据并以 MM/DD/YYYY 格式提取报告时,我得到
ORA-01848: day of year must be between 1 and 365 (366 for leap year)
用于以下查询
select to_CHAR(TO_DATE(MyColumn, 'DDD'),'MM/DD/YYYY') from MyTable;
闰年时如何获取MM/DD/YYYY格式的日期?
您当前的查询:
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 的值并坚持使用当前年份,但同样您可能会得到 unrealistic/unhelpful 转换后的日期。或者您可以使用 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
我创建了一个逻辑,可以根据输入的日期计算日期。当它不是闰年时,它会显示日期。如果是闰年,如果天数是 366
,它会显示最后一天。如果不是闰年,如果天数是 366
,它会显示该年的最后一天,因此它永远不会导致您遇到的错误。
with tb(col1) as (Select level
from dual
connect by level < 367)
-- Actual Query ..Col1 is the day number being passed.
Select Case when col1 < 366 then
to_char(TO_DATE(col1, 'DDD'),'MM/DD/YYYY')
else
to_char(LAST_DAY(ADD_MONTHS(TRUNC(SYSDATE , 'Year'),11)),'MM/DD/YYYY')
end col
from tb ;