Существует ли открытый код java стандарта ISO 3166-1 для кодов стран?

Кто-нибудь знает о свободно доступном пакете Java 1.5, который предоставляет список кодов стран ISO 3166-1 в виде enum или EnumMap? В частности, мне нужны "элементы кода ISO 3166-1-alpha-2", то есть двухсимвольный код страны, такой как "us", "uk", "de" и т. Д. Создание достаточно простое (хотя и утомительное), но если в апаче-ланде уже есть стандартный, или что-то вроде этого сэкономит немного времени.

15 ответов

Теперь реализация списка кодов стран ( ISO 3166-1 alpha-2/ alpha-3/ numeric) в виде перечисления Java доступна на GitHub под лицензией Apache License версии 2.0.

Пример:

CountryCode cc = CountryCode.getByCode("JP");

System.out.println("Country name = " + cc.getName());                // "Japan"
System.out.println("ISO 3166-1 alpha-2 code = " + cc.getAlpha2());   // "JP"
System.out.println("ISO 3166-1 alpha-3 code = " + cc.getAlpha3());   // "JPN"
System.out.println("ISO 3166-1 numeric code = " + cc.getNumeric());  // 392

Последнее изменение 2016-Jun-09

Перечисление CountryCode было упаковано в com.neovisionaries.i18n с другими перечислениями Java, LanguageCode ( ISO 639-1), LanguageAlpha3Code ( ISO 639-2), LocaleCode, ScriptCode ( ISO 15924) и CurrencyCode ( ISO 4217) и зарегистрировано в Maven Central Repository.

специалист

<dependency>
  <groupId>com.neovisionaries</groupId>
  <artifactId>nv-i18n</artifactId>
  <version>1.22</version>
</dependency>

Gradle

dependencies {
  compile 'com.neovisionaries:nv-i18n:1.22'
}

GitHub

https://github.com/TakahikoKawasaki/nv-i18n

Javadoc

http://takahikokawasaki.github.com/nv-i18n/

OSGi

Bundle-SymbolicName: com.neovisionaries.i18n
Export-Package: com.neovisionaries.i18n;version="1.22.0"

Этот код получает 242 страны в Sun Java 6:

String[] countryCodes = Locale.getISOCountries();

Хотя веб-сайт ISO утверждает, что существует 249 элементов кода ISO 3166-1-alpha-2, хотя javadoc ссылается на ту же информацию.

Вот как я сгенерировал перечисление с кодом страны + названием страны:

package countryenum;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

public class CountryEnumGenerator {
    public static void main(String[] args) {
        String[] countryCodes = Locale.getISOCountries();
        List<Country> list = new ArrayList<Country>(countryCodes.length);

        for (String cc : countryCodes) {
            list.add(new Country(cc.toUpperCase(), new Locale("", cc).getDisplayCountry()));
        }

        Collections.sort(list);

        for (Country c : list) {
            System.out.println("/**" + c.getName() + "*/");
            System.out.println(c.getCode() + "(\"" + c.getName() + "\"),");
        }

    }
}

class Country implements Comparable<Country> {
    private String code;
    private String name;

    public Country(String code, String name) {
        super();
        this.code = code;
        this.name = name;
    }

    public String getCode() {
        return code;
    }


    public void setCode(String code) {
        this.code = code;
    }


    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }


    @Override
    public int compareTo(Country o) {
        return this.name.compareTo(o.name);
    }
}

Если вы уже собираетесь полагаться на язык Java, то я предлагаю использовать простой HashMap вместо создания новых классов для стран и т. Д.

Вот как бы я использовал его, если бы полагался только на локализацию Java:

private HashMap<String, String> countries = new HashMap<String, String>();
String[] countryCodes = Locale.getISOCountries();

for (String cc : countryCodes) {
    // country name , country code map
    countries.put(new Locale("", cc).getDisplayCountry(), cc.toUpperCase());
}

После того, как вы заполните карту, вы можете получить код ISO из названия страны, когда вам это нужно. Или же вы можете сделать это кодом ISO для карты названий стран, просто изменив метод put соответствующим образом.

Существует простой способ создать это перечисление с именем языка. Выполните этот код, чтобы сгенерировать список полей перечисления для вставки:

 /**
  * This is the code used to generate the enum content
  */
 public static void main(String[] args) {
  String[] codes = java.util.Locale.getISOLanguages();
  for (String isoCode: codes) {
   Locale locale = new Locale(isoCode);
   System.out.println(isoCode.toUpperCase() + "(\"" + locale.getDisplayLanguage(locale) + "\"),");
  }
 }

Если кто-то уже использует Amazon AWS SDK, он включает com.amazonaws.services.route53domains.model.CountryCode, Я знаю, что это не идеально, но это альтернатива, если вы уже используете AWS SDK. В большинстве случаев я бы использовал Такахико nv-i18n поскольку, как он упоминает, он реализует ISO 3166-1.

AWS Java SDK имеет CountryCode.

Есть стандартjava.util.Locale.IsoCountryCodeначиная с Явы 9.

Не java-перечисление, а JSON-версия этого доступна по адресу http://country.io/names.json

Чтобы получить текущую локаль устройства в формате Alpha-3 ISO (XXX):

      fun getCurrentCountryCode(): String? {
    val tm = context.getSystemService(AppCompatActivity.TELEPHONY_SERVICE) as TelephonyManager
    val countryCodeValue = tm.networkCountryIso

    val locale: Locale? = Locale.getAvailableLocales().firstOrNull {
        it.country.lowercase() == countryCodeValue.lowercase()
    }

    return locale?.isO3Country
}

