2016-05-06 134 views
1

根據我在網上可以找到的內容(for example),我遇到了正確的月份縮寫值問題,而我嘗試在我的NLS_DATE_LANGUAGE參數中同時使用「英語」和「美國」,但底層值不顯示我想基於通過其他網站找到的通用標準。Oracle 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; 

我的月均現身爲其次,所以大多數月份應該有結尾的「」除五月,六月,七月,和 「君」 值,應該是 「六一」:

一月
二月
三月
四月


七月
八月
Sep
十月
十一月
十二月

我可以很容易地添加基於月的格式異常(例如, 「星期一」而不是「星期一」,除了5-6-7個月),但我想問問是否有人知道任何其他語言或領土價值可以解決這個問題,而不是按月創建一些異常邏輯。我還用「French」生成輸出,輸出與包含「。」的縮寫完美匹配。儘管只是路過 「星期一DD,YYYY

回答

4

沒有產生你所期望的輸出甲骨文NLS_DATE_LANGUAGE值(我只是檢查他們所有!)。您需要對特定值進行特殊處理,這些值主要基於長度,但您鏈接到的示例以及其他樣式指南(例如APPrincetonthis)建議您應該有'9月'。 9月份,而不是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)允許不同的情況('星期一','星期一','星期一')。你可能實際上並不需要這種靈活性,如果你願意的話,你可以擴展這種方法。

+0

謝謝!這或多或少地與我打算等待OP上的答案一致。我不確定,因爲我認爲可能有其他選擇,但謝謝你的確認。乾杯! – denisb

1

甲骨文設置

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 
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 
+0

'05'也可以使用'Month',這會簡化它嗎? –

+0

@AlexPoole是的,好點,做得好! * {: - D會更新我的答案。 – Boneist

+0

如果我真的很吝嗇,我建議你可以讓'09'的情況使用法語而不是英語,因爲'星期一'會給你'九月'。 - 但是對於未來的維護者來說可能會有點混亂...... * 8-) –