sourcecode

SimpleDateFormat 및 로케일 기반 형식 문자열

copyscript 2022. 9. 3. 13:31
반응형

SimpleDateFormat 및 로케일 기반 형식 문자열

지정된 로케일에 따라 다른 방법으로 자바에서 날짜를 포맷하려고 합니다.예를 들어 영어 사용자에게는 "2009년 11월 1일"("MM d, yyyy"로 포맷됨)을, 노르웨이 사용자에게는 "2009년 11월 1일"("d. MMM. yyy")을 표시해 주었으면 합니다.

SimpleDateFormat 컨스트럭터에 로케일을 추가하면 월 부분은 정상적으로 동작합니다만, 나머지는 어떻습니까?

SimpleDateFormat에 로컬과 쌍을 이루는 형식 문자열을 추가할 수 있기를 희망했지만 방법이 없습니다.가능합니까?아니면 코드가 로케일을 체크하고 대응하는 포맷 문자열을 추가해야 합니까?

SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE dd MMM yyyy", Locale.ENGLISH);
String formatted = dateFormat.format(the_date_you_want_here);

DateFormat.getDateInstance(int style, Locale locale)를 사용하여 사용자 고유의 패턴을 만드는 대신SimpleDateFormat.

스타일 + 로케일을 사용합니다.DateFormat.getDateInstance(int 스타일, 로케일)

http://java.sun.com/j2se/1.5.0/docs/api/java/text/DateFormat.html 를 확인해 주세요.

다음 예제를 실행하여 차이점을 확인합니다.

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

public class DateFormatDemoSO {
  public static void main(String args[]) {
    int style = DateFormat.MEDIUM;
    //Also try with style = DateFormat.FULL and DateFormat.SHORT
    Date date = new Date();
    DateFormat df;
    df = DateFormat.getDateInstance(style, Locale.UK);
    System.out.println("United Kingdom: " + df.format(date));
    df = DateFormat.getDateInstance(style, Locale.US);
    System.out.println("USA: " + df.format(date));   
    df = DateFormat.getDateInstance(style, Locale.FRANCE);
    System.out.println("France: " + df.format(date));
    df = DateFormat.getDateInstance(style, Locale.ITALY);
    System.out.println("Italy: " + df.format(date));
    df = DateFormat.getDateInstance(style, Locale.JAPAN);
    System.out.println("Japan: " + df.format(date));
  }
}

출력:

United Kingdom: 25-Sep-2017
USA: Sep 25, 2017
France: 25 sept. 2017
Italy: 25-set-2017
Japan: 2017/09/25

dr;dr

LocalDate.now().format(
    DateTimeFormatter.ofLocalizedDate( FormatStyle.MEDIUM )
                     .withLocale( new Locale( "no" , "NO" ) )
)

귀찮은 클래스java.util.Date그리고.SimpleDateFormat이제 java.time 클래스로 대체된 레거시입니다.

LocalDate

클래스는 시간대 및 시간대가 없는 날짜 전용 값을 나타냅니다.

표준 시간대는 날짜를 결정하는 데 매우 중요합니다.날짜는 지역에 따라 전 세계적으로 다릅니다.예를 들어 프랑스 파리에서는 자정 몇 분 후가 새로운 날이고 몽트레알 퀘벡에서는 여전히 "어제"입니다.

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );

DateTimeFormatter

날짜 비율 또는 시간 비율만 나타내는 문자열을 생성하기 위해 사용합니다.

클래스는 자동으로 현지화할 수 있습니다.

현지화하려면 다음을 지정합니다.

  • FormatStyle 문자열의 길이 또는 단축 길이를 결정합니다.
  • Locale (a) 요일명, 월명 등의 번역을 위한 인간의 언어 및 (b) 줄임말, 대문자, 구두점 등의 문제를 결정하는 문화적 규범을 결정한다.

예:

Locale l = Locale.CANADA_FRENCH ; 
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL ).withLocale( l );
String output = ld.format( f );

