Получение нуля из NSNumberformater numberFromString

Я пытаюсь отформатировать сумму из файла .txt, поступающего в локали es_US (x, xxx.xx), в мою текущую локаль с es_ES (x.xxx, xx). Однако я ожидал, что [NSNumberFormater numberFromString] просто переформатирует строку, и я получаю только нулевое значение от этого метода.

Я также попробовал другой подход после проверки ответов отсюда, но NSDecimalnumber не работает, если в строке есть тысячи разделителей, поэтому, если кто-нибудь может сказать мне, что я делаю неправильно, пожалуйста...

 - (void) setSaldo_sap:(NSString *)saldo_sap
 {
    NSNumberFormatter *numFormatter = [[NSNumberFormatter alloc] init];

    [numFormatter setLocale:[NSLocale currentLocale]];
    [numFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
    [numFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
    [numFormatter setNegativeFormat:@"-¤#,##0.00"];

    //saldo_sap = @"         -324,234.55"
    NSString * tmpString = [saldo_sap stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

    NSNumber *num = [numFormatter numberFromString:tmpString];
    NSDecimalNumber *tempNumber = [NSDecimalNumber decimalNumberWithString:tmpString];  

    _saldo_sap = [numFormatter stringFromNumber:tempNumber];        
}

person Rubs    schedule 10.07.2012    source источник


Ответы (2)


Я думаю, вы неправильно понимаете цель NSNumberFormatter: он не «переформатирует», он «форматирует» и «разбирает» числа, отформатированные по установленным правилам. Поэтому, если у вас есть числа, поступающие в локали «es_US», но вы хотите отформатировать их, используя «es_ES», вам понадобятся два NSNumberFormatters: по одному для каждой локали.

Разберите входящий номер с помощью «es_US» и отформатируйте с помощью «es_ES», немного упростив (я не знаю этих двух локалей и точного формата ваших чисел, поэтому вам может потребоваться немного изменить его):

NSString * tmpString = ...

NSNumberFormatter *usFormatter = [[NSNumberFormatter alloc] init];
[usFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier: @"es_US"] autorelease]];
[usFormatter setHasThousandSeparators: YES];

NSNumberFormatter *esFormatter = [[NSNumberFormatter alloc] init];
[esFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier: @"es_ES"] autorelease]];
[esFormatter setHasThousandSeparators: YES];

// this assignment looks also somewhat weird: is it an instance variable? 
// 'cause if it is and you assign an autoreleased string you'll have a bad pointer there
_saldo_sap = [esFormatter stringFromNumber: [usFormatter numberFromString: tmpString]];

// And unless you use ARC you leak your formatter on each call, so at the end
[usFormatter release];
[esFormatter release];

EDIT Если входные строки содержат символы префикса/постфикса, которые могут помешать работе NSNumberFormatter (обычно он используется довольно строго), используйте setLenient::

«Устанавливает, будет ли получатель использовать эвристику для угадывания числа, которое предназначено для строки».

Если вам нужно преобразовать более одного числа, не создавайте средства форматирования для каждого числа, это просто пустая трата памяти и процессора. Сделайте их переменными экземпляра и используйте повторно. Это будет намного понятнее, чем просто иметь один форматтер и перенастраивать его между парсингом одного формата и форматированием в другом.

person Tomasz Stanczak    schedule 10.07.2012

NSString *_saldo_sap = @"         -324234.55";
//NSString *_saldo_sap = @"         324,234.55";

NSString * tmpString = [_saldo_sap stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
//tmpString = @"-324,234.55"

NSNumberFormatter *numFormatter = [[NSNumberFormatter alloc] init];
NSNumber *num = [numFormatter numberFromString:tmpString];

[numFormatter setLocale:[NSLocale currentLocale]];
[numFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
[numFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[numFormatter setNegativeFormat:@"-¤#,##0.00"];

_saldo_sap = [numFormatter stringFromNumber:num];

Во-первых, для получения NSNumber из NSString строка должна быть в правильном читаемом формате, т. е. она не должна содержать никаких символов, таких как «,», как указано. Во-вторых, вы должны сначала преобразовать строку в NSNumber, а затем отформатировать ее соответствующим образом.

person AJS    schedule 10.07.2012
comment
Итак, есть ли какой-либо метод или функция, чтобы избавиться от разделителей тысяч? То есть: _saldo_sap=@ 3,242,55, поскольку он исходит из txt-файла, должен быть @ 3242,55 для преобразования в NSNumber. Имейте в виду, что txt-файлы форматируются, поскольку они адаптированы для разных регионов (стран), например, текст из США и Великобритании поставляется с форматом разделителя запятой и тысяч, а ES, FR и т. Д. - с разделителем точек. для тысяч. - person Rubs; 10.07.2012
comment
«он не должен содержать никаких символов, таких как , », совершенно неверно. NSNumberFormatter прекрасно справляется не только с разделителями тысяч, но и со знаками процента, валюты и т. д. Просто их нужно правильно настроить: посмотрите на setHasThousandSeparators:, setThousandSeparator:. На самом деле NSNumberFormatter может работать с любым форматом, о котором вы только можете подумать, можно установить даже размеры групп!!! Читайте API. - person Tomasz Stanczak; 11.07.2012