首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将ISO 3166-1 alpha-2国家代码转换为本地化国家名称

将ISO 3166-1 alpha-2国家代码转换为本地化国家名称
EN

Stack Overflow用户
提问于 2014-08-14 06:11:03
回答 3查看 2.4K关注 0票数 6

有没有办法在不使用外部资源的情况下,将两个字母的国家代码转换为可读的国家代码?

例如DE -> GermanyAD -> Andorra

如果我能选择目标语言或者它使用的是系统语言,那就太好了,因为我想用德语。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-08-14 15:52:33

正如@Uwe在他的评论中提到的那样,您可以使用EnumSystemGeoIDGetGeoInfo函数。其原则是,使用EnumSystemGeoID函数,您将枚举地理位置标识符,并通过GetGeoInfo函数查询枚举标识符的ISO2字母国家/地区代码(info类型GEO_ISO2等于您感兴趣的代码)。如果是这样的话,那么您可以使用相同的函数查询这个标识符(一个友好的名称(info类型为GEO_FRIENDLYNAME )或官方名称(info类型为GEO_OFFICIALNAME ),返回结果并停止枚举。

下面是一个示例代码,它可能会这样做(不幸的是,枚举函数不支持传递自定义数据,因此我使用了一个全局记录变量来传递值):

代码语言:javascript
复制
type
  TEnumData = record
    GeoCode: string;
    GeoName: string;
    Success: Boolean;
  end;

  GEOID = type LONG;
  GEOTYPE = type DWORD;
  GEOCLASS = type DWORD;

  SYSGEOTYPE = (
    GEO_NATION = $0001,
    GEO_LATITUDE = $0002,
    GEO_LONGITUDE = $0003,
    GEO_ISO2 = $0004,
    GEO_ISO3 = $0005,
    GEO_RFC1766 = $0006,
    GEO_LCID = $0007,
    GEO_FRIENDLYNAME= $0008,
    GEO_OFFICIALNAME= $0009,
    GEO_TIMEZONES = $000A,
    GEO_OFFICIALLANGUAGES = $000B,
    GEO_ISO_UN_NUMBER = $000C,
    GEO_PARENT = $000D
  );

  SYSGEOCLASS = (
    GEOCLASS_NATION = 16,
    GEOCLASS_REGION = 14,
    GEOCLASS_ALL = 0
  );

  GEO_ENUMPROC = function(GeoId: GEOID): BOOL; stdcall;

  function EnumSystemGeoID(GeoClass: GEOCLASS;
    ParentGeoId: GEOID; lpGeoEnumProc: GEO_ENUMPROC): BOOL; stdcall;
    external kernel32 name 'EnumSystemGeoID';
  function GetGeoInfo(Location: GEOID; GeoType: GEOTYPE;
    lpGeoData: LPTSTR; cchData: Integer; LangId: LANGID): Integer; stdcall;
    external kernel32 name {$IFDEF UNICODE}'GetGeoInfoW'{$ELSE}'GetGeoInfoA'{$ENDIF};

implementation

var
  // I have used this global variable due to a lack of user data parameter for the callback function
  EnumData: TEnumData;

function TryGetGeoInfo(GeoId: GEOID; GeoType: GEOTYPE; out Value: string): Boolean;
var
  Buffer: string;
  BufferLen: Integer;
begin
  Result := False;
  BufferLen := GetGeoInfo(GeoId, GeoType, LPTSTR(Buffer), 0, 0);
  if BufferLen <> 0 then
  begin
    SetLength(Buffer, BufferLen);
    Result := GetGeoInfo(GeoId, GeoType, LPTSTR(Buffer), BufferLen, 0) <> 0;
    if Result then
      Value := Trim(Buffer);
  end;
end;

function EnumGeoInfoProc(GeoId: GEOID): BOOL; stdcall;
var
  S: string;
begin
  Result := TryGetGeoInfo(GeoId, GEOTYPE(GEO_ISO2), S);
  if Result and (S = EnumData.GeoCode) then
  begin
    // stop the enumeration since we've found the country by its ISO code
    Result := False;
    // return the success flag and try to return the friendly name of the country to the
    // EnumData.GeoName record field; you can optionally query the GEO_OFFICIALNAME
    EnumData.Success := TryGetGeoInfo(GeoId, GEOTYPE(GEO_FRIENDLYNAME), EnumData.GeoName);
  end;
end;

function TryGetCountryNameByISO2(const Code: string; out Name: string): Boolean;
begin
  // here is the brainless part using global record variable (because the function used
  // here with its callback does not support passing user data); no, you cannot tune it
  // up by making the callback function nested
  EnumData.GeoCode := Code;
  EnumData.Success := False;

  if not EnumSystemGeoID(GEOCLASS(GEOCLASS_NATION), 0, EnumGeoInfoProc) then
    RaiseLastOSError;

  Result := EnumData.Success;
  if Result then
    Name := EnumData.GeoName;
end;

以及一种可能的用法:

代码语言:javascript
复制
var
  S: string;
begin
  if TryGetCountryNameByISO2('DE', S) then
    ShowMessage(S);
end;
票数 6
EN

Stack Overflow用户

发布于 2014-08-14 07:20:40

您可以迭代Languages (从Sysutils)并检查Ext属性。相应的Name属性将为您提供本地化的语言名称。

代码语言:javascript
复制
  for I := 0 to Languages.Count - 1 do begin
    Writeln(Languages.Ext[I], '=', Languages.Name[I]);
  end;
票数 3
EN

Stack Overflow用户

发布于 2014-08-14 09:03:42

Uwe Raabe建议的子语言元素是有帮助的,但是结果并不好,因为它找不到所有的ISO代码,有时还会向一个国家的名称返回一些不同的东西,比如Simplified Chinese

代码语言:javascript
复制
function _GetCountryFromISO(const aISO: string): string;
 const
  cStatement1 = '-(.*)';
  cStatement2 = '\((.*?)\)';
var
  i: Integer;
  match: TMatch;
begin
  Result := aISO;  // default result if not found
  for i := 0 to Languages.Count - 1 do begin
    match := TRegEx.Match(Languages.LocaleName[i], cStatement1);
    if not match.Success then
      Assert(False, '');
    if (aISO.Equals(match.Groups[1].Value)) then begin
      match := TRegEx.Match(Languages.Name[i], cStatement2);
      if not match.Success then
        Assert(False, '');
      Exit(match.Groups[1].Value);
    end;
  end;
end;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25301159

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档