Java의 문자열 표현에서 로케일을 얻는 방법은 무엇입니까?


109

Locale의 메서드에 의해 반환 된 "프로그램 이름"에서 Locale 인스턴스를 가져 오는 깔끔한 방법이 toString()있습니까? 명백하고 추악한 해결책은 String을 파싱 한 다음 그에 따라 새로운 Locale 인스턴스를 구성하는 것입니다.하지만 더 나은 방법 / 준비된 솔루션이있을 수 있습니까?

로케일 자체를 포함하여 SQL 데이터베이스에 일부 로케일 특정 설정을 저장하고 싶지만 직렬화 된 로케일 개체를 거기에 두는 것은 추악 할 것입니다. 나는 차라리 상세하게 꽤 적절한 것처럼 보이는 그들의 String 표현을 저장하고 싶습니다.

답변:


34

참고 항목 Locale.getLanguage(), Locale.getCountry()대신의 데이터베이스에이 조합을 저장 ... "programatic name"...
당신이 로케일 등을 구축하고자 할 때 사용public Locale(String language, String country)

다음은 샘플 코드입니다. :)

// May contain simple syntax error, I don't have java right now to test..
// but this is a bigger picture for your algo...
public String localeToString(Locale l) {
    return l.getLanguage() + "," + l.getCountry();
}

public Locale stringToLocale(String s) {
    StringTokenizer tempStringTokenizer = new StringTokenizer(s,",");
    if(tempStringTokenizer.hasMoreTokens())
    String l = tempStringTokenizer.nextElement();
    if(tempStringTokenizer.hasMoreTokens())
    String c = tempStringTokenizer.nextElement();
    return new Locale(l,c);
}

3
이것은 컴파일조차하지 않을 것입니다.
Adrian

1
@raj 왜 tokenizer를 사용합니까? Java가 준비된 메소드를 제공한다면? 예 : toLocale (String str). 답변의 예를 참조하십시오
VdeX 2015

9
당신은 Locale.forLanguageTag (String)를 사용한다
리안

126

문자열에서 로케일을 반환하는 메서드는 commons-lang 라이브러리에 있습니다. LocaleUtils.toLocale(localeAsString)


2
LocaleUtils.toLocale은 'zh-Hans', 'pt-PT'등과 같은 문자열을 지원하지 않습니다.
Hans van Dodewaard

10
-로케일 부분 사이 에 하이픈이있는 경우 IETF BCP 47 태그를 처리하고 있으며 Java 7을 사용하는 경우 다음을 사용할 수 있습니다.Locale.forLanguageTag
Jaime Hablutzel

59

Java 7부터는 IETF 언어 태그를 사용하는 팩토리 메소드 Locale.forLanguageTag와 인스턴스 메소드가 있습니다 .Locale.toLanguageTag


8
다만 강조하고 싶은 Locale.forLanguageTagIETF (즉, 문자열을 로케일 작품 en-US) 및 ISO 로케일 문자열하지 작업 (즉 않습니다 en_US)
파비안

34
  1. Java는 적절한 구현으로 많은 것을 제공하므로 많은 복잡성을 피할 수 있습니다. 이것은 ms_MY를 반환합니다 .

    String key = "ms-MY";
    Locale locale = new Locale.Builder().setLanguageTag(key).build();
  2. Apache Commons는 LocaleUtils문자열 표현의 구문 분석을 도와야합니다. en_US 를 반환합니다.

    String str = "en-US";
    Locale locale =  LocaleUtils.toLocale(str);
    System.out.println(locale.toString());
  3. 로케일 생성자를 사용할 수도 있습니다.

    // Construct a locale from a language code.(eg: en)
    new Locale(String language)
    // Construct a locale from language and country.(eg: en and US)
    new Locale(String language, String country)
    // Construct a locale from language, country and variant.
    new Locale(String language, String country, String variant)

LocaleUtils 및이 Locale 을 확인하여 더 많은 방법을 탐색하십시오.


1
LocaleUtils.toLocale (localeStringRepresentation)은 작업을 깔끔하게 수행합니다. 또한이 방법의 구현을 보면 매우 포괄적입니다!
Dish

15

옵션 1 :

org.apache.commons.lang3.LocaleUtils.toLocale("en_US")

옵션 2 :

Locale.forLanguageTag("en-US")

참고하시기 바랍니다 옵션 1은 언어와 국가 사이에 "밑줄"이며, 옵션 2 "대시"입니다.


호출에는 API 레벨 21이 필요합니다 (현재 최소값은 17) : java.util.Locale # forLanguageTag
Vlad

12

이 대답은 약간 늦을 수 있지만 문자열을 구문 분석하는 것은 OP가 가정 한 것만 큼 추악하지 않다는 것이 밝혀졌습니다. 나는 그것이 매우 간단하고 간결하다는 것을 알았습니다.

