2

我有一个使用 CLGeocoder 从地址字符串转发地标的应用程序。CLPlacemark 响应包含一个 CLLocation,它为我提供 GPS 坐标。

创建 NSTimeZone 的唯一方法似乎是使用正确的时区名称。需要指出的是,我没有使用设备的当前位置,因此 [NSTimeZone localTimeZone] 对我不起作用。

有没有办法获取 CLLocation 的时区名称,以便我可以正确创建 NSTimeZone?

注意:我一直在使用 timeZoneForSecondsFromGMT,但它从不包含正确的 DST 数据,所以它对我没有帮助。

4

3 回答 3

3

您应该使用https://github.com/Alterplay/APTimeZones从 CLLocation 获取 NSTimeZone。它也适用于 CLGeocoder。

于 2013-10-21T16:47:11.500 回答
1

由于 iOS9 应该可以直接使用CLGeocoder这里指定的:https ://developer.apple.com/library/prerelease/ios/releasenotes/General/WhatsNewIniOS/Articles/iOS9.html

MapKit 和 CLGeocoder 的搜索结果可以为结果提供时区。

于 2015-07-08T05:12:40.473 回答
0

我发现了一种使用 CLGeocoder 的有趣方法,我将其放入 CLLocation 上的一个类别中。有趣的部分如下所示:

-(void)timeZoneWithBlock:(void (^)(NSTimeZone *timezone))block {        
    [[[CLGeocoder alloc] init] reverseGeocodeLocation:self completionHandler:^(NSArray *placemarks, NSError *error) {           
        NSTimeZone *timezone = nil;

        if (error == nil && [placemarks count] > 0) {               
            CLPlacemark *placeMark = [placemarks firstObject];
            NSString *desc = [placeMark description];

            NSRegularExpression  *regex  = [NSRegularExpression regularExpressionWithPattern:@"identifier = \"([a-z]*\\/[a-z]*_*[a-z]*)\"" options:NSRegularExpressionCaseInsensitive error:nil];
            NSTextCheckingResult *result = [regex firstMatchInString:desc options:0 range:NSMakeRange(0, [desc length])];

            NSString *timezoneString = [desc substringWithRange:[result rangeAtIndex:1]];

            timezone = [NSTimeZone timeZoneWithName:timezoneString];
        }
        block(timezone);            
    }];
}

用法是这样的:

CLLocation *myLocation = ...
[myLocation timeZoneWithBlock:^(NSTimeZone *timezone) {
    if (timezone != nil) {
        // do something with timezone
    } else {
        // error determining timezone
    }
}];

尽管需要网络连接和异步工作,但我发现这是获取某个位置的时区的最可靠方法。

多年后编辑

自从在 iOS9 中将 timeZone 属性添加到 CLPlacemark 以来,这个答案并没有很好地老化(感谢 Ortwin Genz)。这是一个更新的类别方法:

-(void)timeZoneWithBlock:(void (^)(NSTimeZone *timezone))block {

    [[[CLGeocoder alloc] init] reverseGeocodeLocation:self completionHandler:^(NSArray *placemarks, NSError *error) {

        NSTimeZone *timeZone = nil;

        if (error == nil && [placemarks count] > 0) {
            CLPlacemark *placeMark = [placemarks firstObject];
            timeZone = placeMark.timeZone;
        }

        block(timeZone);

    }];

}
于 2015-02-18T07:05:37.737 回答