반대로 현지화된 문자열을 해석할 수 있습니다.

LocalDate ld = LocalDate.parse( input , f );

로케일과 타임존은 완전히 직교적인 문제라는 점에 주의해 주세요.몽레알의 순간을 일본어로 표현하거나 오클랜드 뉴질랜드의 순간을 힌디어로 표현하거나 할 수 있습니다.

다른예로는 '있다'는 것입니다.6 junio 2012 ~까지2012-06-06(표준 ISO 8601 형식).java.time 클래스는 기본적으로 ISO 8601 형식을 사용하여 문자열을 해석/생성합니다.

String input = "6 junio 2012";
Locale l = new Locale ( "es" , "ES" );
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "d MMMM uuuu" , l );
LocalDate ld = LocalDate.parse ( input , f );
String output = ld.toString();  // 2012-06-06. 

형식 검토

다음은 자동으로 현지화된 여러 로케일에서 여러 형식의 결과를 검토하기 위한 코드 예입니다.

는 를 구현한 것으로, 낮은 메모리 사용률과 객체 수집 시 빠른 실행 속도에 모두 매우 최적화되어 있습니다.그렇게,EnumSet.allOf( FormatStyle.class )는 루프할 4개의 열거형 오브젝트 모두의 컬렉션을 제공합니다.자세한 내용은 열거 유형에 대한 Oracle 자습서를 참조하십시오.

LocalDate ld = LocalDate.of( 2018 , Month.JANUARY , 23 );

List < Locale > locales = new ArrayList <>( 3 );
locales.add( Locale.CANADA_FRENCH );
locales.add( new Locale( "no" , "NO" ) );
locales.add( Locale.US );

// Or use all locales (almost 800 of them, for about 120K text results).
// Locale[] locales = Locale.getAvailableLocales(); // All known locales. Almost 800 of them.

for ( Locale locale : locales )
{
    System.out.println( "------|  LOCALE: " + locale + " — " + locale.getDisplayName() + "  |----------------------------------" + System.lineSeparator() );

    for ( FormatStyle style : EnumSet.allOf( FormatStyle.class ) )
    {
        DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( style ).withLocale( locale );
        String output = ld.format( f );
        System.out.println( output );
    }
    System.out.println( "" );
}
System.out.println( "« fin »" + System.lineSeparator() );

산출량.

------|  LOCALE: fr_CA — French (Canada)  |----------------------------------

mardi 23 janvier 2018
23 janvier 2018
23 janv. 2018
18-01-23

------|  LOCALE: no_NO — Norwegian (Norway)  |----------------------------------

tirsdag 23. januar 2018
23. januar 2018
23. jan. 2018
23.01.2018

------|  LOCALE: en_US — English (United States)  |----------------------------------

Tuesday, January 23, 2018
January 23, 2018
Jan 23, 2018
1/23/18

« fin »

java.time 정보

java.time 프레임워크는 Java 8 이후에 포함되어 있습니다.이러한 클래스는 , 및 등 문제가 많은 오래된 레거시 날짜 시간 클래스를 대체합니다.

현재 유지보수 모드에 있는 조다 타임 프로젝트는 java.time 클래스로의 이행을 권장합니다.

자세한 내용은 Oracle 자습서를 참조하십시오.또한 Stack Overflow를 검색하여 많은 예와 설명을 확인하십시오.사양은 JSR 310입니다.

java.time 객체를 데이터베이스와 직접 교환할 수 있습니다.JDBC 4.2 이후준거한JDBC 드라이버를 사용합니다.스트링도 필요 없고java.sql.*②.