public static Locale fromString(String locale) {
    String parts[] = locale.split("_", -1);
    if (parts.length == 1) return new Locale(parts[0]);
    else if (parts.length == 2
            || (parts.length == 3 && parts[2].startsWith("#")))
        return new Locale(parts[0], parts[1]);
    else return new Locale(parts[0], parts[1], parts[2]);
}

Locale.toString () 문서에있는 모든 예제를 사용하여 Java 7에서 테스트했습니다. "en", "de_DE", "_GB", "en_US_WIN", "de__POSIX", "zh_CN_ # Hans", "zh_TW_ # Hant-x-java "및"th_TH_TH_ # u-nu-thai ".

중요 업데이트 : 문서 에 따라 Java 7 이상에서 사용하는 것은 권장되지 않습니다 .

특히 toString의 출력을 언어, 국가 및 변형 필드로 구문 분석하는 클라이언트는 스크립트 또는 확장이있는 경우 변형 필드에 추가 정보가있을지라도 계속 그렇게 할 수 있습니다 ( 권장되지 않음 ).

대신 Locale.forLanguageTag 및 Locale.toLanguageTag를 사용하거나 필요한 경우 Locale.Builder를 사용하십시오.


5
Java 7 Locale.forLanguageTag은 IETF의 BCP 47에 표시된대로 인코딩 된 언어 태그에만 적용되며 의 메서드 반환에서와 같이 -밑줄 ( _)이 아닌 하이픈 ( )이 포함 되어 있습니다LocaletoString
Jaime Hablutzel 2013

1
네가 옳아. 기존 로케일 표현을 BCP47 형식으로 변환하는 방법이 여전히 필요합니다. 나의 의도는 앞으로 Locales는 그들의 toString형태 로 저장 toLanguageTag되는 것이 아니라 Locale더 쉽고 정확하게 다시 변환 될 수있는 형태 로 저장되어야한다고 제안하는 것이었다 .
andy 2011

이 방법에는 인덱스 범위를 벗어난 여러 가지 엣지 케이스가 있지 않을까요?
user2524908

@ user2524908 : 저는 그렇게 생각하지 않습니다. 그는 항상 요소에 액세스하기 전에 배열 길이를 테스트하기 때문입니다. 솔루션에는 제대로 작동하지 않지만 "범위를 벗어난 인덱스"가 아닌 많은 경우가있을 수 있습니다.
MestreLion

9

프로젝트에서 Spring 프레임 워크를 사용하는 경우 다음을 사용할 수도 있습니다.

org.springframework.util.StringUtils.parseLocaleString("en_US");

문서 :

주어진 문자열 표현을 로케일로 구문 분석


이것에 대한 문서는 그것이 특히 그 반대라고 말합니다 Locale#toString()-완벽합니다! :)
jocull


3

이것에 대한 정적 valueOf방법 이없는 것 같습니다 . 약간 놀랍습니다.

추악하지만 간단한 방법 중 하나는을 반복 Locale.getAvailableLocales()하여 toString값과 값을 비교하는 것입니다.

별로 좋지는 않지만 문자열 구문 분석이 필요하지 않습니다. Map문자열을 로케일로 미리 채우고 해당 맵에서 데이터베이스 문자열을 찾을 수 있습니다.


아, 반복은 상당히 합리적인 해결책 일 수 있습니다. 실제로 Locale에 이에 대한 정적 메서드가 없다는 것은 놀랍습니다.
Joonas Pulakka

미리 정의 된 Locale인스턴스는 유효한 로케일의 매우 작은 하위 집합만을 나타냅니다. 결코 완전하지 않습니다.
BetaRide 2014 년

3

Android에서 사용할 수 있습니다. 나를 위해 잘 작동합니다.

private static final Pattern localeMatcher = Pattern.compile
        ("^([^_]*)(_([^_]*)(_#(.*))?)?$");

public static Locale parseLocale(String value) {
    Matcher matcher = localeMatcher.matcher(value.replace('-', '_'));
    return matcher.find()
            ? TextUtils.isEmpty(matcher.group(5))
                ? TextUtils.isEmpty(matcher.group(3))
                    ? TextUtils.isEmpty(matcher.group(1))
                        ? null
                        : new Locale(matcher.group(1))
                    : new Locale(matcher.group(1), matcher.group(3))
                : new Locale(matcher.group(1), matcher.group(3),
                             matcher.group(5))
            : null;
}

1

글쎄, 내가 대신 문자열의 연결 저장하는 것 Locale.getISO3Language(), getISO3Country()후자의 호출에 나를 수있는 것 및 키와 getVariant () Locale(String language, String country, String variant)생성자를.

실제로 displayLanguage에 의존하는 것은 로케일의 언어를 사용하여 표시하는 것을 의미하므로 iso 언어 코드와 달리 로케일에 따라 달라집니다.

예를 들어, en 로케일 키는 다음과 같이 저장할 수 있습니다.

en_EN
en_US

등등 ...


1

방금 구현했기 때문에 :

에서 Groovy/ Grails이 될 것이다 :

def locale = Locale.getAvailableLocales().find { availableLocale ->
      return availableLocale.toString().equals(searchedLocale)
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.