Ошибка с iPhone Валюта для евро формата с NSDecimalNumber с помощью NSLocale? - PullRequest
0 голосов
/ 21 ноября 2010

Мое приложение использует денежные значения, и я хотел бы представить эти значения в валюте и форматах, которые пользователь установил на своем iPhone, однако при тестировании у меня возникают проблемы с немецким форматом ЕВРО.

У меня есть метод, который возвращает десятичное число (для хранения в основных данных) из строки в формате валюты.Строка была фактически отформатирована другим (аналогичным) методом с использованием NSlocale.

Я тестировал в Великобритании, США, Японии и Германии, так что пока только Германия вызывала какие-либо проблемы.

Вот код, например передаваемая строка: 2,56 €

+ (NSDecimalNumber*)TLCurrencyFormatFromString:(NSString*)strNumber {


NSNumberFormatter *fmtrCurrencyFromStr = nil;

fmtrCurrencyFromStr = [[NSNumberFormatter alloc] init];
[fmtrCurrencyFromStr setFormatterBehavior:NSNumberFormatterBehavior10_4];
[fmtrCurrencyFromStr setLocale:[NSLocale currentLocale]];
[fmtrCurrencyFromStr setNumberStyle:NSNumberFormatterCurrencyStyle];
[fmtrCurrencyFromStr setGeneratesDecimalNumbers:YES];


NSLog(@"Currency Separator: %@", [fmtrCurrencyFromStr decimalSeparator]); //prints a comma
NSLog(@"Currency Code: %@", [fmtrCurrencyFromStr currencyCode]); //prints EUR

int currencyScale = [fmtrCurrencyFromStr maximumFractionDigits];

NSDecimalNumberHandler *roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain scale:currencyScale raiseOnExactness:FALSE raiseOnOverflow:TRUE raiseOnUnderflow:TRUE raiseOnDivideByZero:TRUE]; 

NSDecimalNumber* currencyNumber = [[NSDecimalNumber alloc] initWithDecimal:[[fmtrCurrencyFromStr numberFromString:strNumber] decimalValue]];

NSLog(@"Currency Number = %@", [currencyNumber decimalNumberByRoundingAccordingToBehavior:roundingBehavior]);

return [currencyNumber decimalNumberByRoundingAccordingToBehavior:roundingBehavior];

}

Переменная «currencyNumber» печатается как: -184469124536074705320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001012 *

, тогда как во всех других локалях будет напечатано 2,56 для хранения в Core Data как NSDecimalNumber.

Ответы [ 3 ]

2 голосов
/ 01 декабря 2010

Установка свойства:

[fmtrCurrencyFromStr setLenient:YES];

Исправляет проблему для Франции, Германии, Норвегии, Великобритании, США, Японии, Намбии и т. Д. ... Я не могу сказать, что это исправляет все, потому что у меня нетне проверял все, но из всех, которые я тестировал до сих пор, это сработало.

0 голосов
/ 28 октября 2011

Я проверил, что на iOS 4.3 использование флага [formatter setLenient: YES] также работает для меня с использованием евро.Если этот флаг не установлен, средство форматирования не возвращает правильные значения для евро.

0 голосов
/ 21 ноября 2010

I думаю ваша проблема с линией

NSDecimalNumber* currencyNumber = [[NSDecimalNumber alloc] initWithDecimal:[[fmtrCurrencyFromStr numberFromString:strNumber] decimalValue]];

Попробуйте заменить ее на строку, в основном эквивалентную

NSDecimalNumber * currencyNumber = [fmtrCurrencyFromStr numberFromString:strNumber];

Вы установили generatesDecimalNumbers, поэтому эти два в значительной степени эквивалентны, за исключением одного раздражающего случая: nil.

Отправка сообщения в nil гарантированно ничего не делает и возвращает 0 для большинства стандартных типов (целое число (кроме не 64-битных целых чисел встарые 32-разрядные среды выполнения), с плавающей запятой, типы указателей);он «возвращает» неинициализированную память, если метод возвращает структуру.NSDecimal - это структура.

(Основная причина, по сути, заключается в том, что среда выполнения не знает, насколько велика структура, поэтому не знает, сколько памяти обнулить, поэтому вместо этого вы получаете «неинициализированную» память.Я обычно нажимаю эту кнопку, когда выполняю v.frame, не гарантируя, что v не равно nil.)

РЕДАКТИРОВАТЬ: Конечно, вы другие проблемы, почему NSNumberFormatterне правильно разбор цены.Это сложный вопрос.Я бы попробовал удалить символ валюты.

...