【Objective-C】NSDateFormatterにまつわるエトセトラ
NSDateFormatterでやらかしそうなやらかしたミスをメモっておく。
24時間表示をOFFにした際、dateFromStringによる正しく評価されない
前提として、「設定」>「一般」>「日付と時刻」>「24時間表示」 をOFFにしているものとします。
やらかした例
NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"yyyy/MM/dd HH:mm:ss"]; NSDate *theDay = [formatter dateFromString:@"2013/09/01 15:00:00"]; NSLog(@"%@", [theDay descriptionWithLocale:[NSLocale currentLocale]]);
コンソール出力
(null)
Oops...
正しい実装
NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"yyyy/MM/dd HH:mm:ss"]; [formatter setLocale:[NSLocale systemLocale]]; // ロケールにsystemLocaleを設定する NSDate *theDay = [formatter dateFromString:@"2013/09/01 15:00:00"]; NSLog(@"%@", [theDay descriptionWithLocale:[NSLocale currentLocale]]);
コンソール出力
2013年9月1日日曜日 午後3:00:00 日本標準時
※ちなみにシュミレータの設定には24時間表示のON/OFFがないため、実機でしか再現できないです。
ユーザ設定の暦によってstringFromDateの出力が意図しないものになる
前提として、「設定」>「一般」>「言語と地域」>「暦法」 を「和暦」に指定しているものとします。
やらかした例
NSDateFormatter *formatter2 = [[NSDateFormatter alloc] init]; [formatter2 setDateFormat:@"yyyy年MM月dd日 HH時mm分ss秒"]; NSString *dayString = [formatter2 stringFromDate:[NSDate date]]; NSLog(@"%@", dayString);
コンソール出力
0027年10月31日 午前5時52分55秒
Ooooops!
正しい実装
NSDateFormatter *formatter2 = [[NSDateFormatter alloc] init]; NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; [formatter2 setCalendar:calendar]; // setCalendarで表示したい暦を指定する。今回はグレゴリオ暦(西暦)。 [formatter2 setDateFormat:@"yyyy年MM月dd日 HH時mm分ss秒"]; NSString *dayString = [formatter2 stringFromDate:[NSDate date]]; NSLog(@"%@", [theDay descriptionWithLocale:[NSLocale currentLocale]]);
コンソール出力
2015年10月31日 午前5時54分32秒
参考
iOS6とNSDateFormatterと和暦と24時間表示オフで発生しやすいバグについて | Technology-Gym