将时区名称转换为时间标识符

4
我发现iOS框架无法理解正确的时区名称,例如“Eastern Standard Time”。如果您输入以下内容:
NSLog(@"EST: %@", [NSTimeZone timeZoneWithName:@"Eastern Standard Time"]);

EST: (null)

相反,您必须使用时间ID(一个更窄的区域),例如“美国/纽约”:

NSLog(@"EST: %@", [NSTimeZone timeZoneWithName:@"America/New_York"]);

当我输入命令时,控制台会友好地回应:

美国东部时间:美国/纽约 (GMT-4),偏移量为-14400(夏令时)

有没有办法将时区名称翻译成时区ID?因为我使用的Web API提供的是时区名称,而不是时区ID。


你需要映射的名称是否有完整列表?我只熟悉America/New_York格式。 - dwlz
我需要映射人类所知的每个时区名称。我正在制作一个可以处理全球位置和时间的应用程序。我认为Windows使用像“东部标准时间”这样的时区名称,因此我猜测API在某种程度上是基于Windows的。 - turingtested
2个回答

9

这是我采用的方法。(虽然很蠢,但它可行。)我使用了位于unicode.org的Windows/TZID时区映射,并围绕一个大字典编写了一个方法。

- (NSString*) translateFromWindowsTimezone: (NSString*) timezoneName{
    NSDictionary *timezoneDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                                @"Australia/Darwin", @"AUS Central Standard Time",
                                @"Asia/Kabul", @"Afghanistan Standard Time",
                                @"America/Anchorage", @"Alaskan Standard Time",
                                @"Asia/Riyadh", @"Arab Standard Time",
                                @"Asia/Baghdad", @"Arabic Standard Time",
                                @"America/Buenos_Aires", @"Argentina Standard Time",
                                @"America/Halifax", @"Atlantic Standard Time",
                                @"Asia/Baku", @"Azerbaijan Standard Time",
                                @"Atlantic/Azores",@"Azores Standard Time",
                                @"America/Bahia", @"Bahia Standard Time",
                                @"Asia/Dhaka", @"Bangladesh Standard Time",
                                @"America/Regina", @"Canada Central Standard Time",
                                @"Atlantic/Cape_Verde", @"Cape Verde Standard Time",
                                @"Asia/Yerevan", @"Caucasus Standard Time",
                                @"Australia/Adelaide", @"Cen. Australia Standard Time",
                                @"America/Guatemala", @"Central America Standard Time",
                                @"Asia/Almaty", @"Central Asia Standard Time",
                                @"America/Cuiaba", @"Central Brazilian Standard Time",
                                @"Europe/Budapest", @"Central Europe Standard Time",
                                @"Europe/Warsaw", @"Central European Standard Time",
                                @"Pacific/Guadalcanal", @"Central Pacific Standard Time",
                                @"America/Chicago", @"Central Standard Time",
                                @"America/Mexico_City", @"Central Standard Time (Mexico)",
                                @"Asia/Shanghai", @"China Standard Time",
                                @"Etc/GMT+12", @"Dateline Standard Time",
                                @"Africa/Nairobi", @"E. Africa Standard Time",
                                @"Australia/Brisbane", @"E. Australia Standard Time",
                                @"Asia/Nicosia", @"E. Europe Standard Time",
                                @"America/Sao_Paulo", @"E. South America Standard Time",
                                @"America/New_York", @"Eastern Standard Time",
                                @"Africa/Cairo", @"Egypt Standard Time",
                                @"Asia/Yekaterinburg", @"Ekaterinburg Standard Time",
                                @"Europe/Kiev", @"FLE Standard Time",
                                @"Pacific/Fiji", @"Fiji Standard Time",
                                @"Europe/London", @"GMT Standard Time",
                                @"Europe/Bucharest", @"GTB Standard Time",
                                @"Asia/Tbilisi", @"Georgian Standard Time",
                                @"America/Godthab", @"Greenland Standard Time",
                                @"Atlantic/Reykjavik", @"Greenwich Standard Time",
                                @"Pacific/Honolulu", @"Hawaiian Standard Time",
                                @"Asia/Calcutta", @"India Standard Time",
                                @"Asia/Tehran", @"Iran Standard Time",
                                @"Asia/Jerusalem", @"Israel Standard Time",
                                @"Asia/Amman", @"Jordan Standard Time",
                                @"Europe/Kaliningrad", @"Kaliningrad Standard Time",
                                @"Asia/Seoul", @"Korea Standard Time",
                                @"Indian/Mauritius", @"Mauritius Standard Time",
                                @"Asia/Beirut", @"Middle East Standard Time",
                                @"America/Montevideo", @"Montevideo Standard Time",
                                @"Africa/Casablanca", @"Morocco Standard Time",
                                @"America/Denver", @"Mountain Standard Time",
                                @"America/Chihuahua", @"Mountain Standard Time (Mexico)",
                                @"Asia/Rangoon", @"Myanmar Standard Time",
                                @"Asia/Novosibirsk", @"N. Central Asia Standard Time",
                                @"Africa/Windhoek", @"Namibia Standard Time",
                                @"Asia/Katmandu", @"Nepal Standard Time",
                                @"Pacific/Auckland", @"New Zealand Standard Time",
                                @"America/St_Johns", @"Newfoundland Standard Time",
                                @"Asia/Irkutsk", @"North Asia East Standard Time",
                                @"Asia/Krasnoyarsk", @"North Asia Standard Time",
                                @"America/Santiago", @"Pacific SA Standard Time",
                                @"America/Los_Angeles", @"Pacific Standard Time",
                                @"America/Santa_Isabel", @"Pacific Standard Time (Mexico)",
                                @"Asia/Karachi", @"Pakistan Standard Time",
                                @"America/Asuncion", @"Paraguay Standard Time",
                                @"Europe/Paris", @"Romance Standard Time",
                                @"Europe/Moscow", @"Russian Standard Time",
                                @"America/Cayenne", @"SA Eastern Standard Time",
                                @"America/Bogota", @"SA Pacific Standard Time",
                                @"America/La_Paz", @"SA Western Standard Time",
                                @"Asia/Bangkok", @"SE Asia Standard Time",
                                @"Pacific/Apia", @"Samoa Standard Time",
                                @"Asia/Singapore", @"Singapore Standard Time",
                                @"Africa/Johannesburg", @"South Africa Standard Time",
                                @"Asia/Colombo", @"Sri Lanka Standard Time",
                                @"Asia/Damascus", @"Syria Standard Time",
                                @"Asia/Taipei", @"Taipei Standard Time",
                                @"Australia/Hobart", @"Tasmania Standard Time",
                                @"Asia/Tokyo", @"Tokyo Standard Time",
                                @"Pacific/Tongatapu", @"Tonga Standard Time",
                                @"Europe/Istanbul", @"Turkey Standard Time",
                                @"America/Indianapolis", @"US Eastern Standard Time",
                                @"America/Phoenix", @"US Mountain Standard Time",
                                @"Etc/GMT", @"UTC",
                                @"Etc/GMT-12", @"UTC+12",
                                @"Etc/GMT+2", @"UTC-02",
                                @"Etc/GMT+11", @"UTC-11",
                                @"Asia/Ulaanbaatar", @"Ulaanbaatar Standard Time",
                                @"America/Caracas", @"Venezuela Standard Time",
                                @"Asia/Vladivostok", @"Vladivostok Standard Time",
                                @"Australia/Perth", @"W. Australia Standard Time",
                                @"Africa/Lagos", @"W. Central Africa Standard Time",
                                @"Europe/Berlin", @"W. Europe Standard Time",
                                @"Asia/Tashkent", @"West Asia Standard Time",
                                @"Pacific/Port_Moresby", @"West Pacific Standard Time",
                                @"Asia/Yakutsk", @"Yakutsk Standard Time", nil];
   return [timezoneDictionary objectForKey:timezoneName];
}

