事象
サーバから取得した日付文字列をNSDateに変換する際に、想定と異なる変換結果が返却されてきた。
環境
- Objective-C
- iOS 9.3.2, 9.3.5
- XCode 7.3.1
実際のコード
NSString *serverResponse = @"2016/09/08 10:00:00";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDate *responseDate = [dateFormatter dateFromString:serverResponse];
NSLog(@"%@", responseDate.description);
実行結果
4004-09-08 01:00:00 +0000
原因
iPhoneの暦法が「和暦」に設定されていたため、「平成2016年09月08日」と認識されてしまった。
(平成元年は1989年のため、1989-1+2016=4004となる)
対応
端末の暦設定に関わらず、西暦としてNSDateに変換を行う。
+ (NSDate *)convertGregorioDate:(NSString *)convertTargetStr {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
formatter.locale = [NSLocale systemLocale];
formatter.timeZone = [NSTimeZone systemTimeZone];
formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSDate *resultDate = [formatter dateFromString:convertTargetStr];
return resultDate;
}
おわりに
開発時に一週間近く悩んだ問題で、コードからはなかなか見つけられなかった。
(トレースして1行ごとに変数をチェックすれば見つかったかもしれないが。)
サーバと通信して日付を文字列として返却するアプリなら必ず発生しうる問題なので、注意が必要。