java.time 클래스는 어디서 얻을 수 있습니까?

  • Java SE 8, Java SE 9 이후
    • 붙박이.
    • 번들 구현이 포함된 표준 Java API의 일부입니다.
    • Java 9에는 몇 가지 사소한 기능과 수정 사항이 추가되어 있습니다.
  • Java SE 6 및 Java SE 7
    • java.time 기능의 대부분은 ThreeTen 백포트의 Java 6 및7로 백포트됩니다.
  • 안드로이드
    • 최신 버전의 Android 번들 구현 java.time 클래스.
    • 이전의 Android에서는 쓰리텐ABP 프로젝트는 ThreeTen-Backport(상기)를 채택하고 있습니다.'쓰리텐ABP 사용방법'을 참조하십시오.

쓰리텐 엑스트라 프로젝트는 java.time을 추가 클래스로 확장합니다.이 프로젝트는 향후 java.time에 추가될 수 있는 가능성을 입증하는 기반입니다.여기에는 , , , 유용한 클래스가 있습니다.

날짜 문자열 현지화:

레드소닉의 투고에 근거합니다.

private String localizeDate(String inputdate, Locale locale) { 

    Date date = new Date();
    SimpleDateFormat dateFormatCN = new SimpleDateFormat("dd-MMM-yyyy", locale);       
    SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy");


    try {
        date = dateFormat.parse(inputdate);
    } catch (ParseException e) {
        log.warn("Input date was not correct. Can not localize it.");
        return inputdate;
    }
    return dateFormatCN.format(date);
}

String localizedDate = localizeDate("05-Sep-2013", new Locale("zh","CN"));

2013년 5월 5일쯤 될 거야

사용자의 현재 로케일에 따라 날짜가 표시됩니다.

날짜 및 시간을 반환하려면:

import java.text.DateFormat;    
import java.util.Date;

Date date = new Date();
DateFormat df = DateFormat.getDateTimeInstance();
String myDate = df.format(date);

1969년 12월 31일 오후 7:00:02

날짜만 반환하려면 다음을 사용합니다.

DateFormat.getDateInstance() 

1969년 12월 31일

특정 날짜에 대한 Java 8 Style

LocalDate today = LocalDate.of(1982, Month.AUGUST, 31);
System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.ENGLISH)));
System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.FRENCH)));
System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.JAPANESE)));

이게 도움이 됐으면 좋겠네요.로케일 인스턴스를 받아들여 로케일 고유의 날짜 형식/패턴을 반환하는 다음 코드를 참조하십시오.

public static String getLocaleDatePattern(Locale locale) {
    // Validating if Locale instance is null
    if (locale == null || locale.getLanguage() == null) {
        return "MM/dd/yyyy";
    }
    // Fetching the locale specific date pattern
    String localeDatePattern = ((SimpleDateFormat) DateFormat.getDateInstance(
            DateFormat.SHORT, locale)).toPattern();
    // Validating if locale type is having language code for Chinese and country
    // code for (Hong Kong) with Date Format as - yy'?'M'?'d'?'
    if (locale.toString().equalsIgnoreCase("zh_hk")) {
        // Expected application Date Format for Chinese (Hong Kong) locale type
        return "yyyy'MM'dd";
    }
    // Replacing all d|m|y OR Gy with dd|MM|yyyy as per the locale date pattern
    localeDatePattern = localeDatePattern.replaceAll("d{1,2}", "dd")
            .replaceAll("M{1,2}", "MM")
            .replaceAll("y{1,4}|Gy", "yyyy");
    // Replacing all blank spaces in the locale date pattern
    localeDatePattern = localeDatePattern.replace(" ", "");
    // Validating the date pattern length to remove any extract characters
    if (localeDatePattern.length() > 10) {
        // Keeping the standard length as expected by the application
        localeDatePattern = localeDatePattern.substring(0, 10);
    }
    return localeDatePattern;
}
String text = new SimpleDateFormat("E, MMM d, yyyy").format(date);

자바8

 import java.time.format.DateTimeFormatter;         
 myDate.format(DateTimeFormatter.ofPattern("dd-MMM-YYYY",new Locale("ar")))

언급URL : https://stackoverflow.com/questions/1661325/simpledateformat-and-locale-based-format-string

반응형