Oracle NLS_DATE_LANGUAGE - 月份缩写

时间:2016-05-06 12:37:02

标签: oracle plsql oracle11g oracle-sqldeveloper

根据我在网上找到的内容(for example),我遇到了正确的月份缩写值问题,而我在NLS_DATE_LANGUAGE参数中尝试同时使用“英语”和“美国”,但基础值根据通过各种其他网站找到的通用标准,我没有显示我想要的内容。

如上所述,我试过了两个:

SELECT TO_CHAR(pDate, 'Mon dd, yyyy', 'NLS_DATE_LANGUAGE = American') FROM DUAL;
SELECT TO_CHAR(pDate, 'Mon dd, yyyy', 'NLS_DATE_LANGUAGE = English') FROM DUAL;

我的月份如下所示,所以大多数月份应该有“。”除了5月,6月和7月以外的值,“Jun”应该是“June”:


二月
三月
四月
可以

七月
八月
九月
十月
十一月

我可以轻松地根据月份添加格式例外(例如“Mon。”而不是“Mon”,除了5-6-7个月),但我想问一个问题是否有人知道任何问题可以解决此问题的其他语言或领域值,而不是按月创建一些异常逻辑。我还使用“French”生成输出,输出与包括“。”在内的缩写完美配合。尽管只是传递了“ Mon dd,YYYY

3 个答案:

答案 0 :(得分:4)

没有Oracle NLS_DATE_LANGUAGE值产生您期望的输出(我只是检查了它们!)。您需要对特定值进行特殊处理,这些值主要基于长度,但您链接到的示例和其他样式指南(例如APPrinceton以及this)表明您应该拥有'九月&#39。九月,而不是Sep.

最简单的方法是对它们进行硬编码:

select case extract(month from add_months(trunc(sysdate, 'YYYY'), level - 1))
  when 1 then 'Jan.' when 2 then 'Feb.' when 3 then 'Mar.' when 4 then 'Apr.'
  when 5 then 'May' when 6 then 'June' when 7 then 'July' when 8 then 'Aug.'
  when 9 then 'Sept.' when 10 then 'Oct.' when 11 then 'Nov.' else 'Dec.' end
from dual
connect by level <= 12;

CASEE
-----
Jan. 
Feb. 
Mar. 
Apr. 
May  
June 
July 
Aug. 
Sept.
Oct. 
Nov. 
Dec. 

您可以使用某个功能来使用自定义转换:

create or replace function my_to_char(p_date date, p_fmt varchar2) return varchar2 is
  l_str varchar2(30);
  l_month varchar2(5);
begin
  l_month := case extract(month from p_date)
    when 1 then 'Jan.' when 2 then 'Feb.' when 3 then 'Mar.' when 4 then 'Apr.'
    when 5 then 'May' when 6 then 'June' when 7 then 'July' when 8 then 'Aug.'
    when 9 then 'Sept.' when 10 then 'Oct.' when 11 then 'Nov.' else 'Dec.' end;

  return to_char(p_date, replace(p_fmt, 'Mon', '"' || l_month || '"'));
end;
/

select my_to_char(date '2016-04-15' , 'DD Mon YYYY') as result from dual;

RESULT             
--------------------
15 Apr. 2016        

我保持功能简单(ish);你需要更加聪明地更换“周一”,(a)这样你就不会抓住“月”,而(b)允许更换不同的案例(&#39) ; mon&#39;,&#39; Mon&#39;,&#39; MON&#39;)。你可能实际上并不需要那么多的灵活性,如果你这样做,你可以扩展这种方法。

答案 1 :(得分:2)

以下是这样做的一种方式 - 请注意,您没有提到九月,这通常缩写为Sept.

with months as (select add_months(trunc(sysdate, 'yyyy'), level -1) mon
                from   dual
                connect by level <= 12)
select mon,
       case when to_char(mon, 'mm') in ('05', '06', '07') then to_char(mon, 'fmMonth fmdd, yyyy', 'NLS_DATE_LANGUAGE = English')
            when to_char(mon, 'mm') = '09' then substr(to_char(mon, 'fmMonth', 'NLS_DATE_LANGUAGE = English'), 1, 4)||to_char(mon, '. dd, yyyy', 'NLS_DATE_LANGUAGE = English')
            else to_char(mon, 'Mon. dd, yyyy', 'NLS_DATE_LANGUAGE = English') 
       end abbrev_mon
from   months;

MON       ABBREV_MON                          
--------- ------------------------------------
01-JAN-16 Jan. 01, 2016                       
01-FEB-16 Feb. 01, 2016                       
01-MAR-16 Mar. 01, 2016                       
01-APR-16 Apr. 01, 2016                       
01-MAY-16 May 01, 2016                        
01-JUN-16 June 01, 2016                       
01-JUL-16 July 01, 2016                       
01-AUG-16 Aug. 01, 2016                       
01-SEP-16 Sept. 01, 2016                      
01-OCT-16 Oct. 01, 2016                       
01-NOV-16 Nov. 01, 2016                       
01-DEC-16 Dec. 01, 2016   

答案 2 :(得分:1)

Oracle设置

CREATE FUNCTION to_char_abbr_month(
  in_date DATE,
  in_nls  VARCHAR2
) RETURN VARCHAR2 DETERMINISTIC
IS
BEGIN
  RETURN REGEXP_REPLACE(
           TRIM( TO_CHAR( in_date, 'Month', in_nls ) ),
           '(\w{3})\w{2,}',
           '\1.'
         )
         || ' ' || TO_CHAR( in_date, 'dd, yyyy', in_nls );
END;
/

<强>查询

SELECT to_char_abbr_month(
         DATE '2016-01-01',
         'NLS_DATE_LANGUAGE = American'
       )
FROM   DUAL

<强>输出

Jan. 01, 2016