Oracle - 使用to_date()从日期时间获取日期

时间:2015-11-10 15:28:27

标签: date datetime oracle10g to-date

我从XML文件获取XML日期/时间,并且需要以仅Date的数据类型加载它,因此我必须截断时间。

我想尝试这样的事情让Oracle做截断:

TO_DATE('2015-11-04 13:45:19.387-05:00','YYYY-MM-DD') 

我通过运行这个来验证这个失败:

SELECT TO_DATE('2015-11-04 13:45:19.387-05:00','YYYY-MM-DD') FROM DUAL 

抛出错误:ORA-01830:数据格式图片在转换整个字符串之前结束。

我正在尝试尽量减少对构建SQL语句的C#程序的更改。如果需要,我可以更改我的C#代码来生成:

TO_DATE('2015-11-04','YYYY-MM-DD') 

Oracle可以处理截断,还是我必须在程序中执行此操作?

2 个答案:

答案 0 :(得分:2)

如果您将信息存储在Oracle的DATE列中(接受日期和时间),则以下内容可帮助您了解需要执行的操作:

select to_timestamp_tz('2015-11-04 13:45:19.387-05:00','YYYY-MM-DD hh24:mi:ss.ff3tzh:tzm') tz, 
       to_date(to_char(to_timestamp_tz('2015-11-04 13:45:19.387-05:00','YYYY-MM-DD hh24:mi:ss.ff3tzh:tzm'), 'dd/mm/yyyy hh24:mi:ss'), 'dd/mm/yyyy hh24:mi:ss') tz_char_date,
       cast(to_timestamp_tz('2015-11-04 13:45:19.387-05:00','YYYY-MM-DD hh24:mi:ss.ff3tzh:tzm') as date) tz_cast_date
from   dual;

TZ                                       TZ_CHAR_DATE             TZ_CAST_DATE              
---------------------------------------- ------------------- ---------------------
04/11/2015 13:45:19.387000000 -05:00     04/11/2015 13:45:19 2015-11-04 13:45:19  

另一种方法是使用substr来缩短字符串以获得您感兴趣的部分:

select to_date(substr('2015-11-04 13:45:19.387-05:00', 1, 19), 'yyyy-mm-dd hh24:mi:ss') substr_date
from   dual;

SUBSTR_DATE          
---------------------
2015-11-04 13:45:19  

答案 1 :(得分:2)

您可以使用the to_timestamp_tz() function将字符串从XML转换为带有时区值的时间戳:

SELECT TO_TIMESTAMP_TZ('2015-11-04 13:45:19.387-05:00','YYYY-MM-DD HH24:MI:SS.FFTZH:TZM')
FROM DUAL;

TO_TIMESTAMP_TZ('2015-11-0413:45:19.387-05:00','YYYY-MM-DDHH24:MI:SS.FFTZH:TZM')
--------------------------------------------------------------------------------
04-NOV-15 13.45.19.387000000 -05:00                                             

然后,您可以使用the trunc() function将时间部分截断为午夜;这也会将它从时间戳隐式转换为日期:

SELECT TRUNC(TO_TIMESTAMP_TZ('2015-11-04 13:45:19.387-05:00','YYYY-MM-DD HH24:MI:SS.FFTZH:TZM'))
FROM DUAL;

TRUNC(TO_TIMESTAMP_TZ('2015-11-0413:45:19.387-05:00','YYYY-MM-DDHH24:MI:SS.FFTZH
--------------------------------------------------------------------------------
04-NOV-15                                                                       

这会忽略实际时区 - 基本上假设值在您的系统时区中(即您在-05:00区域内)。

您还可以使用子字符串在转换前从原始字符串中去除时间和时区部分:

SELECT TO_DATE(SUBSTR('2015-11-04 13:45:19.387-05:00', 1, 10), 'YYYY-MM-DD')
FROM DUAL;

TO_DATE(SUBSTR('2015-11-0413:45:19.387-05:00',1,10),'YYYY-MM-DD')
-----------------------------------------------------------------
04-NOV-15        

...或者如果您愿意,可以在C#中执行子字符串,假设它正在解析XML文档。

(这些是故意以不同于ISO标准的格式显示,因此它们看起来不像XML中的原始字符串值;它们是带有时区类型的实际日期/时间戳,我的客户端只是使用我的NLS设置。)

您还可以选择使用Oracle的内置XML处理来从文档中提取关系数据,但这相当偏离主题,可能不合适。