HOME » Natsu note » iOS » NSNumberFormatterを用いて賢く国際化

NSNumberFormatterを用いて賢く国際化 2013/12/25/|iOS, ,

先日たまたまこんなツイートを見かけました。

去年まで暮らしていたドイツでは後者(日本とはカンマとコンマが逆)の表記が用いられていました。実はカンマとコンマの他にも、3桁区切りの文字がスペースだったり、国や地域によって様々な表現方法があります。金額表示も、通貨単位が数字の前に来るケースと後ろに来るケースがあったりします。

アプリ開発で数字を扱うとき、このようなことを意識したことはありますか?家計簿アプリや電卓アプリなどでは、是非とも意識したいところですね。

この地域ごとのサポートですが、わざわざ一つずつ設定していくのは大変です。しかし、iOSにはNSNumberFormatterという強力な助っ人がいるので心配ご無用です。このことをツイートしたら興味を持っている方いるようだったので、基本事項を解説します。

強力な助っ人: NSNumberFormatter

NSNumberFormatterとは、Localeに適した数字表記をしてくれる優れものです(ちなみに、日付の表記にはNSDateFormatterを使います)。使い方はとても簡単なので、覚えておいて損はないでしょう。

まず、表示したい内容に合わせてフォーマッターのスタイル(NSNumberFormatterStyle)を設定します。スタイルには以下の6種類があります。

  • NSNumberFormatterNoStyle
  • NSNumberFormatterDecimalStyle
  • NSNumberFormatterCurrencyStyle
  • NSNumberFormatterPercentStyle
  • NSNumberFormatterScientificStyle
  • NSNumberFormatterSpellOutStyle

さらに、必要に応じてLocaleの設定を行い、あとは数字を与えて文字列を取得します。なお、Localeはデフォルトではユーザー設定(言語環境→書式)が用いられるようになっています。

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
NSLocale *locale = ...;
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[formatter setLocale:locale];

// フォーマッターを利用した文字列
double value = 1234.5678;
NSString *formattedString = [formatter stringFromValue:@(value)];

それぞれのスタイルとLocaleで表示される結果については、最後のスクリーンショットを見てください。

NSNumberFormatterNoStyle

例として、Localeを日本(ja_JP)にした場合とドイツ(de_DE)にした場合の、各スタイルで生成される文字列を見ていきます。まずは、NSNumberFormatterNoStyle、つまりスタイル指定をしない場合です。元の値はdoubleで1234.5678です。

ja_JP: 1234
de_DE: 1234

小数点以下が表示されていません。その理由は、NoStyleではmaximumFractionDigitsプロパティの値が0となっているためです。小数点以下の表示桁数は、minimumFractionDigitsとmaximumFractionDigitsを用いて設定します。試しにmaximumFractionDigitsを4としてみると、以下のような結果になります。

ja_JP: 1234.5678
de_DE: 1234,5678

ここでさっそく、Twitterで話題となっていたカンマとコンマの違いが出てきました。ただし、NoStyleの場合セパレータ(3桁ごとの区切り)はデフォルトでは表示されません。

NSNumberFormatterDecimalStyle

小数点以下の値も含めた一般的な数字の表現には、このNSNumberFormatterDecimalStyleを利用するのがよいでしょう。こちらは、NSNumberFormatterNoStyleとは異なり、セパレータまできちんと面倒をみてくれます。結果は以下のようになります。

ja_JP: 1,234.568
de_DE: 1.234,568

セパレータが日本では”,”ドイツでは”.”となっているのが確認できると思います。

DecimalStyleにおけるmaximumFractionDigitsのデフォルト値は3です。そのため、小数点以下第四位が四捨五入され、1234.568と表示されるわけです。ここで、四捨五入の代わりに切り上げや切り捨て等を用いたい場合は、roundingModeプロパティの値を変更します。

decimalFormatter.roundingMode = NSNumberFormatterRoundFloor;

これで有効桁数以下が切り捨てされた表示になります。

NSNumberFormatterCurrencyStyle

続いて通貨表示に最適なNSNumberFormatterCurrencyStyleです。これは本当に便利です。各国の通貨単位や記号など知らなくても世界各国に対応したアプリが作れてしまいます。

