How do I force a sign-character on the output of an NSNumberFormatter

会有一股神秘感。 提交于 2019-12-23 07:03:35

问题


I want to use a number formatter to generate my output, so the number is automatically formatted for the user's locale, but I want it to work like "%+.1f" does in printf(), that is always have a sign specified.

NSNumberFormatter *nf = [[NSNumberFormatter alloc] init];
nf.numberStyle = NSNumberFormatterDecimalStyle;
nf.maximumFractionDigits = 1;

double val = 3.1234;
label.text = [NSString stringWithFormat: @"XXX %@ XXX", [nf stringFromNumber: [NSNumber numberWithDouble: val]]];

I want the label to come out "XXX +3.1 XXX" in the US and the appropriate but equivalent string for any other location. The only things I can find are setPositiveFormat: and setPositivePrefix:.

But I don't want to set the format since I don't know how to format numbers in other countries; I don't know if a plus-sign is used to designate a positive number in Arabic or Russian or some culture I have not thought of. I do know, for example, that decimal points, commas, spaces, etc., all have different meanings in European countries compared to the U.S. - Could the same be true for +/- signs?

What I do currently is:

label.text = [NSString stringWithFormat: @"XXX %s%@ XXX", (val < 0) ? "" : "+",
    [nf stringFromNumber: [NSNumber numberWithDouble: val]]];

But this presumes that '+' and '-' are correct for all formats.

I'm sure it must be there since it is a standard formatting thing that has been in printf() since the dark ages...


回答1:


How about this:

NSNumberFormatter *nf = [[NSNumberFormatter alloc] init];
nf.numberStyle = NSNumberFormatterDecimalStyle;
nf.maximumFractionDigits = 1;

double val = 3.1234;
NSString *sign = (val < 0) ? [nf minusSign] : [nf plusSign];
NSString *num = [nf stringFromNumber:@(abs(val))]; // avoid double negative
label.text = [NSString stringWithFormat: @"XXX %@%@ XXX", sign, num];

You may need to check to see if num has the sign prefix or not so it isn't shown twice.

Edit: After some playing around, it has been determined, for the "Decimal" style, that no current locale uses a positivePrefix. No current locale uses a plusSign other than the standard + character. No current locale uses a negativePrefix that is different than minusSign. No current locale uses either positiveSuffix or negativeSuffix.

So an easier approach would be to do:

NSNumberFormatter *nf = [[NSNumberFormatter alloc] init];
nf.numberStyle = NSNumberFormatterDecimalStyle;
nf.maximumFractionDigits = 1;
[nf setPositivePrefix:[nf plusSign]];
[nf setNegativePrefix:[nf minusSign]];

label.text = [nf stringFromNumber:@(val)];



回答2:


This case it's simple, just add the prefix:

nf.positivePrefix= nf.plusSign;



回答3:


Though it won't use the user's locale, you can do the following to generate the +/- sign without the somewhat expensive overhead of an NSNumberFormatter:

// assume 'number' is an NSNumber
label.text = [NSString stringWithFormat:@"%+.02f", [number floatValue]];



回答4:


The underlying formatting language for NSNumberFormatter doesn't have any provision for what you want to do -- it will allow you to specify a localized positive sign on exponents, but not for the entire formatted string. Nor does NSLocale seem to make available the localized positive sign.

Aside from making a dummy string that includes an exponent, pulling the localized positive sign out, and putting your final formatted string together by hand, I think you're out of luck.




回答5:


A reusable formatter in swift:

var numberFormatter: NSNumberFormatter {
    let formatter = NSNumberFormatter()
    formatter.numberStyle = .DecimalStyle
    formatter.locale = NSLocale(localeIdentifier: "it_IT")//your Locale
    formatter.maximumFractionDigits = 2
    formatter.minimumFractionDigits = 0
    formatter.positivePrefix = formatter.plusSign
    return formatter
}

Then use it:

let myDoubleValue = 12.00
let myStringNumber = numberFormatter.stringFromNumber(myDoubleValue)!



回答6:


Simple Case:

    let f = NumberFormatter()
    f.numberStyle = .currency
    f.positivePrefix = f.plusSign + f.currencySymbol

Currency Case :

Hack needed, because setting the prefix to plusSign only will remove the currency symbol.

    let f = NumberFormatter()
    f.numberStyle = .currency
    f.positivePrefix = f.plusSign + f.currencySymbol

There is a bit more work depending on the locale.. The currency symbol may be before, or after, but this is probably another subject..

Edit:

Even if it is another subject, I'd say a possible solution to the problem above is to subclass NSNumberFormatter :

override func string(from number: NSNumber) -> String? {
    returns ( number.doubleValue >= 0 ? super.plusSign : "" ) + super.string(from: number)
}

This way, NSNumberFormatter should manage the currency position while your subclass simply prepend the + sign. No time to test this in depth, but at least it is an approach.



来源:https://stackoverflow.com/questions/14149740/how-do-i-force-a-sign-character-on-the-output-of-an-nsnumberformatter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!