2013-05-30 51 views
0

我有以下疑问:不同日期的Oracle 11g与蟾蜍

SELECT to_date(to_char(to_date('01-FEB-1949'))) FROM DUAL; 
/*this returns 2/1/2049. */ 

SELECT to_date(to_char(to_date('01-FEB-1949'),'dd-MON-yyyy')) FROM DUAL; 
/*this returns 2/1/1949.*/ 

为什么第一个返回年份2049,而不是1949

谷歌搜索我发现,我可以“强迫”客户端的日期格式是通过对注册表的改变key的一个愿望:

KEY_OraClient11g_home1 
NLS_DATE_FORMAT : YYYY/MM/DD 
+0

您的问题中显示的NLS_DATE_FORMAT是1949年的结果吗? –

+0

不,我添加了密钥,而且我仍然得到相同的结果 – Luis

+0

对于'YYYY/MM/DD'的NLS_DATE_FORMAT,我希望您可以将日期格式设置为'2049/02/01'。检查TOAD是否在其配置中包含某些东西,使其使用“RR”或“RRRR”年格式格式化日期(请参见[here](http://docs.oracle.com/cd/B19306_01/server.102 /b14200/sql_elements004.htm#i34510)查看TO_CHAR日期格式模型上的文档)。 –

回答

5

你在两个版本中做多的隐式转换日期。此:

SELECT to_date(to_char(to_date('01-FEB-1949'))) FROM DUAL; 

相当于:

SELECT to_date(to_char(to_date('01-FEB-1949', <NLS_DATE_FORMAT>), 
    <NLS_DATE_FORMAT>, <NLS_DATE_FORMAT>)) FROM DUAL; 

,而第二查询具有那些与一个指定格式替换之一。它看起来像你的默认格式 - 我相信你可以在Toad首选项中设置,而无需直接修改注册表。目前尚不清楚,如果你甚至修改与蟾蜍的东西 - 是DD-MON-RR,如通过插入到这这些查询:

SELECT to_date(to_char(to_date('01-FEB-1949','DD-MON-RR'), 
     'DD-MON-RR'),'DD-MON-RR') AS date1, 
    to_date(to_char(to_date('01-FEB-1949','DD-MON-RR'), 
     'dd-MON-yyyy'),'DD-MON-RR') AS date2 FROM DUAL; 

DATE1       DATE2 
February, 01 2049 00:00:00+0000 February, 01 1949 00:00:00+0000 

SQL Fiddle

可以在this SQL Fiddle,在看到第一个版本中,日期显示为年份为49而非1949的字符串,然后将其解释为RR掩码 - 为2049,这是预期的行为。

简短版本:从不依赖隐式日期转换或NLS日期格式掩码。

+0

哇,这是一些很棒的解释,不知道我正在做多个隐式日期转换。第二,我不知道'sqlfiddle'。第三,我已经给了你所有信息的+1,但是明天@在办公室,我要检查TOAD配置,看看当时的输出是如何设置的。 – Luis

+1

@Luis我会忽略蟾蜍或任何其他应用程序中的设置,并依赖明确的日期格式图片。对于不同的应用程序来说,设置不同的设置太容易了,然后代码就不能通过了。 –

+0

'隐式日期转换'可能是错误的短语;通常在没有'to_date'或'to_char'调用的地方使用,例如'sysdate> '31 - May-13' - 哪个更糟,因为哪个值将被转换并不明显。 '隐式日期格式掩码'在这种情况下可能会更好。 –