mak*_*dad 10 currency nsnumberformatter ios
我的iOS应用会显示不同的货币(美元,日元,澳元,欧元)在不同的本地化(en_US,en_AU,ja_JP等).
对于日语区域/语言(两者都在我的设备上设置),如果我有:
NSNumberFormatter *fmt = [[NSNumberFormatter alloc] init];
fmt.numberStyle = NSNumberFormatterCurrencyStyle;
fmt.currencyCode = @"JPY";
NSString *labelText = [fmt stringFromNumber:@1000000];
Run Code Online (Sandbox Code Playgroud)
我的标签文字是¥1,000,000.但是,在日文和中文中,可能会写入大于10,000的数字100??,这是我想要的输出.
知道我可以写什么代码100??作为输出吗?
我想避免我的代码中的逻辑块检查locale/region,但我觉得这就是我要反对的东西(例如,使用方法调用fmt.multipler = @(1/10000)将1,000,000除以10,000以获得正确的值).
编辑:此处最新要点:https://gist.github.com/fjolnir/cd72ea39be1476023adf
\n\n旧线程,但我在寻找解决方案时遇到了它,所以我想我应该发布我的实现。
\n\n格式化程序本身不处理 \xe5\x86\x86 的放置,但在它之外很容易做到。(如下例所示)
\n\n下面的预期输出是:
\n\n2015-03-11 18:00:13.376 LENumberFormatter[82736:3604947] 12\xe5\x84\x843,460\xe4\xb8\x87\xe5\x86\x86\n2015-03-11 18:00:13.377 LENumberFormatter[82736:3604947] 25\xe5\x86\x86\nRun Code Online (Sandbox Code Playgroud)\n\n-
\n\n@import Foundation;\n@import ObjectiveC.message;\n\ntypedef NS_ENUM(NSUInteger, LENumberFormatterAbbreviationStyle) {\n kLEAbbreviateShort, // 2.5m\n kLEAbbreviateNormal // 2m 5k\n};\n\n@interface LENumberFormatter : NSNumberFormatter\n@property(nonatomic) BOOL abbreviateLargeNumbers;\n@property(nonatomic) LENumberFormatterAbbreviationStyle abbreviationStyle;\n@end\n\n\n@implementation LENumberFormatter\n- (instancetype)init\n{\n if((self = [super init])) {\n self.abbreviationStyle = [self _usingKanjiNumbers]\n ? kLEAbbreviateNormal\n : kLEAbbreviateShort;\n }\n return self;\n}\n\n- (NSString *)stringForObjectValue:(id const)aObj\n{\n if(!_abbreviateLargeNumbers || ![aObj isKindOfClass:[NSNumber class]])\n return [super stringForObjectValue:aObj];\n\n // Copy ourselves to get format the partial digits using the settings on self\n LENumberFormatter * const partialFormatter = [self copy];\n partialFormatter.currencySymbol = @"";\n if(_abbreviationStyle == kLEAbbreviateNormal)\n partialFormatter.maximumFractionDigits = 0;\n\n NSString *(^partialFormat)(NSNumber*) = ^(NSNumber *num) {\n NSString *(*superImp)(struct objc_super*,SEL,NSNumber*) = (void*)&objc_msgSendSuper;\n return superImp(&(struct objc_super) { partialFormatter, self.superclass }, _cmd, num);\n };\n\n double n = [aObj doubleValue];\n BOOL const shortFormat = _abbreviationStyle == kLEAbbreviateShort;\n\n NSDictionary * const separators = [self _localizedGroupingSeparators];\n NSArray * const separatorExponents = [separators.allKeys sortedArrayUsingSelector:@selector(compare:)];\n\n BOOL const currencySymbolIsSuffix = [self.positiveFormat hasSuffix:@"\xc2\xa4"];\n NSMutableString * const result = currencySymbolIsSuffix || self.numberStyle != NSNumberFormatterCurrencyStyle\n ? [NSMutableString new]\n : [self.currencySymbol mutableCopy];\n NSUInteger significantDigits = 0;\n NSNumber *lastExp = nil;\n for(NSNumber *exp in separatorExponents.reverseObjectEnumerator) {\n double divisor = pow(10, exp.shortValue);\n if(divisor > n)\n continue;\n\n if(lastExp)\n significantDigits += lastExp.doubleValue - exp.doubleValue;\n lastExp = exp;\n\n if(self.usesSignificantDigits && significantDigits >= self.maximumSignificantDigits)\n break;\n\n double partialNum = shortFormat\n ? n/divisor\n : floor(n/divisor);\n NSString * const digits = [self _groupRecursively] && ![exp isEqual:@0]\n ? [partialFormatter stringFromNumber:@(partialNum)]\n : partialFormat(@(partialNum));\n [result appendFormat:@"%@%@", digits, separators[exp]];\n\n n = fmod(n, divisor);\n\n if(shortFormat)\n break; // Just use a float+first hit\n\n // If we make it here, partialNum is integral and we can use log10 to find the number of digits\n significantDigits += log10(partialNum) + 1;\n partialFormatter.maximumSignificantDigits -= digits.length;\n\n }\n if(n > 0\n && !shortFormat\n && (!self.usesSignificantDigits || significantDigits < self.maximumSignificantDigits))\n {\n partialFormatter.maximumFractionDigits = self.maximumFractionDigits;\n [result appendString:partialFormat(@(n))];\n }\n if(self.numberStyle == NSNumberFormatterCurrencyStyle && currencySymbolIsSuffix && self.currencySymbol)\n [result appendString:self.currencySymbol];\n\n return result.length > 0\n ? [result stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet]\n : [super stringForObjectValue:aObj];\n}\n\n- (BOOL)_usingKanjiNumbers\n{\n return [self.locale.localeIdentifier rangeOfString:@"^(ja|zh)_"\n options:NSRegularExpressionSearch].location != NSNotFound;\n}\n- (NSDictionary *)_localizedGroupingSeparators\n{\n if(self._usingKanjiNumbers)\n return @{ @2: @"\xe7\x99\xbe", @3: @"\xe5\x8d\x83", @4: @"\xe4\xb8\x87", @8: @"\xe5\x84\x84" };\n else {\n NSBundle * const bundle = [NSBundle bundleForClass:self.class];\n return @{ \n @3: [bundle localizedStringForKey:@"thousandSuffix" value:@"k " table:nil],\n @6: [bundle localizedStringForKey:@"millionSuffix" value:@"m " table:nil]\n };\n }\n}\n\n- (BOOL)_groupRecursively\n{\n // Return _usingKanjiNumbers if you want:\n // 12\xe5\x84\x843\xe5\x8d\x834\xe7\x99\xbe56\xe4\xb8\x877\xe5\x8d\x838\xe7\x99\xbe90\n // Rather than:\n // 1\xe5\x84\x842,3456\xe4\xb8\x877\xe5\x8d\x838\xe7\x99\xbe90\n return NO;\n}\n\n- (instancetype)copyWithZone:(NSZone * const)aZone\n{\n LENumberFormatter * const copy = [super copyWithZone:aZone];\n copy.abbreviateLargeNumbers = _abbreviateLargeNumbers;\n copy.abbreviationStyle = _abbreviationStyle;\n return copy;\n}\n@end\n\n\nint main(int argc, char *argv[]) {\n @autoreleasepool {\n LENumberFormatter * const f = [LENumberFormatter new];\n f.locale = [NSLocale localeWithLocaleIdentifier:@"ja_JP"];\n// f.locale = [NSLocale localeWithLocaleIdentifier:@"en_US"];\n f.numberStyle = NSNumberFormatterCurrencyStyle;\n f.abbreviateLargeNumbers = YES;\n f.abbreviationStyle = kLEAbbreviateNormal; // Automatic if using system locale\n f.maximumSignificantDigits = 5;\n f.usesSignificantDigits = YES;\n// f.currencyCode = @"JPY";\n// f.currencySymbol = @"\xc2\xa5";\n\n if([f.locale.localeIdentifier hasPrefix:@"ja"]) {\n f.positiveFormat = @"#,##0\xc2\xa4";\n if([f.currencyCode isEqualToString:@"JPY"])\n // We allow ourselves this special case because *\xe6\x97\xa5\xe6\x9c\xac\xe5\x86\x86 just looks dumb\n f.currencySymbol = @"\xe5\x86\x86";\n else\n f.currencySymbol = [f.locale displayNameForKey:NSLocaleCurrencyCode\n value:f.currencyCode];\n }\n\n NSLog(@"%@", [f stringFromNumber:@1234567890]);\n NSLog(@"%@", [f stringFromNumber:@25]);\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1186 次 |
| 最近记录: |