日期在不同服务器上显示不同

时间:2012-10-29 18:26:36

标签: sql oracle oracle11g

当我在桌面上运行以下查询时

Select to_char(join_date, 'DD-MON-YYYY')
From students
group by to_char(join_date, 'DD-MON-YYYY');

我得到以下输出:

23-Oct-2012
25-Oct-2012
23-Oct-2012
23-Oct-2012
23-Oct-2012
26-Oct-2012
23-Oct-2012
24-Oct-2012
23-Oct-2012

但是如果我在不同的服务器上运行它,输出结果如下:

23-Oct. -2012
25-Oct. -2012
23-Oct. -2012
23-Oct. -2012
23-Oct. -2012
26-Oct. -2012
23-Oct. -2012
24-Oct. -2012
23-Oct. -2012

任何可能导致这种情况的想法? 第二台服务器在与我不同的国家/地区运行,因此其区域设置可能不同。

更新

NLS_DATE_FORMAT在两台服务器上都是DD-Mon-RRRR。

3 个答案:

答案 0 :(得分:1)

当oracle从数据库中检索日期字段并且显示给您时,会进行隐式强制转换。此转换的格式模式在oracle配置中设置。 Quoting oracle doc

  

Oracle日期值的默认日期格式来自   NLS_DATE_FORMAT和NLS_DATE_LANGUAGE初始化参数

如果两台服务器上的NLS_DATE_FORMAT为DD-Mon-RRRR ,请检查NLS_DATE_LANGUAGE

答案 1 :(得分:1)

您没有将代码输错为:

select to_char(join_date,'dd-mon.-yyyy') from students;

这将给出结果:

23-Oct.-2012

答案 2 :(得分:1)

正如danihp建议的那样,差异可能低于NLS_LANGUAGE设置,这可能来自更高的NLS参数。你可以覆盖它以获得一致的结果 - 尽管这不一定是个好主意 - 如globalisation support guide中所述。运行这些查询应该在两台服务器上产生一致的结果(猜测你的一台服务器是你所展示的数据中的法语):

select to_char(join_date, 'DD-MON-YYYY', 'NLS_DATE_LANGUAGE=FRENCH')
from students ...;

select to_char(join_date, 'DD-MON-YYYY', 'NLS_DATE_LANGUAGE=ENGLISH')
from students ...;

这种混乱的根源可能是您期望MON代表的。正如SQL reference中所述,MON是'月份的缩写名称';这意味着它不一定是三个字符的缩写。如何缩写完整月份名称取决于NLS设置。

在英语中,所有月份名称都可以毫不含糊地缩写为三个字符:

select level as l,
    to_char(to_date(level, 'MM'), 'Month', 'NLS_DATE_LANGUAGE=ENGLISH'),
    to_char(to_date(level, 'MM'), 'Mon', 'NLS_DATE_LANGUAGE=ENGLISH')
from dual
connect by level <= 12
order by 1

         L TO_CHAR(TO_DATE(LEVEL,'MM'),'MONTH', TO_CHAR(TO_D
---------- ------------------------------------ ------------
         1 January                              Jan
         2 February                             Feb
         3 March                                Mar
         4 April                                Apr
         5 May                                  May
         6 June                                 Jun
         7 July                                 Jul
         8 August                               Aug
         9 September                            Sep
        10 October                              Oct
        11 November                             Nov
        12 December                             Dec

在法语中并非如此:

select level as l,
    to_char(to_date(level, 'MM'), 'Month', 'NLS_DATE_LANGUAGE=FRENCH'),
    to_char(to_date(level, 'MM'), 'Mon', 'NLS_DATE_LANGUAGE=FRENCH')
from dual
connect by level <= 12
order by 1;

         L TO_CHAR(TO_DATE(LEVEL,'MM'),'MONTH', TO_CHAR(TO_DATE(LEVE
---------- ------------------------------------ --------------------
         1 Janvier                              Janv.
         2 Février                              Févr.
         3 Mars                                 Mars
         4 Avril                                Avr.
         5 Mai                                  Mai
         6 Juin                                 Juin
         7 Juillet                              Juil.
         8 Août                                 Ao
         9 Septembre                            Sept.
        10 Octobre                              Oct.
        11 Novembre                             Nov.
        12 Décembre                             Déc.

显然,使用三个字母的缩写会给Juin和Juillet带来困难。据推测,用句点表示缩写是一种文化因素,并且有几个月需要四个字符才能与众不同,这会使MON格式长度最多为五个字符。

格式模型将其保持为固定宽度可能有点令人惊讶,因此您可以在中间留出较短缩写的空格,就像在原始数据中一样。我敢肯定,无论哪种方式都可以争论,而且它似乎始终如一地应用。我不知道有什么方法可以自动停止。