要使用它,只需输入:

NSString *tzidTimezoneName = [self translateFromWindowsTimezone: someWindowsTimezoneName];

如果您使用此代码,请在发现任何错误或缺少时区的情况下进行评论!

2
真痛苦,我们不得不这样做,但还是谢谢! - rebello95
1
顺便说一下,我喜欢设置为“Europe/Paris”的“浪漫标准时间” :) 彩蛋? - turingtested

0

我不知道任何标准会使用您称之为“正确的时区名称”的内容。它们是与区域设置相关的,在夏天和冬天之间变化等。尽管如此,以下代码将实现您所描述的功能:

- (NSTimeZone *)timeZoneForLongName:(NSString *)longName {

    NSLocale    *locale=[[NSLocale alloc]initWithLocaleIdentifier:@"en_US"];

    for(NSString *name in NSTimeZone.knownTimeZoneNames)
    {
        NSTimeZone *tz=[NSTimeZone timeZoneWithName:name];

        if([[tz localizedName:NSTimeZoneNameStyleStandard locale:locale]isEqualToString:longName]
           || [[tz localizedName:NSTimeZoneNameStyleDaylightSaving locale:locale]isEqualToString:longName]
           )
        {
            return tz;
        }
    }

    return nil;
}

无法工作!我从NSLog(@"EST: %@", [self timeZoneForLongName:@"Eastern Standard Time"]);得到的回应是EST:America/Atikokan,这是错误的。 - turingtested
然而,我发现了一个将Windows时区名称映射到TZID(Xcode正在使用的)的网站:http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/zone_tzid.html - turingtested
“EST: America/Atikokan” 不是错误的,它只是众多正确答案之一。使用“Eastern Standard Time”作为输入,并期望输出为纽约(而不是任何其他由EST管理的城市之一)是有缺陷的。顺便说一下,Xcode是一个集成开发环境。 - Gerd K
是的,我知道。但如果你写下: NSLog(@“GMT秒数:%i”,[[NSTimeZone timeZoneWithName:@“America / New_York”] secondsFromGMT]);...你会在控制台中得到: GMT秒数:-14400而且: NSLog(@“GMT秒数:%i”,[[NSTimeZone timeZoneWithName:@“America / Atikokan”] secondsFromGMT]);...你得到的是: GMT秒数:-18000 ...不一样。 - turingtested

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接