如何在不设置区域设置的情况下设置 NLS 日期格式

Posted

技术标签:

【中文标题】如何在不设置区域设置的情况下设置 NLS 日期格式【英文标题】:How can I set the NLS date format without setting the Locale 【发布时间】:2010-10-27 07:04:55 【问题描述】:

我们的 java 类调用 PLSQL proc,它以 NLS_DATE_FORMAT 定义的默认格式返回日期。我们的应用程序为国际化设置了自己的语言环境,但我希望日期格式保持为“DD-MON-RR”,即 en_US Locale NLS_DATE_FORMAT。由于语言环境的变化,oracle 获取的日期字符串不同,随后的 TO_DATE() 函数调用失败。我尝试通过在 java 类中更改 Locale to Locale.setDefault(new Locale("en","US")); //"en_US" 来解决此问题,它工作正常,但国际化部分将不再工作。我在新加坡,所以我的语言环境是"en_SG",而 oracle 在设置NLS_TERRITORY: SINGAPORE 后采用的日期格式是NLS_DATE_FORMAT:'DD/MM/RR'。我向服务器查询 V$NLS_PARAMETERS,默认日期格式为“DD-MON-RR”。所以我的问题是,我可以设置 NLS_DATE_FORMAT 而不影响应用程序的区域设置。或者我可以让 jdbc 驱动程序完全忽略客户端的 NLS 设置吗?

【问题讨论】:

【参考方案1】:

你可以使用to_char函数来格式化你想要的日期,你也可以在to_char函数中包含第三个参数来表示使用的语言环境:

select to_char(sysdate, 'DY-MM-YYYY', 'NLS_DATE_LANGUAGE=AMERICAN')  from dual;

有关日期格式的更多信息,请参阅SQL Reference。

【讨论】:

哦,是的,如果可能的话,实际上我可以在 PLSQL 中使用TO_CHAR(sysdate,'DD-MON-RR')。但我的项目正在将旧 PRO C* 代码的一部分重新设计为 java。所以每个人都希望保持 PL/SQL 部分不变,因为它目前工作正常。出现问题的原因是 PRO C* 代码与数据库位于同一台机器上,因此它们遵循相同的 NLS 设置。但是这个 Java 类可能是应用程序服务器的一部分,并且在未来它最有可能移动到 Web 服务中。因此,我想保留现有的区域设置,因为该应用程序目前也可以正常工作。【参考方案2】:

我正在为我的应用程序确定 i18n 的东西,我的设计基于以下假设)

1) Locale.setDefault(new Locale("en","US"));不好,因为您正在更改 JVM 的默认语言环境,而不仅仅是您的应用程序。所以最好在每个请求的基础上传递应用程序的语言环境(可能是线程本地的)

2) 在应用程序级别处理所有 i18n 格式化/解析。 DB 应该只处理比较(可选)、排序(可选)和存储。所以只需设置 NLS_CHARACTERSET、NLS_COMP、NLS_SORT 和 NLS_LENGTH_SEMANTICS。顺便说一下,在数据库级别进行比较和排序意味着创建特定于语言环境的索引,从而减慢插入/更新速度

【讨论】:

是的,您的第一点是正确的。对于第二点,我们在前端确实有 i18n 格式,但是该过程返回来自 oracle 过程的字符串 from 中的数据。一个更简单的字符串是如何形成的代码就像select 'MKDT'||lpad(nvl(length(por.maker_date),0),3,'0')||por.maker_date data from TABLEXYZ; 我猜这行会自动调用TO_CHAR(<DATE>, <DEFAULT NLS DATE FORMAT>) 并转换日期。我知道他们应该使用TO_CHAR(<DATE>, <SPECIFIC DATE FORMAT>)。我已经建议在 DB Procs 中进行此更改,但它涉及到对稳定 PROCS 的大量更改。

以上是关于如何在不设置区域设置的情况下设置 NLS 日期格式的主要内容,如果未能解决你的问题,请参考以下文章

ORACLE NLS_DATE_FORMAT设置

在不使用代码的情况下更改 Windows 区域设置/文化

在不使用 localectl 的情况下更改 CentOS/RHEL 中的系统区域设置?

Win7系统怎么更改日期,时间和数字格式

windows7修改日期和时间的显示格式

如何根据区域设置中定义的语言本地化 DatePicker 的日期格式