ja_JP: ¥1,235
de_DE: 1.234,57 €

注目すべき点は以下です。

  • 適切な通貨単位を表示してくれる
  • 適切な位置に通貨単位を表示してくれる(数字の前か後か)
  • 小数点以下を適切な桁数で表示してくれる(日本は円までで銭は表示しない)

もちろん、これらの表示方法はフォーマッターの設定で変更が可能です。しかし、デフォルトで一般的な状態になっているということは非常に重要です。

サンプルアプリでも確認いただけますが、スウェーデンクローナなどはその表示方法が面白くて、「1 234:57 kr」となるようです(フォーマッターはこのように返してきますが、現地で実際にこう表示されているかは定かではありません)。こういうのは、一つ一つ調べていくときりがないので、フォーマッターにお任せするのが一番です。

NSNumberFormatterPercentStyle

次は、パーセント表示に最適化されているNSNumberFormatterPercentStyleです。このスタイルは、1を100%と表示します。そのため、渡す値に注意が必要です(1が1%ではない)。これまでどおり、1234.5678を渡すと以下のように表示されます。

ja_JP: 123,457%
de_DE: 123.457 %

この値ではあまり意味がないので、試しに0.567を渡してみましょう。

ja_JP: 57%
de_DE: 57 %

minimumFractionDigitsのデフォルト値が0であるため、小数点以下が四捨五入され57%と表示されます。日本の表記とドイツの表記では、数字とパーセント記号の間にスペースのあり・なしの違いがあります。これらもフォーマッターがすべて管理してくれています。

小数点以下まで表示するためにminimumFractionDigitsを2にしてみると、結果は以下のようになります。

ja_JP: 56.70%
de_DE: 56,70 %

また、ここでも、コンマとカンマの違いが確認できました。

NSNumberFormatterScientificStyle

残るスタイルは2つです。NSNumberFormatterScientificStyleでは指数表記が使われます。あまり活用場面が思いつきませんが、特殊なアプリを作ろうと思ったら必要になってくるかも知れません。

ja_JP: 1.2345678E3
de_DE: 1,2345678E3

NSNumberFormatterSpellOutStyle

最後はNSNumberFormatterSpellOutStyleです。これは、数字を読みあげた場合の文字として表現します。例えば、これまでの例と同じく1234.5678を渡すと結果は以下のようになります。ドイツ語だと分かりにくいと思うので英語の結果も付けておきます。

ja_JP: 千二百三十四・五六七八
de_DE: ein­tausend­zwei­hundert­vier­und­dreißig Komma fünf sechs sieben acht
en_US: one thousand two hundred thirty-four point five six seven eight

こちらもあまり活用場面は思いつきませんが、英語やドイツ語の勉強にはなりそうですね・・・。

以上がNSNumberFormatterの基本的な使い方になります。ほかにも、負の値だけ色を変えるとか、特定のフォーマットを独自に指定するとか、機能は多彩ですが、こちらはまた機会があれば別途記事にしたいと思います。

ここで紹介したような内容であれば、少々の応用は簡単にできます。ぜひリファレンスガイドを眺めてみてください。

Localeを指定して通過単位の文字を取得するなどのこともできますので、数字を表示する以外にも使い道はたくさんあります。

世界各国でiOSデバイスが利用されるようになった今、国際化は非常に重要です。できるだけ手間なく確実に国際化を進めるためにも、数字の取り扱いにはぜひNSNumberFomatterの利用をお勧めします。

非常に簡単ですがサンプルコードがGitHubにあります。
NumberFormatterSample

このサンプルでは、値1234.5678をja_JP, en_US, de_DE, sv_SEのLocaleに対して各スタイルで表示します。実行してみるとカンマやコンマ等の表記法が様々であることを確認いただけると同時に、NSNumberFormatterを利用する意味が理解できると思います。

NumberFormatterSample実行結果NumberFormatterSample実行結果

NumberFormatterSample実行結果NumberFormatterSample実行結果


本を書きました。iOS 7の新機能、拡張機能については、是非こちらもどうぞ。