Oracle NLS_DATE_LANGUAGE - 月份缩写

Oracle NLS_DATE_LANGUAGE - Month Abbreviations

根据我在网上找到的正确月份缩写值 (for example),我遇到了问题,而我尝试在 "English" 和 "American" 中使用 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;

我的月份如下所示,所以大多数月份应该有尾随“。”除五月、六月和七月和 "Jun" 外的值应为 "June":

一月
二月
三月
四月
五月

七月
八月
九月
十月
十一月
十二月

我可以很容易地添加一个基于月份的格式例外(例如 "Mon." 而不是 "Mon",5-6-7 月份除外),但我想我会问这个问题如果有人知道可以解决此问题的任何其他语言或地区值,而不是按月创建一些异常逻辑。我还使用 "French" 生成输出,并且输出与包括“.”在内的缩写完美配合。尽管刚刚通过“Mon dd, YYYY

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,}',
           '.'
         )
         || ' ' || 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

这是一种方法 - 请注意,您没有提到九月,通常缩写为 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   

没有 Oracle NLS_DATE_LANGUAGE 值可以产生您期望的输出(我刚刚检查了它们!)。您需要对某些值进行特殊处理,这主要基于长度,但您链接到的示例和其他样式指南(例如 AP and Princeton, and this)建议您应该在 9 月使用 'Sept.',而不是 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        

我一直保持功能简单(大概);你需要更聪明地替换 'Mon',(a) 这样你就不会捕捉到 'Month',并且 (b) 允许不同的情况('mon','Mon' , 'MON').不过,您实际上可能不需要那么大的灵活性,如果需要,您可以扩展这种方法。