2013-03-20 11 views
9

Zgodnie z dokumentacją, [NSDecimalNumber decimalNumberWithString:] powinny stosować separator locale dziesiętnych:NSDecimalNumber decimalNumberWithString: ignoruje bieżącej lokalizacji

czy NSDecimalSeparator to okres (co jest stosowane, na przykład, w Stanach Zjednoczonych) lub przecinek (jak jest używany na przykład we Francji) zależy od domyślnych ustawień regionalnych.

Ale gdy próbuję go, ten kod:

NSLog(@"%@", [NSDecimalNumber decimalNumberWithString:@"100,1"]); 
NSLog(@"%@", [NSDecimalNumber decimalNumberWithString:@"100,1" locale:NSLocale.currentLocale]); 

Daje ...

100 
100.1 

... jako wyjście na obu iOS 5 i iOS 6. Próbowałam ze szwedzkim i francuskim jako ustawienia regionalne, ponieważ oba te kraje używają przecinka (,) jako separatora dziesiętnego.

Czy dane wyjściowe nie powinny być takie same?

(wiem, że mogę używać [NSDecimalNumber decimalNumberWithString: locale:], aby wymusić zachowanie, więc to nie jest pytanie o znalezienie alternatywy, tylko jeśli jest to bug czy robię coś źle)

Odpowiedz

6

NSDecimalNumber to po prostu klasa pamięci dla danych liczbowych. Uruchamia on analizator składni (NSNumberFormatter) w ciągu, który przekazujesz, aby utworzyć jego numer. Powód, dla którego twoja druga loga działa "lepiej", polega na tym, że pierwsza używa domyślnego ustawienia narodowego (to wygląda jak to en_US, ale nie mogę tego zweryfikować, zobacz edycję cios, aby uzyskać więcej informacji.) do parsowania, a "100,1" nie jest prawidłową liczbą, więc część "nieliczbowa" zostaje usunięta. Określając ustawienia regionalne, które używają separatorów dziesiętnych ",", przechwytuje on pełną liczbę.

Kiedy NSLog() NSDecimalNumber to po prostu wywołanie -description, który nie ma kontekstu ustawień regionalnych i może drukować, mniej więcej, co chce.

Jeśli chcesz drukować prawidłowo sformatowane numery używać NSNumberFormatter tak:

NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:@"100.1"]; 

NSLog(@"%@", number); 

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; 

[formatter setNumberStyle:NSNumberFormatterDecimalStyle]; 

NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"fr_FR"]; 

[formatter setLocale:locale]; 

NSLog(@"%@", [formatter stringFromNumber:number]); 

Lub krótko

NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:@"100.1"]; 
NSLog(@"%@", [NSNumberFormatter localizedStringFromNumber:number numberStyle:NSNumberFormatterDecimalStyle]); 

jeśli chcesz po prostu użyć bieżącego ustawienia regionalne.

Podsumowując:

  1. NSDecimalNumber jest tylko przechowywanie. Zalogowanie go nie odzwierciedla niczego na temat ustawień regionalnych.
  2. Aby NSDecimalNumber poprawnie zapisał numer, jego ustawienia regionalne muszą być zgodne z ustawieniami oczekiwanego wejścia (dobrym wyborem jest tutaj -[NSLocale currentLocale]).
  3. Aby wyświetlić numery poprawnie sformatowane dla danego regionu, użyj NSNumberFormatter.

Edit:

Ok, zrobiłem trochę więcej badań na ten temat.

W GNUStepie wygląda na to, że kończy się wartością NSDecimalSeparator w NSUserDefaults (z szybkiego przeglądania ich kodu).

Wykonanie pewnych eksperymentów odkryłem, że żaden z poniższych wpływać na zachowanie domyślne parsowania, o ile mogę powiedzieć:

  1. NSDecimalSeparator w NSUserDefaults.
  2. AppleLocale w NSUserDefaults.
  3. NSLocaleCode w NSUserDefaults.
  4. Wartość ustawiona dla CFBundleDevelopmentRegion.
  5. Wartości środowiska LANG/LC_ALL/etc ....
  6. +[NSLocale systemLocale].

Oczywiście nie jest to +[NSLocale currentLocale], ponieważ to pytanie wynika z faktu, że aktualne ustawienia regionalne nie mają wpływu.

+1

Pytanie nie dotyczy drukowania, jego informacji na temat parsowania. _ "pierwszy używa domyślnego ustawienia narodowego formatu (en_US) do parsowania" _ - Moje pytanie brzmi, dlaczego en_US jest domyślnym, gdy moje bieżące ustawienia narodowe to fr_FR. Kiedy więc dokumentacja mówi, że domyślne ustawienia regionalne zależą od tego, kiedy to się różni od en_US, jeśli nie, gdy moje bieżące locale to fr_FR? – thejaz

+0

Dokumentacja nie wyjaśnia, co powoduje, że ustawienia narodowe stają się "domyślnymi" ustawieniami regionalnymi, chociaż wydaje się, że mogą się zmienić. Początkowo myślałem, że może to być związane z wartością ustawioną dla CFBundleDevelopmentRegion, która ["Zwykle odpowiada natywnemu językowi autora"] (https://developer.apple.com/library/ios/#documentation/General/Reference /InfoPlistKeyReference/Articles/CoreFoundationKeys.html), ale zmiana tej wartości nie miała żadnego wpływu na zachowanie. Jeśli API lub dokumentacja jest niejasna, najlepiej jest [złożyć radar] (https://bugreport.apple.com). – frozendevil

+0

Złożyłem dokumentacyjny radar, który zachęcam do skopiowania (rdar: // 13520160, http://openradar.appspot.com/radar?id=2878409); Dodałem również nieco więcej informacji do mojej odpowiedzi. – frozendevil

Powiązane problemy