2016-05-06 4 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; 

Моего месяц выходит, как следует, так что большинство месяцев должны иметь завершающие «» Значение за май, июнь и июль, и "Июнь", за исключением, должно быть "Июнь":

Jan
февраля
Mar
апреля
мая
июня
июля
августа
Сент.
окт.
ноябрь
декабрь

Я могу легко добавить исключение формата в зависимости от месяца (например, «ПН» вместо «Mon», за исключением месяцев 5-6-7), но просто подумал, что я задал бы вопрос, знает ли кто-нибудь о каких-либо других языковых или территориальных значениях, которые могли бы решить это, вместо того, чтобы создавать некоторую логику исключения по месяцам. Я также выпускаю выход с «French», и выход отлично работает с сокращениями, включая «.». несмотря на проездом "пн Д.Д., YYYY" Настройка

ответ

4

Там нет значения Oracle NLS_DATE_LANGUAGE, которая производит вывод, который вы ожидаете (я только что проверил их все!). Вам нужна специальная обработка для определенных значений, которая в основном основана на длине, но пример, с которым вы связаны, и другие руководства по стилям (например, AP и Princeton и this) предполагают, что у вас должно быть «сентябрь», на сентябрь, а не 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), чтобы вы не поймали «Месяц» и (б), чтобы разрешить разные случаи («mon», «Mon», «MON»). На самом деле вам может не понадобиться такая гибкость, и если вы это сделаете, вы можете расширить этот подход.

+0

Спасибо! Это более или менее похоже на то, что я собирался в ожидании ответов на мой ОП. Я не был уверен, так как думал, что могут быть другие альтернативы, но спасибо за подтверждение. Ура! – denisb

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 
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' также может использовать «месяц», что упростит его немного. –

+0

@AlexPoole Да, хороший момент, хорошо сделано! * {: - D Обновит мой ответ. – Boneist

+0

Если бы я действительно был в курсе, я бы предположил, что вы могли бы использовать «09» для использования французского вместо английского, так как «Mon» тогда дал бы вам «сентябрь». - но это может быть немного запутанным для будущих сопровождающих ... * 8-) –

Смежные вопросы