96
81

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

iOSの"24時間表示"切り替えのワナ

Last updated at Posted at 2014-07-23

ものすごいトラップに引っかかったのでメモ代わりに。

iOSで日付や時間を取り扱う際はNSDateクラスとNSDateFormatterを使用します。日付から文字列にする際はこのように出力フォーマットを指定します。

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = @"yyyy/MM/dd HH:mm:ss";

NSDate *date = [NSDate date];
NSString *formatString = [dateFormatter stringFromDate:date];

逆に文字列から日付にする際はこんな感じです。

NSString *dateString = @"2014/07/23 12:00:00";

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = @"yyyy/MM/dd HH:mm:ss";

NSDate *date = [dateFormatter dateFromString:dateString];

だいたいこんな感じで問題なく使っていると思います。

が。

実はこの変換がうまく行かない場合があります。
時間表示が午前/午後表記=24時間表示がオフの場合です。

時間表記の切り替えは設定 > 一般 > 日付と時刻から選択できます。

デフォルトはこちら。
timeformat_01.png

こちらがオフ。
timeformat_02.png

ステータスバーに表示されている時間を見ると分かりやすいと思います。

この設定をしたときに文字列から日付への変換がうまくいきません。dateFromStringからnilが返ってきます。NSDictionaryに入れようとすると最悪な事態になりますね。落ちます。

問題となるパターンとしては、日付のフォーマットを@"yyyy/MM/dd HH:mm:ss"のようにベタ打ちしているパターン、csvファイルなどに日付フォーマットを決めて書かれているものを読み込んでNSDateに変換しようとするパターンなど、フォーマットを固定して使用している場合がこれにあたります。

しかも困ったことに**シミュレーターは24時間表示切り替えができません。**実機で検証した上で、24時間表示の切り替えがあることを考慮してテストを行わないといけませんね。

で、これをどうやって解決したら良いか?こちらのドキュメントを参照してみましょう。ここにはこんなことが書かれています。

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. In most cases the best locale to choose is "en_US_POSIX", a locale that's specifically designed to yield US English results regardless of both user and system preferences.

Google翻訳してみます(翻訳原文ママ)。

あなたは固定形式の日付で作業している一方、は、まず固定フォーマットに適したものに日付フォーマッタのロケールを設定する必要があります。ほとんどの場合、選択するのが最善のロケールが「en_US_POSIX」は、具体的に関係なく、ユーザとシステム環境の両方の米国英語の結果をもたらすように設計されていますロケールです。

ということなので、固定フォーマットの文字列を日付に変換する際はen_US_POSIXNSDateFormatterのロケールに指定しましょう。

NSString *dateString = @"2014/07/23 12:00:00";

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = @"yyyy/MM/dd HH:mm:ss";
dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];

NSDate *date = [dateFormatter dateFromString:dateString];

これで文字列から日付への変換は問題なくできるようになります。

96
81
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
96
81

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?