Чтобы получить формат текущей локали языка устройства (xx-XX):

      fun getCurrentLocale(): String? {
    return try {
        val locale = context.resources.configuration.locales[0]
        return "${locale.language}-${locale.country}"
    } catch (e: Exception) {
        e.printStackTrace()
        null
    }
}

Это все еще не отвечает на вопрос. Я тоже искал некий счетчик для этого и ничего не нашел. Некоторые примеры использования хеш-таблицы здесь, но представляют собой то же самое, что встроенный get

Я бы пошел по другому подходу. Поэтому я создал скрипт на python для автоматической генерации списка на Java:

#!/usr/bin/python
f = open("data.txt", 'r')
data = []
cc = {}

for l in f:
    t = l.split('\t')
    cc = { 'code': str(t[0]).strip(), 
           'name': str(t[1]).strip()
    }
    data.append(cc)
f.close()

for c in data:
    print """
/**
 * Defines the <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">ISO_3166-1_alpha-2</a> 
 * for <b><i>%(name)s</i></b>.
 * <p>
 * This constant holds the value of <b>{@value}</b>.
 *
 * @since 1.0
 *
 */
 public static final String %(code)s = \"%(code)s\";""" % c

где файл data.txt представляет собой простое копирование и вставка из таблицы Википедии (просто удалите все лишние строки, убедившись, что у вас есть код страны и название страны в каждой строке).

Затем просто поместите это в ваш статический класс:

/**
 * Holds <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">ISO_3166-1_alpha-2</a>
 * constant values for all countries. 
 * 
 * @since 1.0
 * 
 * </p>
 */
public class CountryCode {

    /**
     * Constructor defined as <code>private</code> purposefully to ensure this 
     * class is only used to access its static properties and/or methods.  
     */
    private CountryCode() { }

    /**
     * Defines the <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">ISO_3166-1_alpha-2</a> 
     * for <b><i>Andorra</i></b>.
     * <p>
     * This constant holds the value of <b>{@value}</b>.
     *
     * @since 1.0
     *
     */
     public static final String AD = "AD";

         //
         // and the list goes on! ...
         //
}

JCountry — это библиотека с открытым исходным кодом, содержащая коды ISO 3166-1 и соответствующие переводы названий стран на разные языки. Это оболочка для информации об изокодах Debian. Он также содержит ISO-коды языков (iso 639-2) и соответствующие переводы названий языков.

      // Maven
<dependency>
    <groupId>io.github.castmart</groupId>
    <artifactId>jcountry</artifactId>
    <version>0.0.2</version>
</dependency>

Вот репозиторий: https://github.com/castmart/jcountry

      JCountry jcountry = JCountry.getInstance();
CountryDB countryDB = jcountry.getCountriesDB();
// Get the countries DB hash maps <String, Country>
var dbByAlpha2 = countryDB.getCountriesMapByAlpha2();
var dbByAlpha3 = countryDB.getCountriesMapByAlpha3();
var dbByName = countryDB.getCountriesMapByName();

// Get Translations by language based locale 
Optional<ResourceBundle> bundle = countryDB.getCountriesTranslations(Locale.GERMAN);

// MX -> Mexiko
var translatedCountryName = bundle.get().getString(dbByAlpha2.get("MX").getName());

// Languages DB
LanguageDB languageDB = new LanguageDBImpl(true);
var dbByAlpha2 = languageDB.getLanguagesMapByAlpha2();

// Get Translations by language based locale 
Optional<ResourceBundle> bundle = languageDB.getLanguagesTranslations(Locale.GERMAN);

// Spanisch (Kastilisch)
var translatedCountryName = bundle.get().getString(dbByAlpha2.get("es").getName());

Я создал enum, к которому вы обращаетесь по английскому названию страны. Смотри Country-Util.
На каждом перечислении вы можете позвонить getLocale() чтобы получить Java Locale.

Из локали вы можете получить всю информацию, к которой вы привыкли, например, двухбуквенный код страны ISO-3166-1.

public enum Country{

    ANDORRA(new Locale("AD")),
    AFGHANISTAN(new Locale("AF")),
    ANTIGUA_AND_BARBUDA(new Locale("AG")),
    ANGUILLA(new Locale("AI")),
    //etc
    ZAMBIA(new Locale("ZM")),
    ZIMBABWE(new Locale("ZW"));

    private Locale locale;

    private Country(Locale locale){
        this.locale = locale;
    }

    public Locale getLocale(){
        return locale;
    }

Pro:

  • Легкий вес
  • Карты в Java Locales
  • Адресуется по полному названию страны
  • Значения перечисления не жестко закодированы, но генерируются вызовом Locale.getISOCountries(). То есть: просто перекомпилируйте проект с использованием новейшей версии Java, чтобы любые изменения, внесенные в список стран, были отражены в enum.

Против:

  • Не в репозитории Maven
  • Скорее всего, проще / менее выразительно, чем другие решения, которые я не знаю.
  • Создано для собственных нужд / не поддерживается. - Вы, вероятно, должны клонировать репо.

Я не знал об этом вопросе до тех пор, пока я только недавно не открыл свой enum-код для этой цели! Удивительное совпадение!

Я разместил весь исходный код в своем блоге с лицензией BSD caluse 3, так что я не думаю, что у кого-то будут какие-либо жалобы по этому поводу.

Можно найти здесь. https://subversivebytes.wordpress.com/2013/10/07/java-iso-3166-java-enum/

Надеюсь, что это полезно и облегчает боли развития.

Я нашел список IsoCountry здесь , в нем есть 2- и 3-символьные коды стран.

Другие вопросы по тегам