最近发现线上项目突然取不到时间导致业务逻辑无法继续。开始不知道什么原因,后续发现用户使用的是12小时制。经过测试发现如下问题。
问题
NSString *dateStr = [NSString stringWithFormat:@"2022-06-01 00:00:00"];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSDate *date = [dateFormatter dateFromString:dateStr];
NSLog(@"--------------%@------------------",date);
12小时制
24小时制
注意⚠️:iOS 15.4
及以上,在12小时制下,通过字符串获取NSDate
取到的值为nil
。
NSDate *date = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSString *dateString = [dateFormatter stringFromDate:date];
NSLog(@"%@", dateString);
12小时制
24小时制
注意⚠️:iOS 15.4
及以上,在12小时制下,通过NSDate
获取时间字符串HH
情况下依旧取得12小时制结果。
原因
通过文档知道这是不遵守苹果开发规范导致的问题,在NSDateFormatter
使用方法都是不规范的。
注意⚠️:苹果官方对NSDateFormatter
的解释中可以看出,要想在任何时候输出固定格式的日期,需要设置.local
。
解决方法
##OC
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh_Hans_CN"];
// 或者
//dateFormatter.locale = [NSLocale systemLocale];
dateFormatter.calendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierISO8601];
##Swift
let formatter = DateFormatter()
formatter.locale = Locale.init(identifier: "zh_Hans_CN")
formatter.calendar = Calendar.init(identifier: .iso8601)
注意⚠️:如果我们需要使用日历相关,我们还需要设置dateFormatter
的日历格式。
dateFormatter.calendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierISO8601];
使用
如果我们项目中NSDateFormatter
使用地方比较多,那么可以封装一个NSDateFormatter
的方法或者使用Category
来替换。
+ (NSDateFormatter *)DateFormatter{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
dateFormatter.locale = [NSLocale systemLocale];
dateFormatter.calendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierISO8601];
return dateFormatter;
}