iOS|一个与 NSDateFormatter 有关的小 Bug

简介: iOS APP 里的一个小 Bug,竟然与用户设置有关。

我们的 iOS APP 有一个小 Bug,场景简化后是这样:

接口返回一个时间字符串,APP 里比较它与当前时间,如果当前时间晚于它,就显示一个按钮,否则不显示。

本来是一个很简单的逻辑,但是,有一部分用户反馈,按钮该显示的时候却没有显示。

分析

结合用户反馈的信息,经过多次尝试后,才发现这个行为竟然与用户手机的时间制式有关——如果用户手机设置里的 24小时制 开关没有打开,那么这个 Bug 就会出现。

相关的逻辑是这样写的:

NSDate *remoteDate = [NSDate dateFromStr:remoteDateString];
if (remoteDate) {
    // 比较 remoteDate 和 本地当前时间,控制按钮显隐
}

这个 dateFromStr: 是一个 category 方法,实现是这样的:

+ (NSDate*)dateFromStr:(NSString *)dateStr {
    NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    return [dateFormatter dateFromString:dateStr];
}

经过调试,发现 remoteDate 在 24小时制 开关关闭时,返回的是 nil,而在打开时,返回的是正确的时间。

苹果官方文档里,NSDateFormatter 的 dateFromString: 方法是这样描述的:

Returns a date representation of a given string interpreted using the receiver’s current settings.

Return Value
A date representation of string. If dateFromString: can’t parse the string, returns nil.

同时还给出了 Working With Fixed Format Date Representations 的参考链接,里面有说明:

When working with fixed format dates, such as RFC 3339, you set the dateFormat property to specify a format string. For most fixed formats, you should also set the locale property to a POSIX locale ("en_US_POSIX"), and set the timeZone property to UTC.

这个页面里还给出了一个 QA 链接 Technical Q&A QA1480 “NSDateFormatter and Internet Dates”,里面有这样的描述:

On iOS, the user can override the default AM/PM versus 24-hour time setting (via Settings > General > Date & Time > 24-Hour Time), which causes NSDateFormatter to rewrite the format string you set, which can cause your time parsing to fail.
...
On the other hand, if you're working with fixed-format dates, you should first set the locale of the date formatter to something appropriate for your fixed format.

里面提到了用户可以通过设置 24小时制 来影响 NSDateFormatter 的行为,还提到了当尝试把固定格式的日期字符串转换成日期对象时,应该设置 locale。

至此破案了,这个 Bug 就是由于没有设置 NSDateFormatter 的 locale 属性导致的。

解决

修改后的代码是这样的,仅加了一行 locale 设置:

+ (NSDate*)dateFromStr:(NSString *)dateStr {
    NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    [dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]];
    return [dateFormatter dateFromString:dateStr];
}

经过测试功能正常了,不管用户手机的 24小时制 开关是否打开,都能正常解析服务端返回的时间字符串了。

参考


如果读完文章有收获,可以关注我的微信公众号「闷骚的程序员」并🌟设为星标🌟,随时阅读更多内容。

目录
相关文章
|
安全 iOS开发
记录IOS16的一个非常严重的bug
记录IOS16的一个非常严重的bug
313 1
|
iOS开发
iOS 第三方dSYM定位BUG
iOS 第三方dSYM定位BUG
357 0
|
文字识别 定位技术 vr&ar
iOS 15体验:更新不少,BUG更多(中)
昨天介绍了iOS 15的诸多更新,今天继续介绍iOS 15上的一些有意思的新功能。
445 0
|
iOS开发
iOS 二级页面返回一级页面导航栏错位bug解决方法
iOS 二级页面返回一级页面导航栏错位bug解决方法
1072 0
|
iOS开发
iOS UITableViewCell嵌套CollectionView,tableview和collectionview同时滑动bug修复
iOS UITableViewCell嵌套CollectionView,tableview和collectionview同时滑动bug修复
1366 0
iPhone7、7P iOS10.2及以下系统转场动画出现白屏bug的解决办法
iPhone7、7P iOS10.2及以下系统转场动画出现白屏bug的解决办法
530 0
|
iOS开发
IOS学习笔记之十七 (NSDate、NSDateFormatter、NSCalendar、NSDateComponents、NSTimer)
IOS学习笔记之十七 (NSDate、NSDateFormatter、NSCalendar、NSDateComponents、NSTimer)
279 0
|
安全 网络架构 iOS开发
以科研的名义 思科IOS bug造成1%互联网瘫痪,互联网营销
  思科已经修复了IOS(Internetwork Operating System)路由器软件中的一个bug,上周,这个bug引发了短暂的互联网停电事故,据说这次事故影响到了1%的互联网。   这个bug是上周五发现的,当时,RIPE NCC (Reseaux IP Europeens Network Coordination Centre)和杜克大学的一些研究者正在通过RIPE NCC的系统分发实验性的BGP (Border Gateway Protocol)数据。
1098 0
|
机器学习/深度学习 安全 算法
【阿里聚安全·安全周刊】一种秘密窃取数据的新型 Android 木马|iOS 11相机惊现BUG
阿里安全周刊第九十期,分享本周移动安全热点和技术知识。
2164 0
|
iOS开发 定位技术