iOS: форматирование десятичных чисел - PullRequest
3 голосов
/ 22 февраля 2012

У меня есть NSDecimalNumber, представляющая сумму денег. Я хочу напечатать его как «999 999 999 999 999 999,00», независимо от локали. Как мне это сделать?

NSNumberFormatter печатает вместо меня 1 000 000 000 000 000 000,00 (кажется, что инженеры Apple никогда не проектировали iPhone в качестве платформы для финансового программного обеспечения).

[NSDecimalNumber description] и [NSDecimalNumber descriptionWithLocale] оба печатают правильное значение. Как я могу отформатировать результат, установив для группового разделителя @"\u2006", десятичный разделитель @"**,**" и ровно 2 десятичных знака после десятичного разделителя?

Заранее спасибо!

Обновление: Вот мое решение, в 10 раз больше, чем у Султана:

@implementation NSDecimalNumber(MiscUtils)

-(NSString*)moneyToString
{
    static NSDecimalNumberHandler* s_handler = nil;
    if( !s_handler )
        s_handler = [ [ NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain scale:2 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO ] retain ];

    NSDecimalNumber *dec = [ self decimalNumberByRoundingAccordingToBehavior:s_handler ];
    NSString* str = [ dec description ];
    NSRange rDot = [ str rangeOfString:@"." ];
    int nIntDigits = str.length;
    int nFracDigits = 0;
    if( rDot.length > 0 )
    {
        nIntDigits = rDot.location;
        nFracDigits = str.length - ( rDot.location + 1 );
    }
    int nGroupSeparators = ( nIntDigits - 1 ) / 3;

    NSMutableString* res = [ NSMutableString stringWithCapacity:nIntDigits + nGroupSeparators + 3 ];
    NSString *groupingSeparator = @"\u2006";

    int nFirstGroup = ( nIntDigits % 3 );
    int nextInd = 0;
    if( nFirstGroup )
    {
        [ res appendString:[ str substringToIndex:nFirstGroup ] ];
        nextInd = nFirstGroup;
    }

    while( nextInd < nIntDigits )
    {
        if( res.length > 0 )
            [ res appendString:groupingSeparator ];
        [ res appendString:[ str substringWithRange:NSMakeRange( nextInd, 3 ) ] ];
        nextInd += 3;
    }

    if( nFracDigits > 0 )
    {
        if( nFracDigits > 2 )
            nFracDigits = 2;
        [ res appendString:@"," ];
        [ res appendString:[ str substringWithRange:NSMakeRange( rDot.location + 1, nFracDigits ) ] ];
        while( nFracDigits < 2 )
        {
            [ res appendString:@"0" ];
            nFracDigits++;
        }
    }
    else
        [ res appendString:@",00" ];
//  DLog( "formatDecimal: %@ -> %@", dec, res );
    return res;
}
@end 

Ответы [ 2 ]

6 голосов
/ 18 мая 2012

Попробуйте это:

    NSLocale *usLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"US"];

    NSNumberFormatter *frm = [[NSNumberFormatter alloc] init];
    [frm setNumberStyle:NSNumberFormatterDecimalStyle];
    [frm setMaximumFractionDigits:2];
    [frm setMinimumFractionDigits:2];
    [frm setLocale:usLocale];
    NSString *formattedNumberStr = [frm stringFromNumber:[NSNumber numberWithFloat:floatToRound]];

    [frm release];
[usLocale release];

    return formattedNumberStr;
3 голосов
/ 22 февраля 2012

У меня была такая же проблема.Мне сказали, что NSNumberFormatter сначала преобразует все в double.Как я это решил?Это просто, просто напишите свой собственный форматер.

  1. Сначала округлите десятичную дробь до 2 десятичных цифр.
  2. Получить описание в виде строки.
  3. Найти десятичную точку (.) в строке и замените его на тот, который вам нужен.
  4. После каждых трех цифр от десятичной точки слева вставьте разделитель группировки.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...