2016-12-16 2 views
1

Я хочу преобразовать число, которое вводится как NSString в NSDecimalNumber на основе NSLocale.Преобразование NSSting в NSDecimalNumber на основе locale

, например

InputString => 110.50 
Current Locale => en_FI 
Expected output => 110.50 
Actual output => 110 

InputString => 110.50 
Current Locale => en_US 
Expected output => 110.50 
Actual output => 110.50 



InputString => 110,50 
Current Locale => en_US 
Expected output => 110.50 
Actual output => 110 


InputString => 110.50 
Current Locale => en_US 
Expected output => 110.50 
Actual output => 110.50 

Я использую следующий код для достижения этой цели, но он не работает.

NSDecimalNumber *decimalNumber = [NSDecimalNumber decimalNumberWithString:self.amountTextField.text locale:[NSLocale currentLocale]]; 

Как упоминалось выше в 1-м и 3-м, я не являюсь желаемым выходом. Любая идея, что я делаю неправильно здесь.

+0

Почему вы используете локальный режим, если игнорируете особенности локали? – Sulthan

+0

Вы назвали этот вопрос google? – danh

ответ

0

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

import Foundation 

let formatter = NumberFormatter() 
formatter.numberStyle = .decimal 

func cleanNumberString(with string: String) -> String { 
    let knownDecimalSeparators = [",", "."] 
    let localSeparator = formatter.decimalSeparator ?? "." 
    var cleanString = string; 
    for separator in knownDecimalSeparators { 
     cleanString = cleanString.replacingOccurrences(of: separator, with: localSeparator) 
    } 
    return cleanString 
} 

func number(with string: String) -> Double { 
    let cleanString = cleanNumberString(with: string) 
    let number = formatter.number(from: cleanString) 
    return number?.doubleValue ?? 0 
} 

let string1 = "14,4" 
let string2 = "14.4" 

let cleanString1 = cleanNumberString(with: string1) 
let cleanString2 = cleanNumberString(with: string2) 

let number1 = number(with: string1) 
let number2 = number(with: string2) 

То же самое в Objective-C

@interface CleanNumberFormatter() 

@property (nonatomic) NSNumberFormatter *formatter; 

@end 

@implementation CleanNumberFormatter 

- (instancetype)init 
{ 
    self = [super init]; 
    if (self) { 
     self.formatter = [NSNumberFormatter new]; 
     self.formatter.numberStyle = NSNumberFormatterDecimalStyle; 
    } 
    return self; 
} 

- (NSString *)cleanNumberStringWithString:(NSString *)string 
{ 
    NSArray *knownDecimalSeparators = @[@",", @"."]; 
    NSString *localSeparator = self.formatter.decimalSeparator ?: @","; 
    NSString *cleanString = [string copy]; 
    for (NSString *separator in knownDecimalSeparators) { 
     cleanString = [cleanString stringByReplacingOccurrencesOfString:separator withString:localSeparator]; 
    } 
    return cleanString; 
} 

- (double)numberWithString:(NSString *)string 
{ 
    NSString *cleanString = [self cleanNumberStringWithString:string]; 
    double number = [self.formatter numberFromString:cleanString].doubleValue; 
    return number; 
} 

- (void)foo 
{ 
    NSString *string1 = @"14.4"; 
    NSString *string2 = @"14,4"; 

    NSString *cleanString1 = [self cleanNumberStringWithString:string1]; 
    NSString *cleanString2 = [self cleanNumberStringWithString:string2]; 

    double number1 = [self numberWithString:string1]; 
    double number2 = [self numberWithString:string2]; 
} 

@end 
+0

Я не хочу дешифратор с твердым кодом, я хочу получить его из локали устройства – Madu

+0

@ Десятичный разделитель @Madu для 'en_FI' is', ', но в вашей входной строке это' .'. Поэтому в вашем примере все работает так, как ожидалось. –

+0

Да, это то, что я хочу, если локаль устройства en_FI, и пользователь входит в 110.25. то он правильно меняет меня 110.25 вместо 110 только – Madu

0

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

+0

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

+0

Извините, я не понял ваш вопрос правильно. Возможно, вы захотите посмотреть через свою строку и заменить разделители в зависимости от языка? Поскольку сама локаль будет игнорировать ваши десятичные числа, если разделитель не является правильным. Добавление собственного метода для этого, прежде чем преобразовать в число, может быть лучшим вариантом. –

Смежные вопросы