Bug com a moeda do iPhone para formato Euro com NSDecimalNumber usando NSLOCale?
-
26-09-2019 - |
Pergunta
Meu aplicativo usa valores monetários, e eu gostaria de representar esses valores na moeda e nos formatos que o usuário definiu no iPhone, no entanto, ao testar, parece estar tendo problemas com o formato do euro alemão.
Eu tenho um método que retorna um número decimal (para armazenar dados principais) a partir da sequência formatada por moeda. A string foi realmente formatada por outro método (semelhante) usando NSLocale.
Eu testei com os locais do Reino Unido, EUA, japonês e alemão, até agora apenas a Alemanha causou problemas.
Aqui está o código, a string que está sendo aprovada é, por exemplo: 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];
}
A variável 'CurrencyNumber' é impressa como: -18446912453607470532000000000000000000000000000000000000000000000000000000000000000000000000000000
Enquanto em todos os outros locais, ele imprimiria 2.56 para armazenar dados principais como nsdecimalNumber.
Solução
Definindo a propriedade:
[fmtrCurrencyFromStr setLenient:YES];
Corrige o problema para a França, Alemanha, Noruega, Reino Unido, EUA, Japão, Nâmbia etc ... Não posso dizer que isso corrige tudo porque não testei tudo, mas de todos aqueles que testei até agora , funcionou.
Outras dicas
EU acho Seu problema está com a linha
NSDecimalNumber* currencyNumber = [[NSDecimalNumber alloc] initWithDecimal:[[fmtrCurrencyFromStr numberFromString:strNumber] decimalValue]];
Tente substituí-lo pela linha principalmente equivalente
NSDecimalNumber * currencyNumber = [fmtrCurrencyFromStr numberFromString:strNumber];
Você definiu generatesDecimalNumbers
, então os dois são praticamente equivalentes, exceto por um caso irritante: nulo.
O envio de uma mensagem para NIL é garantido para não fazer nada e retornar 0 para a maioria dos tipos padrão (número inteiro (exceto os números inteiros de 64 bits em tempos de execução antigos de 32 bits), ponto flutuante, tipos de ponteiro); Ele "retorna" a memória não inicializada se o método retornar uma estrutura. Nsdecimal é uma estrutura.
(A razão subjacente é essencialmente que o tempo de execução não sabe o tamanho da estrutura, então não sabe quanta memória zero, por isso você recebe memória "não inicializada". v.frame
sem garantir que V não seja nulo.)
EDITAR: Claro, você outro O problema é por que o NSNumberFormatter não está analisando o preço corretamente. Essa é difícil. Eu tentaria tirar o símbolo da moeda.
Verifiquei isso no iOS 4.3 usando a bandeira [Setlenient: sim] funcionou para mim usando euros. Sem esse conjunto de bandeiras, o formatador não retorna valores corretos para euros.