将具有单独时区的日期对象转换为NSDate的正确方法是什么

时间:2018-12-01 15:36:05

标签: ios nsdate nsdateformatter

我的应用程序从Web服务(PHP)提取数据,该数据以以下格式提供日期:

        endDate =             {
            date = "2020-09-30 16:16:08.000000";
            timezone = "-04:00";
            "timezone_type" = 1;
        };

这是我一直用于转换为NSDate的代码,据我所知,它在每次测试中都有效,但是根据用户报告和调试日志,它在某些设备上失败。

请注意,此日期的正确转换将确定内容是否在应用程序中解锁,因此,如果失败,则客户会与我们联系。

             NSDictionary* dateDict = [responseDict objectForKey:@"endDate"];
             NSString* strEndDate = [dateDict objectForKey:@"date"];
             NSString* strOffset = [dateDict objectForKey:@"timezone"];

             NSTimeInterval zoneSeconds = 0;
             NSRange rng = [strOffset rangeOfString:@":"];
             if (rng.location != NSNotFound && rng.location >= 1)
             {
                 NSString* hoursOnly = [strOffset substringToIndex:rng.location];   
                 NSInteger offsetValue = [hoursOnly integerValue];
                 zoneSeconds = (3600 * offsetValue);
             }

             NSDateFormatter* df = [[NSDateFormatter alloc] init];
             NSTimeZone *timeZone = [NSTimeZone timeZoneForSecondsFromGMT:zoneSeconds];
             [df setTimeZone:timeZone];
             [df setDateFormat:@"yyyy-MM-dd HH:mm:ss.000000"];

             NSDate* newEndDate = [df dateFromString:strEndDate];

但是,一些用户的调试日志显示dateFromString调用失败并返回nil。

我们有一个拥有2台iOS设备的用户,并且使用相同的帐户(相同的日期),该应用在其中一台上的运行正常,但在另一台上失败。相同的Apple ID,都运行iOS12。调试日志显示两个设备都从服务器收到了相同的日期,但是其中一个未能将日期从字符串转换为NSDate。

到目前为止,我的假设是设备上的某些设置或配置失败会有所不同。但是我整日都在摆弄日历和日期设置,因此不能失败。我知道有问题的用户将两个设备都配置为相同的时区。

是否有更好,更正确的方法来进行日期转换,这可能会更可靠?

2 个答案:

答案 0 :(得分:0)

使用任意日期格式it's highly recommended to set the locale of the date formatter to the fixed value en_US_POSIX时。

与其计算格林尼治标准时间的秒数,不如使用正则表达式剥离毫秒,附加字符串时区并使用适当的日期格式,可能会更有效。

此代码使用更现代的语法来设置带点符号和字典文字键订阅的日期格式化程序属性

NSDictionary *dateDict = responseDict[@"endDate"];
NSString *strEndDate = dateDict[@"date"];
NSString *strTimeZone = dateDict[@"timezone"];
NSString *dateWithoutMilliseconds = [strEndDate stringByReplacingOccurrencesOfString:@"\\.\\d+" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, strEndDate.length)];
NSString *dateWithTimeZone = [NSString stringWithFormat:@"%@%@", dateWithoutMilliseconds, strTimeZone];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
df.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
df.dateFormat = @"yyyy-MM-dd HH:mm:ssZZZZZ"];
NSDate *newEndDate = [df dateFromString:dateWithTimeZone];

答案 1 :(得分:0)

这个问题实际上与最初建议的(What is the best way to deal with the NSDateFormatter locale "feechur"?)类似,但这是另一个问题(NSDateFormatter fails to return a datetime for UK region with 12 hour clock set)确实让我点击了它-拥有12小时制的英国地区这会导致代码失败,但是通过简单地将语言环境设置为“ un_US_POSIX”,即可轻松解决dateFormatter的问题(在该问题的答案中也曾提出过建议(但在vadian的建议下,我也没有尝试过他的代码))。感谢所有提供提示和线索的人!