20

NSNumberFormatter は、ユーロ (およびおそらく他の) 通貨文字列を数値型に解析できないようです。誰かが私が間違っていることを証明できますか.

次を使用して、通貨文字列から数値を取得しようとしています:

NSNumberFormatter *currencyFormatter = [[[NSNumberFormatter alloc] init] autorelease];
[currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
NSNumber *currencyNumber = [currencyFormatter numberFromString:currencyString];

これは、英国および米国の通貨の金額で問題なく機能します。$ と £ および千単位の区切り記号も問題なく処理します。

ただし、ユーロ通貨の金額 (設定アプリで地域形式をフランスまたはドイツに設定) で使用すると、空の文字列が返されます。次の文字列はすべて失敗します。

12,34 €
12,34
12.345,67 €
12.345,67

これらの文字列は、対応するロケールを使用するときに NSNumberFormatter の stringFromNumber メソッドから得られるものと正確に一致することに注意してください。

設定アプリで Region Format を France に設定し、次のコードで currencyNumber を 12.34 に設定すると、 currencyString が '12,34 €' に設定されます。

NSNumberFormatter *currencyFormatter = [[[NSNumberFormatter alloc] init] autorelease];
[currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
NSString *currencyString = [currencyFormatter stringFromNumber:currencyNumber];

特にユーロでこの問題をハッキングするのは明らかにかなり簡単ですが、できるだけ多くの国でこのアプリを販売したいと考えており、同様の状況が他のロケールでも発生する可能性があると考えています.

誰か答えがありますか?

ティア、ダンカン

4

7 に答える 7

20

これは難しい問題です。次の作業を問題なく実行します。

double moneyAmount = 1256.34;
NSLocale *french = [[NSLocale alloc] initWithLocaleIdentifier:@"fr_FR"]; 
NSNumberFormatter *currencyStyle = [[NSNumberFormatter alloc] init];

[currencyStyle setLocale:french];
[currencyStyle setNumberStyle:NSNumberFormatterCurrencyStyle];
NSNumber *amount = [NSNumber numberWithDouble:moneyAmount];
NSString *amountString =  [currencyStyle stringFromNumber:amount];

NSNumber *pAmount = [currencyStyle numberFromString:amountString]; // == 1256.34

ただし、この-currencyGroupingSeparatorメソッドの出力は、予想される ではなく、改行なしのスペース\u00a0であるstring を返します。,

OS X / iOS のフォーマッタ クラス (および正規表現クラスなど) は、他のプロジェクトでも使用されているICU ライブラリを利用します。この特定の問題に関して、他に少なくとも2 つのバグレポートを見つけました。ただし、これは予想される動作のようです。(これが定義されている場所を見つけるために ICU のソースをふるいにかけるのに時間を費やしましたが、迷路です。)

当分の間-setLenient:YES、通貨フォーマッターに渡すことをお勧めします。おそらく、Apple のレーダーにバグレポートを提出することさえあります。

于 2010-10-10T03:35:17.923 に答える
2

設定で地域をフランスに設定してから、文字列の数値を取得しようとしましたか?または、を使用して数値フォーマッタのローカルを手動で設定することもできますsetLocale:。NSNumberFormatterは、数値が文字列であるかどうかを把握するために必要なロケールを使用します。ユーザーが自分の地域のローカライズされた通貨文字列を入力できるようにするだけでよい場合は、システムをそのロケールに変更してからテストします。ユーザーが複数の形式を入力できるようにする必要がある場合は、ユーザーが何を入力しているかがわかるように、ある種の選択システムを追加します。

于 2010-08-25T21:16:47.753 に答える
2

(少なくとも iOS 4.3 では) [formatter setLenient:YES] フラグを使用すると、ユーロを使用して機能することを確認しました。このフラグが設定されていないと、フォーマッタはユーロの正しい値を返しません。

于 2011-10-28T08:19:45.280 に答える
1

私は醜い答えを持っていますNSScanner

NSArray * testStrings = [NSArray arrayWithObjects:@"12,34 €", @"12,34" ,@"12.345,67 €" ,@"12.345,67", nil];

    NSCharacterSet * charset = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];

    for(NSString * s in testStrings)
    {
        s = [s stringByReplacingOccurrencesOfString:@"." withString:@""];
        s = [s stringByReplacingOccurrencesOfString:@"," withString:@"."];
        NSScanner * scanner = [NSScanner scannerWithString:s];
        [scanner setCharactersToBeSkipped:charset];
        float f;
        [scanner scanFloat:&f];
        NSLog(@"float output is %.2f",f);
    }

出力:
2011-05-05 12:56:25.460 ScannerTest[10882:903] float 出力は 12.34
2011-05-05 12:56:25.473 ScannerTest[10882:903] float 出力は 12.34
2011-05-05 12:56 :25.474 ScannerTest[10882:903] float 出力は 12345.67
2011-05-05 12:56:25.475 ScannerTest[10882:903] float 出力は 12345.67

于 2011-05-05T18:58:59.243 に答える
0

Swift でこれを行う方法は次のとおりです。

   var locale = NSLocale.currentLocale()
    var formatter = NSNumberFormatter()
    formatter.locale = NSLocale(localeIdentifier: "en_US")
    formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle

    var moneyDouble = formatter.numberFromString(textField.text)?.doubleValue

textField.text が入力されている数値であると仮定します。

于 2014-10-26T01:18:13.553 に答える
0

デフォルト設定 ( lenient= NO) では、数値を文字列にフォーマットするときに生成される文字列とまったく同じようにフォーマットされている場合にのみ、文字列を数値に変換します。

そのため、緩い変換を使用する場合は、多くのロケール (すべて?) で、入力文字列内のスペースが改行されないようにする必要があることに注意する必要があります ( \u00a0)。ウィット:

NSString *amount = @"10 000,00 €";

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterCurrencyStyle;

formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier: @"fr_FR"];

NSNumber *number = [currencyFormatter numberFromString: amount];

number変数が nil になるため、これは期待される結果を生成しません。目的の結果を得るには、文字列の両方の場所で改行なしのスペースを使用します (千単位の区切り記号と通貨記号の区切り記号として)。

amount = @"10\u00a0000,00\u00a0€";

その後、変換は期待どおりに行われます。

もちろん、寛大な変換を使用したい場合は、それが最も簡単な方法であり、おそらく人間の入力を処理するための最良のオプションです。

一方、機械で生成されたデータを処理する場合、入力データの正確性をチェックする能力が失われるため、文字列の寛大な解釈は望ましくない場合があります。

于 2013-05-13T16:50:30.207 に答える