BLOGサブスレッドの日常
2017.03.09
NSDataFormatterで気をつけること
chao
はじめに
しみずです。どうぞよろしく。
iOSの開発をしている時に、和暦表示にしたり本体設定の24時間表示をOFFにした場合
NSDateFormatterの挙動に気をつけることがあったので、書き残しておきます。
24時間表示をOFFにした場合の挙動
本体設定から24時間表示をOFFにできます。
一般 > 日付と時刻 > 24時間表示 これをOFFに。
ちなみにシミュレータからはこの設定できないようですので実機で確認しましょう。
24時間OFFにした場合、きちんと対策をしないと NSDateFormatter の dateFromString で nil が返ってきてしまいます。
// NSDateFormatter初期化
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
// 文字列 > NSDate へ変換
let date = formatter.dateFromString("2017-03-09 10:00:00")
// date => nil
date が nil なので、その後のコードの書き方次第で
最悪アプリが落ちてしまう事も考えられますね。
和暦表示にした場合の挙動
こちらも本体設定から和暦表示に設定を行えます。
一般 > 日付と時刻 > 歴法 これを和暦に。
和暦にした場合、NSDateFormatter の年の部分が和暦で扱われます。
例えば、本日の日付をNSDateFormatterを用いて文字列にした場合
今年は平成29年なので、年の部分が29になります。
// NSDateFormatter初期化
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
// 本日を文字列に変換
let dateString = formatter.stringFromDate(NSDate())
// dateString => "0029-03-09 20:16:13"
上記コードでは、年の部分を yyyy と4桁にしているので
年は 0029 となっています。
また、逆に文字列からNSDateに変換する時も年の部分は和暦なので
西暦で指定してしまうと凄い値になってしまいます。
let date = formatter.dateFromString("2017-03-09 10:00:00")
// date => 4005-03-09 10:00:00(JST)
年が 4005年になってますね。
平成元年が 1989年から始まっているので、そこから2016年後の値(平成元年分マイナス1しています)になります。
1989 + 2016 = 4005 ですね。
修正方法
24時間表示、和暦共に以下のように、locale プロパティに "en_US_POSIX" を指定すれば
本体設定に関わらず常に同じ値が取れてくるようになります。
コード上は常に西暦&24時間で扱います。
// NSDateFormatter初期化
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") // ← コレを追加
// 文字列 > NSDate へ変換
let date = formatter.dateFromString("2017-03-09 10:00:00")
// date => 2017-03-09 10:00:00(JST)
// 本日を文字列に変換
let dateString = formatter.stringFromDate(NSDate())
// dateString => "2017-03-09 20:16:13"
参考:https://developer.apple.com/library/content/qa/qa1480/_index.html
おわりに
たまに不具合が出てしまうNSDateFormatter関連のお話でした。
これに早く気づくために、テスト用端末の数台には和暦表示や24時間表示OFFにしておくと良いですね。
この記事を書いた人
chao