最近發(fā)現(xiàn)線上項(xiàng)目突然取不到時(shí)間導(dǎo)致業(yè)務(wù)邏輯無法繼續(xù)。開始不知道什么原因,后續(xù)發(fā)現(xiàn)用戶使用的是12小時(shí)制。經(jīng)過測(cè)試發(fā)現(xiàn)如下問題。
問題
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小時(shí)制

24小時(shí)制
注意??:iOS 15.4及以上,在12小時(shí)制下,通過字符串獲取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小時(shí)制

24小時(shí)制
注意??:iOS 15.4及以上,在12小時(shí)制下,通過NSDate獲取時(shí)間字符串HH情況下依舊取得12小時(shí)制結(jié)果。
原因
通過文檔知道這是不遵守蘋果開發(fā)規(guī)范導(dǎo)致的問題,在NSDateFormatter使用方法都是不規(guī)范的。
注意??:蘋果官方對(duì)NSDateFormatter的解釋中可以看出,要想在任何時(shí)候輸出固定格式的日期,需要設(shè)置.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)
注意??:如果我們需要使用日歷相關(guān),我們還需要設(shè)置dateFormatter的日歷格式。
dateFormatter.calendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierISO8601];
使用
如果我們項(xiàng)目中NSDateFormatter使用地方比較多,那么可以封裝一個(gè)NSDateFormatter的方法或者使用Category來替換。
+ (NSDateFormatter *)DateFormatter{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
dateFormatter.locale = [NSLocale systemLocale];
dateFormatter.calendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierISO8601];
return dateFormatter;
}