Bug con el iPhone de divisas para el formato europeo con NSDecimalNumber usando NSLocale?
-
26-09-2019 - |
Pregunta
Mi aplicación utiliza los valores monetarios, y me gustaría para representar estos valores en la moneda y formatos que el usuario ha establecido en su iPhone sin embargo, cuando se prueba, que parecen estar teniendo problemas con el formato EURO alemán.
I tiene un método que devuelve un número decimal (para almacenar en los datos de núcleo) de la cadena de moneda con formato. La cadena fue en realidad el formato por otro método (similar) usando NSlocale.
He probado con el Reino Unido, Estados Unidos, Japón y lugares alemanes, hasta el momento sólo Alemania ha causado ningún problema.
Este es el código, la cadena que se pasa es por ejemplo: 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];
}
La variable 'currencyNumber' se imprime como: -18446912453607470532000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
mientras que en todos los demás lugares, sería imprimir 2,56 para almacenar en la base de datos como NSDecimalNumber.
Solución
Configuración de la propiedad:
[fmtrCurrencyFromStr setLenient:YES];
soluciona el problema de Francia, Alemania, Noruega, Reino Unido, EE.UU., Japón, Namibia, etc ... No puedo decir que lo fija para todos porque no he probado todo, pero de todos los que he probado hasta ahora, ha funcionado.
Otros consejos
pensar es su problema con la línea
NSDecimalNumber* currencyNumber = [[NSDecimalNumber alloc] initWithDecimal:[[fmtrCurrencyFromStr numberFromString:strNumber] decimalValue]];
Probar reemplazándolo con la línea principalmente equivalente
NSDecimalNumber * currencyNumber = [fmtrCurrencyFromStr numberFromString:strNumber];
Usted ha fijado generatesDecimalNumbers
, por lo que los dos son más o menos equivalentes a excepción de un caso molesto:. Nil
El envío de un mensaje a cero está garantizado para no hacer nada y devuelven 0 para la mayoría de los tipos estándar (número entero (excepto enteros no de 64 bits en los viejos tiempos de ejecución de 32 bits), punto flotante, los tipos de puntero); "devuelve" la memoria sin inicializar si el método devuelve una estructura. NSDecimal es una estructura.
(La razón subyacente es, esencialmente, que el tiempo de ejecución no sabe lo grande que la estructura es, por lo que no se sabe la cantidad de memoria a cero, por lo que se obtiene "sin inicializar" memoria en su lugar. Por lo general golpeo éste cuando lo haga v.frame
sin asegurarse de que v no es nula.)
EDIT: Por supuesto, otro problema es qué NSNumberFormatter no es analizar el precio correctamente. Esa es una dificil. Me gustaría probar pelar el símbolo de moneda.
He verificado que en iOS 4.3 utilizando la [formateador setLenient: SÍ] bandera trabajado para mí también el uso de Euros. Sin ese conjunto de bandera, el formateador no devuelve valores correctos para euros.